//╒═════════════════════════════════════════════════════════════════════════════╕ //│ Author: Ben Rollinson + Luke Austin Date: 15/09/14 │ //╞═════════════════════════════════════════════════════════════════════════════╡ //│ │ //│ Animal Controller │ //│ │ //│ Manages creating the pickups that trigger switching the player │ //│ character into an animal. Next-gen new feature. Handles switching │ //│ mission state to animal-mode and transitioning back out of animal mode. │ //│ │ //╘═════════════════════════════════════════════════════════════════════════════╛ USING "globals.sch" USING "ambient_globals.sch" USING "rage_builtins.sch" USING "commands_pad.sch" USING "commands_player.sch" USING "commands_graphics.sch" USING "commands_misc.sch" USING "commands_camera.sch" USING "commands_hud.sch" USING "commands_audio.sch" USING "commands_event.sch" USING "commands_stats.sch" USING "animals_private.sch" USING "candidate_public.sch" USING "player_ped_public.sch" USING "shop_public.sch" USING "snapshot_private.sch" USING "randomChar_public.sch" USING "cheat_controller_public.sch" USING "vehicle_gen_public.sch" USING "taxi_functions.sch" USING "common_packages.sch" USING "scrap_common.sch" USING "clothes_shop_private.sch" USING "director_mode_public.sch" CONST_FLOAT ANIMAL_PICKUP_SPAWN_DIST 100.0 CONST_FLOAT ANIMAL_PICKUP_SPAWN_DIST_SQR 10000.0 // 100^2 CONST_FLOAT ANIMAL_PICKUP_DESPAWN_DIST 110.0 CONST_FLOAT ANIMAL_PICKUP_DESPAWN_DIST_SQR 12100.0 // 110^2 CONST_FLOAT ANIMAL_PICKUP_SPAWN_DIST_PC 255.0 // Max draw scaling on PC is 248.0 CONST_FLOAT ANIMAL_PICKUP_SPAWN_DIST_SQR_PC 65025.0 // 255^2 CONST_FLOAT ANIMAL_PICKUP_DESPAWN_DIST_PC 265.0 CONST_FLOAT ANIMAL_PICKUP_DESPAWN_DIST_SQR_PC 70225.0 // 265^2 CONST_FLOAT CULL_SPHERE_SIZE 2.5 #IF IS_DEBUG_BUILD FLOAT fPickupSpawnDist = ANIMAL_PICKUP_SPAWN_DIST #ENDIF FLOAT fPickupSpawnDistSqr = ANIMAL_PICKUP_SPAWN_DIST_SQR FLOAT fPickupDespawnDistSqr = ANIMAL_PICKUP_DESPAWN_DIST_SQR CONST_FLOAT ANIMAL_PICKUP_TRIGGER_DIST 0.70 CONST_FLOAT ANIMAL_PICKUP_TRIGGER_DIST_SQR 0.49 // 0.7^2 CONST_FLOAT ANIMAL_PICKUP_TRIGGER_DIST_LARGE 0.90 CONST_FLOAT ANIMAL_PICKUP_TRIGGER_DIST_SQR_LARGE 0.81 // 0.9^2 CONST_FLOAT ANIMAL_PICKUP_CLEAR_AREA_DIST 15.0 CONST_INT ANIMAL_MODE_EXIT_HOLD_TIME 1250 CONST_INT ANIMAL_MODE_LOAD_SCENE_TIMEOUT 12000 CONST_INT ANIMAL_PICKUPS_UPDATED_PER_FRAME 2 CONST_INT ANIMAL_PICKUP_LOWLAND_COUNT 15 CONST_INT ANIMAL_PICKUP_HIGHLAND_COUNT 6 CONST_INT ANIMAL_PICKUP_UNDERWATER_COUNT 6 CONST_INT ANIMAL_PICKUP_SECRET_COUNT 7 CONST_INT ANIMAL_PICKUP_COUNT_MAX 15 CONST_INT BIT_ANIMAL_CONTROL_LOADED_PLAYER_MODEL 0 CONST_INT BIT_ANIMAL_CONTROL_PLAYING_AS_ANIMAL 1 CONST_INT BIT_SELECTED_TRANSFORM_IN_DATA 2 CONST_INT BIT_STARTED_TRANSFORM_IN_ANIMATION 3 CONST_INT BIT_ENDED_TRANSFORM_IN_ANIMATION 4 CONST_INT BIT_RAGDOLLED_TRANSFORM_IN_ANIMATION 5 CONST_INT BIT_SELECTED_TRANSFORM_OUT_DATA 6 CONST_INT BIT_PRIMED_TRANSFORM_OUT_ANIMATION 7 CONST_INT BIT_STARTED_TRANSFORM_OUT_ANIMATION 8 CONST_INT BIT_ENDED_TRANSFORM_OUT_ANIMATION 9 CONST_INT BIT_INTERRUPT_EVENT_FIRED 10 CONST_INT BIT_IDLE_ANIM_STARTED 11 CONST_INT BIT_CONVERSATION_STARTED 12 ENUM AnimalControllerState ACS_INITIALISING, ACS_WAIT_FOR_PICKUP, ACS_GO_ON_MISSION, ACS_SWITCHING_TO_ANIMAL, ACS_PLAYING_AS_ANIMAL, ACS_SWITCHING_FROM_ANIMAL ENDENUM AnimalControllerState eState // For retrieving data on how many variations each animal model has. STRUCT AnimalVariationData INT iHead INT iTorso INT iLeg ENDSTRUCT //// AnimalAnimationData sAnim AnimalSoundData sSound // General state management. BOOL bForceCleanupSetup = FALSE INT data INT iFadeInTimer = -1 INT iLoadSceneTimer = -1 INT iStateBitset INT iExitButtonTimer = -1 INT iCandidateID = NO_CANDIDATE_ID INT wantedTimer = -1 INT contextId = -1 enumCharacterList eLastPlayerCharacter = NO_CHARACTER //Transition anim variables. BOOL drawRect = FALSE BOOL whiteBoxfadeIn = TRUE CAMERA_INDEX camSyncScene FLOAT fDrunkCameraShake INT iSyncSceneID = 0 INT drawTimer = -1 INT whiteAlpha = 0 INT cameraTimer INT myTimer // Pickup positional data. VECTOR vPickupPos[APT_COUNT][ANIMAL_PICKUP_COUNT_MAX] VECTOR vPickupRot[APT_COUNT][ANIMAL_PICKUP_COUNT_MAX] VECTOR vSpawnPos[APT_COUNT][ANIMAL_PICKUP_COUNT_MAX] FLOAT fSpawnHead[APT_COUNT][ANIMAL_PICKUP_COUNT_MAX] FLOAT fSpawnPitch[APT_COUNT][ANIMAL_PICKUP_COUNT_MAX] VECTOR vRespawnPos[APT_COUNT][ANIMAL_PICKUP_COUNT_MAX] FLOAT fRespawnHead[APT_COUNT][ANIMAL_PICKUP_COUNT_MAX] VECTOR vVehiclePos[APT_COUNT][ANIMAL_PICKUP_COUNT_MAX] FLOAT fVehicleHead[APT_COUNT][ANIMAL_PICKUP_COUNT_MAX] // Spawn state management. AnimalPickupType eCurrentPickupType = APT_LOWLAND AnimalPickup eSoundDataLoaded = AP_INVALID #if FEATURE_SP_DLC_DIRECTOR_MODE DirectorUnlockAnimal eUnlockAnimal #ENDIF BOOL bLoadingPickup = FALSE INT iCurrentPickupIndex = 0 INT iBitsetPickupSpawned[APT_COUNT] INT iBitsetPickupLeaveArea[APT_COUNT] INT iCurrentLeaveAreaCheck[APT_COUNT] INT iPickupSoundID = -1 INT iBarkSoundID = -1 // Pickup trigger state management. INT iNextPickupAnimal[APT_COUNT] AnimalPickup eTriggeredAnimal AnimalPickupType eTriggeredType INT iTriggeredIndex INT iTriggeredWantedLevel CAM_VIEW_MODE eTriggeredCameraView //Splash screen state management. BOOL bDisplaySplash BOOL bMessageOnDisplay = TRUE INT iSplashTimer INT iSplashStage // Indexes. OBJECT_INDEX oPickup[APT_COUNT][ANIMAL_PICKUP_COUNT_MAX] OBJECT_INDEX oChunky VEHICLE_INDEX vehPlayer SCALEFORM_INDEX siPickupSplash MODEL_NAMES chunkyModel = Prop_Peyote_Chunk_01 //PROP_GOLF_BALL //misc structPedsForConversation sConversationPeds STRING currentConversation = "" INT barkTimer = GET_GAME_TIMER() VECTOR vPossibleTrigger = <<0,0,0>> INT iClearupPickupIndex = -1 INT iCullSpherePeyoteCollect = -1 INT iCullSphereAnimalSpawn = -1 PED_VARIATION_STRUCT sPedVariations BOOL bWearingMask BOOL bWearingScubaGear VECTOR vVehPositionOriginalMisc = <<0,0,0>> FLOAT fVehHeadingOriginalMisc = 0 VECTOR vVehPositionMisc = <<0,0,0>> FLOAT fVehHeadingMisc = 0 INT crushDepthTimer = GET_GAME_TIMER() // Changes the spawn distances depending on if running PC or console PROC GET_PEYOTE_SPAWN_DISTANCES() IF IS_PC_VERSION() #IF IS_DEBUG_BUILD fPickupSpawnDist = ANIMAL_PICKUP_SPAWN_DIST_PC #ENDIF fPickupSpawnDistSqr = ANIMAL_PICKUP_SPAWN_DIST_SQR_PC fPickupDespawnDistSqr = ANIMAL_PICKUP_DESPAWN_DIST_SQR_PC ELSE #IF IS_DEBUG_BUILD fPickupSpawnDist = ANIMAL_PICKUP_SPAWN_DIST #ENDIF fPickupSpawnDistSqr = ANIMAL_PICKUP_SPAWN_DIST_SQR fPickupDespawnDistSqr = ANIMAL_PICKUP_DESPAWN_DIST_SQR ENDIF ENDPROC PROC Initialise_Pickup_Data() GET_PEYOTE_SPAWN_DISTANCES() //Pickup position data. vPickupPos[APT_LOWLAND][0] = << -529.820, 4188.161, 191.650 >> vPickupRot[APT_LOWLAND][0] = << -2.160, 17.280, -80.0 >> vPickupPos[APT_LOWLAND][1] = << -116.178, 1428.289, 293.404 >> vPickupRot[APT_LOWLAND][1] = << -3.600, 6.480, 100.0 >> vPickupPos[APT_LOWLAND][2] = << 2592.256, 6156.699, 165.061 >> vPickupRot[APT_LOWLAND][2] = << 5.0, -10.0, 25.0 >> vPickupPos[APT_LOWLAND][3] = << 2347.476, 2551.505, 45.668 >> vPickupRot[APT_LOWLAND][3] = << 4.0, 0.0, 90.0 >> vPickupPos[APT_LOWLAND][4] = << 1422.945, -2615.256, 46.688 >> vPickupRot[APT_LOWLAND][4] = << -8.0, 0.0, 180.0 >> vPickupPos[APT_LOWLAND][5] = << 1328.343, -607.007, 73.513 >> vPickupRot[APT_LOWLAND][5] = << 0, 0, 55.0 >> vPickupPos[APT_LOWLAND][6] = << -320.583, -1652.426, 30.849 >> vPickupRot[APT_LOWLAND][6] = << 1.0, 4.0, 155.0 >> vPickupPos[APT_LOWLAND][7] = << -1162.315, -1998.300, 12.160 >> vPickupRot[APT_LOWLAND][7] = << 6.0, 1.0, 245.0 >> vPickupPos[APT_LOWLAND][8] = << -2001.561, 3518.889, 56.035 >> vPickupRot[APT_LOWLAND][8] = << 12.960, 0.0, -51.840 >> vPickupPos[APT_LOWLAND][9] = << -1615.908, 2072.896, 76.997 >> vPickupRot[APT_LOWLAND][9] = << 11.520, -7.920, 210.0 >> vPickupPos[APT_LOWLAND][10] = << 513.941, 3009.893, 39.797 >> vPickupRot[APT_LOWLAND][10] = << 3.0, 8.0, 140.0 >> vPickupPos[APT_LOWLAND][11] = << -1038.658, 881.085, 161.007 >> vPickupRot[APT_LOWLAND][11] = << -2.0, 0.0, 160.0 >> vPickupPos[APT_LOWLAND][12] = << 1306.135, 2105.401, 81.951 >> vPickupRot[APT_LOWLAND][12] = << 3.0, 10.0, 165.0 >> vPickupPos[APT_LOWLAND][13] = << 142.407, 6865.949, 27.324 >> vPickupRot[APT_LOWLAND][13] = << 1.0, 3.0, 120.0 >> vPickupPos[APT_LOWLAND][14] = << 437.683, 782.841, 192.166 >> vPickupRot[APT_LOWLAND][14] = << -9.0, -3.600, 125.280 >> vPickupPos[APT_HIGHLAND][0] = << -95.011, 321.923, 141.565 >> vPickupRot[APT_HIGHLAND][0] = << 1.0, 0.500, 80.0 >> vPickupPos[APT_HIGHLAND][1] = << -1334.848, -1066.133, 11.307 >> vPickupRot[APT_HIGHLAND][1] = << 1.0, 2.0, 135.0 >> vPickupPos[APT_HIGHLAND][2] = << 1483.204, 6029.105, 310.793 >> vPickupRot[APT_HIGHLAND][2] = << 5.0, 2.0, 100.0 >> vPickupPos[APT_HIGHLAND][3] = << 502.151, 5506.052, 773.540 >> vPickupRot[APT_HIGHLAND][3] = << 1.0, 2.0, 245.0 >> vPickupPos[APT_HIGHLAND][4] = << 3336.348, -274.956, 3.965 >> vPickupRot[APT_HIGHLAND][4] = << 0.0, 6.0, 100.0 >> vPickupPos[APT_HIGHLAND][5] = << -1002.453, 4499.704, 156.972 >> vPickupRot[APT_HIGHLAND][5] = << 0.0, 0.0, 25.0 >> vPickupPos[APT_UNDERWATER][0] = << 87.199, 4315.681, 20.717 >> vPickupRot[APT_UNDERWATER][0] = << -8.0, 3.0, 180.0 >> vPickupPos[APT_UNDERWATER][1] = << -1845.740, -1257.063, -23.453 >> vPickupRot[APT_UNDERWATER][1] = << 8.0, 0.0, 0.0 >> vPickupPos[APT_UNDERWATER][2] = << -563.346, -2481.856, -17.769 >> vPickupRot[APT_UNDERWATER][2] = << -2.0, 2.0, 195.0 >> vPickupPos[APT_UNDERWATER][3] = << 4164.940, 3569.537, -48.400 >> vPickupRot[APT_UNDERWATER][3] = << 2.160, -15.120, 170.0 >> vPickupPos[APT_UNDERWATER][4] = << -781.0, 6619.869, -19.919 >> vPickupRot[APT_UNDERWATER][4] = << -15.840, 4.0, 100.0 >> vPickupPos[APT_UNDERWATER][5] = << -2873.0, 2594.401, -11.424 >> vPickupRot[APT_UNDERWATER][5] = << 5.760, 0.0, 330.0 >> vPickupPos[APT_SECRET][0] = << -1597.148, 4593.326, 38.139 >> vPickupRot[APT_SECRET][0] = << 5.0, 20.0, 0.0 >> vPickupPos[APT_SECRET][1] = << -1562.325, 4462.752, 17.231 >> vPickupRot[APT_SECRET][1] = << -11.0, 2.0, 200.0 >> vPickupPos[APT_SECRET][2] = << -1472.531, 4439.456, 18.862 >> vPickupRot[APT_SECRET][2] = << -10.0, -5.0, 0.0 >> vPickupPos[APT_SECRET][3] = << 34.291, 4322.551, 42.358 >> vPickupRot[APT_SECRET][3] = << 0.0, 3.0, 5.0 >> vPickupPos[APT_SECRET][4] = << 295.732, 4275.579, 40.985 >> vPickupRot[APT_SECRET][4] = << 7.920, 0.0, 0.0 >> vPickupPos[APT_SECRET][5] = << 1106.727, 4520.820, 50.421 >> vPickupRot[APT_SECRET][5] = << -1.0, -2.0, 310.0 >> vPickupPos[APT_SECRET][6] = << 1662.614, 5152.309, 151.377 >> vPickupRot[APT_SECRET][6] = << -5.0, 0.0, 260.0 >> //Animal spawn data. vSpawnPos[APT_LOWLAND][0] = <<-531.5155, 4192.8955, 192.3638>> fSpawnHead[APT_LOWLAND][0] = 184.6266 fSpawnPitch[APT_LOWLAND][0] = -12.0 vSpawnPos[APT_LOWLAND][1] = <<-112.5678, 1425.6851, 293.9277>> fSpawnHead[APT_LOWLAND][1] = 4.5629 fSpawnPitch[APT_LOWLAND][1] = -12.0 vSpawnPos[APT_LOWLAND][2] = <<2584.3120, 6161.1787, 163.9988>> fSpawnHead[APT_LOWLAND][2] = 358.1584 fSpawnPitch[APT_LOWLAND][2] = -12.0 vSpawnPos[APT_LOWLAND][3] = <<2347.6477, 2549.3523, 45.6677>> fSpawnHead[APT_LOWLAND][3] = 349.2026 fSpawnPitch[APT_LOWLAND][3] = -12.0 vSpawnPos[APT_LOWLAND][4] = <<1422.3647, -2612.9714, 46.7801>> fSpawnHead[APT_LOWLAND][4] = 3.9096 fSpawnPitch[APT_LOWLAND][4] = -12.0 vSpawnPos[APT_LOWLAND][5] = <<1328.1217, -609.4195, 73.3241>> fSpawnHead[APT_LOWLAND][5] = 232.2858 fSpawnPitch[APT_LOWLAND][5] = -12.0 vSpawnPos[APT_LOWLAND][6] = <<-303.2847, -1658.9226, 30.8488>> fSpawnHead[APT_LOWLAND][6] = 332.2989 fSpawnPitch[APT_LOWLAND][6] = -15.0 vSpawnPos[APT_LOWLAND][7] = <<-1172.1837, -2018.7661, 12.1605>> fSpawnHead[APT_LOWLAND][7] = 180.8184 fSpawnPitch[APT_LOWLAND][7] = -12.0 vSpawnPos[APT_LOWLAND][8] = <<-2003.7185, 3526.0918, 56.6927>> fSpawnHead[APT_LOWLAND][8] = 164.7774 fSpawnPitch[APT_LOWLAND][8] = -12.0 vSpawnPos[APT_LOWLAND][9] = <<-1617.1471, 2073.6863, 76.9415>> fSpawnHead[APT_LOWLAND][9] = 66.5177 fSpawnPitch[APT_LOWLAND][9] = -12.0 vSpawnPos[APT_LOWLAND][10] = <<512.3995, 3013.7869, 39.7735>> fSpawnHead[APT_LOWLAND][10] = 119.1231 fSpawnPitch[APT_LOWLAND][10] = -12.0 vSpawnPos[APT_LOWLAND][11] = <<-1032.4998, 891.1083, 167.2734>> fSpawnHead[APT_LOWLAND][11] = 139.8774 fSpawnPitch[APT_LOWLAND][11] = -12.0 vSpawnPos[APT_LOWLAND][12] = <<1299.4652, 2105.8928, 80.0829>> fSpawnHead[APT_LOWLAND][12] = 97.5191 fSpawnPitch[APT_LOWLAND][12] = -12.0 vSpawnPos[APT_LOWLAND][13] = <<143.9502, 6867.6396, 27.3547>> fSpawnHead[APT_LOWLAND][13] = 335.1610 fSpawnPitch[APT_LOWLAND][13] = -12.0 vSpawnPos[APT_LOWLAND][14] = <<436.9434, 783.1006, 192.1307>> fSpawnHead[APT_LOWLAND][14] = 116.2676 fSpawnPitch[APT_LOWLAND][14] = -12.0 vSpawnPos[APT_HIGHLAND][0] = <<-90.1056, 318.6911, 142.8513>> fSpawnHead[APT_HIGHLAND][0] = 155.7856 fSpawnPitch[APT_HIGHLAND][0] = -15.0 vSpawnPos[APT_HIGHLAND][1] = <<-1352.2411, -1090.4954, 19.1143>> fSpawnHead[APT_HIGHLAND][1] = 81.1243 fSpawnPitch[APT_HIGHLAND][1] = -5.0 vSpawnPos[APT_HIGHLAND][2] = <<1466.0331, 6043.3350, 303.1763>> fSpawnHead[APT_HIGHLAND][2] = 329.3290 fSpawnPitch[APT_HIGHLAND][2] = -28.5 //<<1488.0555, 6044.7388, 316.4484>> 321.2529 vSpawnPos[APT_HIGHLAND][3] = <<499.6498, 5515.7427, 777.0497>> fSpawnHead[APT_HIGHLAND][3] = 202.7672 fSpawnPitch[APT_HIGHLAND][3] = -20.0 vSpawnPos[APT_HIGHLAND][4] = <<3339.1919, -273.7192, 4.1283>> fSpawnHead[APT_HIGHLAND][4] = 349.2330 fSpawnPitch[APT_HIGHLAND][4] = -9.0 vSpawnPos[APT_HIGHLAND][5] = <<-983.5906, 4484.8691, 145.7952>> fSpawnHead[APT_HIGHLAND][5] = 256.3761 fSpawnPitch[APT_HIGHLAND][5] = -18.0 vSpawnPos[APT_UNDERWATER][0] = <<91.3454, 4318.5913, 26.4644>> fSpawnHead[APT_UNDERWATER][0] = 171.3796 fSpawnPitch[APT_UNDERWATER][0] = -2.0 vSpawnPos[APT_UNDERWATER][1] = <<-1831.9692, -1223.1770, -2.9458>> fSpawnHead[APT_UNDERWATER][1] = 228.1000 fSpawnPitch[APT_UNDERWATER][1] = -2.0 vSpawnPos[APT_UNDERWATER][2] = <<-574.5851, -2478.3750, -11.0610>> fSpawnHead[APT_UNDERWATER][2] = 262.1271 fSpawnPitch[APT_UNDERWATER][2] = -2.0 vSpawnPos[APT_UNDERWATER][3] = <<4155.3315, 3566.9980, -39.9966>> fSpawnHead[APT_UNDERWATER][3] = 183.5475 fSpawnPitch[APT_UNDERWATER][3] = -2.0 vSpawnPos[APT_UNDERWATER][4] = <<-750.1962, 6603.1489, -11.7596>> fSpawnHead[APT_UNDERWATER][4] = 61.7154 fSpawnPitch[APT_UNDERWATER][4] = -2.0 vSpawnPos[APT_UNDERWATER][5] = <<-2871.6328, 2613.8621, -4.2648>> fSpawnHead[APT_UNDERWATER][5] = 180.3624 fSpawnPitch[APT_UNDERWATER][5] = -2.0 vSpawnPos[APT_SECRET][0] = <<-1596.1281, 4595.7778, 40.5927>> fSpawnHead[APT_SECRET][0] = 200.6605 fSpawnPitch[APT_SECRET][0] = -12.0 vSpawnPos[APT_SECRET][1] = <<-1567.3816, 4464.3052, 17.4783>> fSpawnHead[APT_SECRET][1] = 118.7467 fSpawnPitch[APT_SECRET][1] = -12.0 vSpawnPos[APT_SECRET][2] = <<-1436.3053, 4428.8013, 44.8536>> fSpawnHead[APT_SECRET][2] = 43.5218 fSpawnPitch[APT_SECRET][2] = -12.0 vSpawnPos[APT_SECRET][3] = <<31.2408, 4328.0522, 43.9517>> fSpawnHead[APT_SECRET][3] = 163.1396 fSpawnPitch[APT_SECRET][3] = -12.0 vSpawnPos[APT_SECRET][4] = <<278.1924, 4276.5039, 39.3595>> fSpawnHead[APT_SECRET][4] = 75.6033 fSpawnPitch[APT_SECRET][4] = -12.0 vSpawnPos[APT_SECRET][5] = <<1116.0020, 4506.7651, 64.8542>> fSpawnHead[APT_SECRET][5] = 116.3962 fSpawnPitch[APT_SECRET][5] = -12.0 vSpawnPos[APT_SECRET][6] = <<1676.1929, 5139.8701, 149.3976>> fSpawnHead[APT_SECRET][6] = 232.4278 fSpawnPitch[APT_SECRET][6] = -15.0 //Story character respawn data. vRespawnPos[APT_LOWLAND][0] = <<-524.6988, 4192.3159, 192.7360>> fRespawnHead[APT_LOWLAND][0] = 227.6253 vRespawnPos[APT_LOWLAND][1] = <<-117.8253, 1442.4640, 293.5365>> fRespawnHead[APT_LOWLAND][1] = 87.7333 vRespawnPos[APT_LOWLAND][2] = <<2557.4600, 6175.3799, 162.3287>> fRespawnHead[APT_LOWLAND][2] = 288.4795 vRespawnPos[APT_LOWLAND][3] = <<2348.4385, 2558.8052, 45.6677>> fRespawnHead[APT_LOWLAND][3] = 148.4075 vRespawnPos[APT_LOWLAND][4] = <<1430.1506, -2603.4170, 47.0881>> fRespawnHead[APT_LOWLAND][4] = 267.3886 vRespawnPos[APT_LOWLAND][5] = <<1333.4773, -612.6886, 73.3284>> fRespawnHead[APT_LOWLAND][5] = 63.2009 vRespawnPos[APT_LOWLAND][6] = <<-297.3636, -1640.2587, 30.8488>> fRespawnHead[APT_LOWLAND][6] = 289.2072 vRespawnPos[APT_LOWLAND][7] = <<-1165.9183, -2057.0120, 13.2056>> fRespawnHead[APT_LOWLAND][7] = 315.7894 vRespawnPos[APT_LOWLAND][8] = <<-1994.0844, 3425.9937, 30.1122>> fRespawnHead[APT_LOWLAND][8] = 108.6822 vRespawnPos[APT_LOWLAND][9] = <<-1639.0577, 2098.2478, 84.2193>> fRespawnHead[APT_LOWLAND][9] = 338.7872 vRespawnPos[APT_LOWLAND][10] = <<495.2835, 3013.3164, 40.0883>> fRespawnHead[APT_LOWLAND][10] = 198.0553 vRespawnPos[APT_LOWLAND][11] = <<-1066.2367, 846.7995, 165.8318>> fRespawnHead[APT_LOWLAND][11] = 94.0064 vRespawnPos[APT_LOWLAND][12] = <<1383.1772, 2158.0913, 96.6152>> fRespawnHead[APT_LOWLAND][12] = 79.5920 vRespawnPos[APT_LOWLAND][13] = <<103.1246, 6858.5254, 14.4039>> fRespawnHead[APT_LOWLAND][13] = 332.0037 vRespawnPos[APT_LOWLAND][14] = <<391.7144, 799.8500, 186.6764>> fRespawnHead[APT_LOWLAND][14] = 191.2877 vRespawnPos[APT_HIGHLAND][0] = <<-109.7514, 360.1761, 111.6961>> fRespawnHead[APT_HIGHLAND][0] = 145.6437 vRespawnPos[APT_HIGHLAND][1] = <<-1298.9086, -1037.6077, 11.4803>> fRespawnHead[APT_HIGHLAND][1] = 117.7394 vRespawnPos[APT_HIGHLAND][2] = <<1479.4984, 6030.3364, 310.9688>> fRespawnHead[APT_HIGHLAND][2] = 64.9945 vRespawnPos[APT_HIGHLAND][3] = <<517.0012, 5505.4873, 769.9974>> fRespawnHead[APT_HIGHLAND][3] = 181.1102 vRespawnPos[APT_HIGHLAND][4] = <<3334.1162, -278.0879, 3.2410>> fRespawnHead[APT_HIGHLAND][4] = 253.4440 vRespawnPos[APT_HIGHLAND][5] = <<-1019.0459, 4507.2334, 156.9224>> fRespawnHead[APT_HIGHLAND][5] = 109.9727 vRespawnPos[APT_UNDERWATER][0] = <<93.9209, 4327.6221, 25.8346>> fRespawnHead[APT_UNDERWATER][0] = 125.6890 vRespawnPos[APT_UNDERWATER][1] = <<-1797.5909, -1234.8378, -5.0000>> fRespawnHead[APT_UNDERWATER][1] = 311.2352 vRespawnPos[APT_UNDERWATER][2] = <<-559.9407, -2481.4109, -4.2611>> fRespawnHead[APT_UNDERWATER][2] = 254.5420 vRespawnPos[APT_UNDERWATER][3] = <<4141.1323, 3552.2490, -4.0547>> fRespawnHead[APT_UNDERWATER][3] = 116.5838 vRespawnPos[APT_UNDERWATER][4] = <<-772.8342, 6616.0649, -4.3376>> fRespawnHead[APT_UNDERWATER][4] = 218.2574 vRespawnPos[APT_UNDERWATER][5] = <<-2865.1311, 2603.2021, -4.1572>> fRespawnHead[APT_UNDERWATER][5] = 239.9374 vRespawnPos[APT_SECRET][0] = <<-1634.9861, 4588.8208, 43.2674>> fRespawnHead[APT_SECRET][0] = 37.7429 vRespawnPos[APT_SECRET][1] = <<-1632.2286, 4436.8857, 0.1957>> fRespawnHead[APT_SECRET][1] = 47.7317 vRespawnPos[APT_SECRET][2] = <<-1433.1962, 4421.3945, 46.2258>> fRespawnHead[APT_SECRET][2] = 66.4789 vRespawnPos[APT_SECRET][3] = <<39.5120, 4326.8232, 42.8410>> fRespawnHead[APT_SECRET][3] = 248.5840 vRespawnPos[APT_SECRET][4] = <<282.5654, 4272.0122, 39.3133>> fRespawnHead[APT_SECRET][4] = 93.8162 vRespawnPos[APT_SECRET][5] = <<1111.1002, 4539.9712, 52.7703>> fRespawnHead[APT_SECRET][5] = 161.8738 vRespawnPos[APT_SECRET][6] = <<1674.5198, 5146.0874, 149.8852>> fRespawnHead[APT_SECRET][6] = 302.0059 //Vehicle reposition data. vVehiclePos[APT_LOWLAND][0] = <<-538.6052, 4192.4507, 191.9071>> fVehicleHead[APT_LOWLAND][0] = 117.3685 vVehiclePos[APT_LOWLAND][1] = <<-130.9344, 1467.0774, 292.8185>> fVehicleHead[APT_LOWLAND][1] = 9.6516 vVehiclePos[APT_LOWLAND][2] = <<2592.9504, 6179.6523, 165.7680>> fVehicleHead[APT_LOWLAND][2] = 22.0803 vVehiclePos[APT_LOWLAND][3] = <<2330.0549, 2546.6521, 45.6677>> fVehicleHead[APT_LOWLAND][3] = 1.6841 vVehiclePos[APT_LOWLAND][4] = <<1440.2496, -2611.4546, 47.2619>> fVehicleHead[APT_LOWLAND][4] = 344.7832 vVehiclePos[APT_LOWLAND][5] = <<1347.1837, -606.6709, 73.3589>> fVehicleHead[APT_LOWLAND][5] = 323.1254 vVehiclePos[APT_LOWLAND][6] = <<-248.1520, -1689.0166, 32.4828>> fVehicleHead[APT_LOWLAND][6] = 179.6259 vVehiclePos[APT_LOWLAND][7] = <<-1155.6938, -2036.0483, 12.1606>> fVehicleHead[APT_LOWLAND][7] = 135.3064 vVehiclePos[APT_LOWLAND][8] = <<-2016.4073, 3412.0730, 30.1195>> fVehicleHead[APT_LOWLAND][8] = 2.2746 vVehiclePos[APT_LOWLAND][9] = <<-1585.8943, 2102.4768, 66.8681>> fVehicleHead[APT_LOWLAND][9] = 176.9579 vVehiclePos[APT_LOWLAND][10] = <<522.2675, 3030.5461, 38.8381>> fVehicleHead[APT_LOWLAND][10] = 222.1449 vVehiclePos[APT_LOWLAND][11] = <<-1086.9869, 787.2667, 163.7984>> fVehicleHead[APT_LOWLAND][11] = 98.3083 vVehiclePos[APT_LOWLAND][12] = <<1413.9580, 2160.1021, 97.1414>> fVehicleHead[APT_LOWLAND][12] = 11.7878 vVehiclePos[APT_LOWLAND][13] = <<106.1145, 6857.8354, 14.5062>> fVehicleHead[APT_LOWLAND][13] = 184.1832 vVehiclePos[APT_LOWLAND][14] = <<402.4059, 783.2064, 186.6439>> fVehicleHead[APT_LOWLAND][14] = 134.5921 vVehiclePos[APT_HIGHLAND][0] = <<-128.1134, 379.8373, 111.7576>> fVehicleHead[APT_HIGHLAND][0] = 154.6337 vVehiclePos[APT_HIGHLAND][1] = <<-1312.1760, -1068.4644, 5.8127>> fVehicleHead[APT_HIGHLAND][1] = 29.1101 vVehiclePos[APT_HIGHLAND][2] = <<1495.2583, 6032.5420, 308.7726>> fVehicleHead[APT_HIGHLAND][2] = 288.5849 vVehiclePos[APT_HIGHLAND][3] = <<506.5558, 5533.2139, 776.3751>> fVehicleHead[APT_HIGHLAND][3] = 207.4062 vVehiclePos[APT_HIGHLAND][4] = <<2852.0632, -111.2995, 1.0301>> fVehicleHead[APT_HIGHLAND][4] = 42.0921 vVehiclePos[APT_HIGHLAND][5] = <<-972.9418, 4549.8477, 126.8038>> fVehicleHead[APT_HIGHLAND][5] = 262.6260 vVehiclePos[APT_UNDERWATER][0] = <<12.7101, 4443.6348, 58.5636>> fVehicleHead[APT_UNDERWATER][0] = 276.7658 vVehiclePos[APT_UNDERWATER][1] = <<-1811.7888, -1240.5096, 12.0174>> fVehicleHead[APT_UNDERWATER][1] = 51.5445 vVehiclePos[APT_UNDERWATER][2] = <<-439.6339, -2460.3359, 5.0008>> fVehicleHead[APT_UNDERWATER][2] = 228.8953 vVehiclePos[APT_UNDERWATER][3] = <<3911.2756, 3453.2720, 4.3854>> fVehicleHead[APT_UNDERWATER][3] = 64.5589 vVehiclePos[APT_UNDERWATER][4] = <<-543.1194, 6411.5640, 1.7985>> fVehicleHead[APT_UNDERWATER][4] = 288.9971 vVehiclePos[APT_UNDERWATER][5] = <<-2780.5483, 2534.4990, 1.5562>> fVehicleHead[APT_UNDERWATER][5] = 137.5726 vVehiclePos[APT_SECRET][0] = <<-1643.0061, 4603.5952, 44.1547>> fVehicleHead[APT_SECRET][0] = 280.9118 vVehiclePos[APT_SECRET][1] = <<-1634.6913, 4412.9478, 1.6828>> fVehicleHead[APT_SECRET][1] = 32.5647 vVehiclePos[APT_SECRET][2] = <<-1460.9769, 4480.4946, 18.2185>> fVehicleHead[APT_SECRET][2] = 289.6174 vVehiclePos[APT_SECRET][3] = <<12.7101, 4443.6348, 58.5636>> fVehicleHead[APT_SECRET][3] = 276.7658 vVehiclePos[APT_SECRET][4] = <<282.5648, 4300.9976, 43.2166>> fVehicleHead[APT_SECRET][4] = 355.7436 vVehiclePos[APT_SECRET][5] = <<1061.7312, 4453.1748, 54.9683>> fVehicleHead[APT_SECRET][5] = 263.9897 vVehiclePos[APT_SECRET][6] = <<1684.7528, 5173.5146, 145.7554>> fVehicleHead[APT_SECRET][6] = 221.6928 ENDPROC FUNC VECTOR Get_Highland_Pickup_Helicopter_Position(INT paramIndex) SWITCH paramIndex CASE 0 RETURN <<-124.6880, 426.3544, 112.4759>> BREAK CASE 1 RETURN <<-1349.7454, -1071.8394, 10.4666>> BREAK CASE 2 RETURN <<1495.2583, 6032.5420, 308.7726>> BREAK CASE 3 RETURN <<506.5558, 5533.2139, 776.3751>> BREAK CASE 4 RETURN <<3293.0806, -146.4574, 15.0023>> BREAK CASE 5 RETURN <<-1001.4104, 4512.1934, 158.1028>> BREAK ENDSWITCH RETURN <<0,0,0>> ENDFUNC FUNC FLOAT Get_Highland_Pickup_Helicopter_Heading(INT paramIndex) SWITCH paramIndex CASE 0 RETURN 189.2918 BREAK CASE 1 RETURN 299.4451 BREAK CASE 2 RETURN 288.5849 BREAK CASE 3 RETURN 207.4062 BREAK CASE 4 RETURN 214.5423 BREAK CASE 5 RETURN 150.8355 BREAK ENDSWITCH RETURN 0.0 ENDFUNC FUNC MODEL_NAMES Get_Animal_Pickup_Model(AnimalPickupType paramType, INT paramIndex) SWITCH paramType CASE APT_LOWLAND SWITCH paramIndex CASE 5 RETURN PROP_PEYOTE_LOWLAND_02 BREAK DEFAULT RETURN PROP_PEYOTE_LOWLAND_01 BREAK ENDSWITCH BREAK CASE APT_HIGHLAND SWITCH paramIndex CASE 0 RETURN PROP_PEYOTE_HIGHLAND_02 BREAK CASE 1 RETURN PROP_PEYOTE_HIGHLAND_02 BREAK DEFAULT RETURN PROP_PEYOTE_HIGHLAND_01 BREAK ENDSWITCH BREAK CASE APT_UNDERWATER RETURN PROP_PEYOTE_WATER_01 BREAK CASE APT_SECRET RETURN PROP_PEYOTE_GOLD_01 BREAK ENDSWITCH RETURN PROP_PEYOTE_LOWLAND_01 ENDFUNC FUNC AnimalPickupType Get_Animal_Type(AnimalPickup paramPickup) SWITCH paramPickup CASE AP_LOWLAND_BOAR CASE AP_LOWLAND_CAT CASE AP_LOWLAND_COW CASE AP_LOWLAND_COYOTE CASE AP_LOWLAND_DEER CASE AP_LOWLAND_HUSKY CASE AP_LOWLAND_MTLION CASE AP_LOWLAND_PIG CASE AP_LOWLAND_POODLE CASE AP_LOWLAND_PUG CASE AP_LOWLAND_RABBIT CASE AP_LOWLAND_RETRIEVER CASE AP_LOWLAND_ROTTWEILER CASE AP_LOWLAND_SHEPHERD CASE AP_LOWLAND_WESTY CASE AP_SECRET_CHOP RETURN APT_LOWLAND BREAK CASE AP_HIGHLAND_CHICKENHAWK CASE AP_HIGHLAND_CORMORANT CASE AP_HIGHLAND_CROW CASE AP_HIGHLAND_HEN CASE AP_HIGHLAND_PIGEON CASE AP_HIGHLAND_SEAGULL RETURN APT_HIGHLAND BREAK CASE AP_UNDERWATER_DOLPHIN CASE AP_UNDERWATER_FISH CASE AP_UNDERWATER_KILLERWHALE CASE AP_UNDERWATER_SHARKHAMMER CASE AP_UNDERWATER_SHARKTIGER CASE AP_UNDERWATER_STINGRAY CASE AP_UNDERWATER_HUMPBACKWHALE RETURN APT_UNDERWATER BREAK CASE AP_SECRET_SASQUATCH RETURN APT_SECRET BREAK ENDSWITCH SCRIPT_ASSERT("Get_Animal_Type: Animal does not have a type assigned. Bug BenR.") RETURN APT_INVALID ENDFUNC FUNC MODEL_NAMES Get_Animal_Model_From_Pickup_Enum(AnimalPickup paramPickup) SWITCH paramPickup CASE AP_LOWLAND_BOAR RETURN A_C_BOAR BREAK CASE AP_LOWLAND_CAT RETURN A_C_CAT_01 BREAK CASE AP_LOWLAND_COW RETURN A_C_COW BREAK CASE AP_LOWLAND_COYOTE RETURN A_C_COYOTE BREAK CASE AP_LOWLAND_DEER RETURN A_C_DEER BREAK CASE AP_LOWLAND_HUSKY RETURN A_C_HUSKY BREAK CASE AP_LOWLAND_MTLION RETURN A_C_MTLION BREAK CASE AP_LOWLAND_PIG RETURN A_C_PIG BREAK CASE AP_LOWLAND_POODLE RETURN A_C_POODLE BREAK CASE AP_LOWLAND_PUG RETURN A_C_PUG BREAK CASE AP_LOWLAND_RABBIT RETURN A_C_RABBIT_01 BREAK CASE AP_LOWLAND_RETRIEVER RETURN A_C_RETRIEVER BREAK CASE AP_LOWLAND_ROTTWEILER RETURN A_C_ROTTWEILER BREAK CASE AP_LOWLAND_SHEPHERD RETURN A_C_SHEPHERD BREAK CASE AP_LOWLAND_WESTY RETURN A_C_WESTY BREAK CASE AP_HIGHLAND_CHICKENHAWK RETURN A_C_CHICKENHAWK BREAK CASE AP_HIGHLAND_CORMORANT RETURN A_C_CORMORANT BREAK CASE AP_HIGHLAND_CROW RETURN A_C_CROW BREAK CASE AP_HIGHLAND_HEN RETURN A_C_HEN BREAK CASE AP_HIGHLAND_PIGEON RETURN A_C_PIGEON BREAK CASE AP_HIGHLAND_SEAGULL RETURN A_C_SEAGULL BREAK CASE AP_UNDERWATER_DOLPHIN RETURN A_C_DOLPHIN BREAK CASE AP_UNDERWATER_FISH RETURN A_C_FISH BREAK CASE AP_UNDERWATER_KILLERWHALE RETURN A_C_KILLERWHALE BREAK CASE AP_UNDERWATER_SHARKHAMMER RETURN A_C_SHARKHAMMER BREAK CASE AP_UNDERWATER_SHARKTIGER RETURN A_C_SHARKTIGER BREAK CASE AP_UNDERWATER_STINGRAY RETURN A_C_STINGRAY BREAK CASE AP_SECRET_SASQUATCH RETURN IG_ORLEANS BREAK ENDSWITCH SCRIPT_ASSERT("Get_Animal_Model_From_Pickup_Enum: Invalid enum passed.") RETURN DUMMY_MODEL_FOR_SCRIPT ENDFUNC PROC CLEANUP_DRAW_WHITE_RECT() drawRect = FALSE whiteBoxfadeIn = TRUE drawTimer = -1 whiteAlpha = 0 ENDPROC PROC INIT_DRAW_WHITE_RECT_FADE_IN() drawRect = TRUE whiteBoxfadeIn = TRUE drawTimer = GET_GAME_TIMER() + 500 whiteAlpha = 0 ENDPROC PROC INIT_DRAW_WHITE_RECT_FADE_OUT() drawRect = TRUE whiteBoxfadeIn = FALSE drawTimer = GET_GAME_TIMER() + 500 whiteAlpha = 255 ENDPROC PROC DRAW_WHITE_RECT() IF drawRect INT temp = drawTimer - GET_GAME_TIMER() FLOAT fTemp IF whiteBoxfadeIn fTemp = 255-(temp*0.51) IF fTemp >= 0 //increase alpha whiteAlpha = ROUND(fTemp) ENDIF IF GET_GAME_TIMER() > drawTimer whiteAlpha = 255 ENDIF ELSE fTemp = temp*0.51 IF fTemp >= 0 //decrease alpha whiteAlpha = ROUND(fTemp) ENDIF IF whiteAlpha < 0 whiteAlpha = 0 ENDIF IF GET_GAME_TIMER() > drawTimer CLEANUP_DRAW_WHITE_RECT() ENDIF ENDIF DRAW_RECT(0.5,0.5,1,1,255,255,255,whiteAlpha) //CPRINTLN(DEBUG_ANIMAL_MODE, "whiteAlpha ", whiteAlpha) ENDIF ENDPROC PROC Get_Number_Of_Variations_For_Animal(AnimalVariationData &sData, AnimalPickup paramAnimal) SWITCH paramAnimal CASE AP_LOWLAND_BOAR sData.iHead = 4 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_LOWLAND_CAT sData.iHead = 3 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_LOWLAND_COW sData.iHead = 4 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_LOWLAND_COYOTE sData.iHead = 5 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_LOWLAND_DEER sData.iHead = 3 sData.iTorso = 1 sData.iLeg = 1 SET_PED_COMPONENT_VARIATION(PLAYER_PED_ID(),PED_COMP_SPECIAL,1,0) //draw antlers BREAK CASE AP_LOWLAND_HUSKY sData.iHead = 3 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_LOWLAND_MTLION sData.iHead = 3 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_LOWLAND_PIG sData.iHead = 3 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_LOWLAND_POODLE sData.iHead = 1 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_LOWLAND_PUG sData.iHead = 1 sData.iTorso = 6 sData.iLeg = 4 BREAK CASE AP_LOWLAND_RABBIT sData.iHead = 4 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_LOWLAND_RETRIEVER sData.iHead = 4 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_LOWLAND_ROTTWEILER sData.iHead = 1 sData.iTorso = 4 sData.iLeg = 3 BREAK CASE AP_LOWLAND_SHEPHERD sData.iHead = 3 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_LOWLAND_WESTY sData.iHead = 1 sData.iTorso = 6 sData.iLeg = 3 BREAK CASE AP_HIGHLAND_CHICKENHAWK sData.iHead = 1 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_HIGHLAND_CORMORANT sData.iHead = 1 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_HIGHLAND_CROW sData.iHead = 1 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_HIGHLAND_HEN sData.iHead = 1 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_HIGHLAND_PIGEON sData.iHead = 1 sData.iTorso = 4 sData.iLeg = 1 BREAK CASE AP_HIGHLAND_SEAGULL sData.iHead = 1 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_UNDERWATER_DOLPHIN sData.iHead = 1 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_UNDERWATER_FISH sData.iHead = 1 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_UNDERWATER_KILLERWHALE sData.iHead = 1 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_UNDERWATER_SHARKHAMMER sData.iHead = 1 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_UNDERWATER_SHARKTIGER sData.iHead = 1 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_UNDERWATER_STINGRAY sData.iHead = 1 sData.iTorso = 1 sData.iLeg = 1 BREAK CASE AP_SECRET_SASQUATCH sData.iHead = 1 sData.iTorso = 1 sData.iLeg = 1 BREAK DEFAULT SCRIPT_ASSERT("Get_Number_Of_Variations_For_Animal: Invalid animal enum passed.") BREAK ENDSWITCH ENDPROC FUNC INT Get_Number_Of_Animal_Pickups_Of_Type(AnimalPickupType paramType) SWITCH paramType CASE APT_LOWLAND RETURN ANIMAL_PICKUP_LOWLAND_COUNT BREAK CASE APT_HIGHLAND RETURN ANIMAL_PICKUP_HIGHLAND_COUNT BREAK CASE APT_UNDERWATER RETURN ANIMAL_PICKUP_UNDERWATER_COUNT BREAK CASE APT_SECRET RETURN ANIMAL_PICKUP_SECRET_COUNT BREAK ENDSWITCH SCRIPT_ASSERT("Get_Number_Of_Animal_Pickups_Of_Type: Invalid type enum passed.") RETURN -1 ENDFUNC FUNC STRING Get_Animation_Camera_Choice() //choose correct camera(s), then choose from best cams for each anim/location STRING cam = "" SWITCH eTriggeredType CASE APT_LOWLAND SWITCH iTriggeredIndex CASE 0 CASE 3 CASE 6 CASE 7 CASE 8 CASE 9 CASE 10 CASE 11 CASE 12 CASE 13 CASE 14 IF GET_RANDOM_BOOL() cam = "eat_peyote_cam1" ELSE cam = "eat_peyote_cam2" ENDIF BREAK CASE 1 CASE 2 CASE 4 SWITCH GET_RANDOM_INT_IN_RANGE(0,3) CASE 0 cam = "eat_peyote_cam1" BREAK CASE 1 cam = "eat_peyote_cam2" BREAK CASE 2 cam = "eat_peyote_cam4" BREAK ENDSWITCH BREAK CASE 5 cam = "eat_peyote_plantpot_cam1" BREAK ENDSWITCH BREAK CASE APT_HIGHLAND SWITCH iTriggeredIndex CASE 0 CASE 1 cam = "eat_peyote_plantpot_cam1" BREAK CASE 2 CASE 5 IF GET_RANDOM_BOOL() cam = "eat_peyote_cam1" ELSE cam = "eat_peyote_cam2" ENDIF BREAK CASE 3 CASE 4 cam = "eat_peyote_cam2" BREAK ENDSWITCH BREAK CASE APT_UNDERWATER SWITCH iTriggeredIndex CASE 0 cam = "eat_peyote_cam2" BREAK DEFAULT cam = "eat_peyote_cam1" BREAK ENDSWITCH BREAK CASE APT_SECRET cam = "eat_peyote_cam1" BREAK ENDSWITCH IF IS_STRING_NULL_OR_EMPTY(cam) SCRIPT_ASSERT("Get_Animation_Camera_Choice Peyote not found") ENDIF RETURN cam ENDFUNC PROC Get_Pickup_Type_Lead_In_Anim_Data(AnimalAnimationData &sData, MODEL_NAMES paramModel) SWITCH paramModel CASE PROP_PEYOTE_LOWLAND_01 CASE PROP_PEYOTE_HIGHLAND_01 CASE PROP_PEYOTE_GOLD_01 sData.strDict = "random@peyote@eat" sData.strAnim = "eat_peyote" BREAK CASE PROP_PEYOTE_LOWLAND_02 CASE PROP_PEYOTE_HIGHLAND_02 sData.strDict = "random@peyote@eat" sData.strAnim = "eat_peyote_plantpot" BREAK CASE PROP_PEYOTE_WATER_01 sData.strDict = "random@peyote@eatswimming" sData.strAnim = "eat_peyote" BREAK DEFAULT SCRIPT_ASSERT("Get_Pickup_Type_Lead_In_Anim_Data: Invalid model enum passed.") BREAK ENDSWITCH sData.strCamAnim = Get_Animation_Camera_Choice() CPRINTLN(DEBUG_ANIMAL_MODE, "Selected lead-in animation data. Dict:", sData.strDict, " Anim:", sData.strAnim, " CamAnim:", sData.strCamAnim, ".") ENDPROC PROC Get_Pickup_Type_Animal_Idle_Anim_Data() SWITCH eTriggeredAnimal CASE AP_LOWLAND_BOAR sAnim.strIdleDict = "creatures@boar@amb@peyote@enter" BREAK CASE AP_LOWLAND_CAT sAnim.strIdleDict = "creatures@cat@amb@peyote@enter" BREAK CASE AP_LOWLAND_COW sAnim.strIdleDict = "creatures@cow@amb@peyote@enter" BREAK CASE AP_LOWLAND_COYOTE sAnim.strIdleDict = "creatures@coyote@amb@peyote@enter" BREAK CASE AP_LOWLAND_DEER sAnim.strIdleDict = "creatures@deer@amb@peyote@enter" BREAK CASE AP_LOWLAND_HUSKY sAnim.strIdleDict = "creatures@retriever@amb@peyote@enter" BREAK CASE AP_LOWLAND_MTLION sAnim.strIdleDict = "creatures@cougar@amb@peyote@enter" BREAK CASE AP_LOWLAND_PIG sAnim.strIdleDict = "creatures@pig@amb@peyote@enter" BREAK CASE AP_LOWLAND_POODLE sAnim.strIdleDict = "creatures@pug@amb@peyote@enter" BREAK CASE AP_LOWLAND_PUG sAnim.strIdleDict = "creatures@pug@amb@peyote@enter" BREAK CASE AP_LOWLAND_RABBIT sAnim.strIdleDict = "creatures@rabbit@amb@peyote@enter" BREAK CASE AP_LOWLAND_RETRIEVER sAnim.strIdleDict = "creatures@retriever@amb@peyote@enter" BREAK CASE AP_LOWLAND_ROTTWEILER sAnim.strIdleDict = "creatures@rottweiler@amb@peyote@enter" BREAK CASE AP_LOWLAND_SHEPHERD sAnim.strIdleDict = "creatures@rottweiler@amb@peyote@enter" BREAK CASE AP_LOWLAND_WESTY sAnim.strIdleDict = "creatures@pug@amb@peyote@enter" BREAK CASE AP_HIGHLAND_CHICKENHAWK sAnim.strIdleDict = "" BREAK CASE AP_HIGHLAND_CORMORANT sAnim.strIdleDict = "" BREAK CASE AP_HIGHLAND_CROW sAnim.strIdleDict = "" BREAK CASE AP_HIGHLAND_HEN sAnim.strIdleDict = "creatures@hen@amb@peyote@enter" BREAK CASE AP_HIGHLAND_PIGEON sAnim.strIdleDict = "" BREAK CASE AP_HIGHLAND_SEAGULL sAnim.strIdleDict = "" BREAK CASE AP_UNDERWATER_DOLPHIN sAnim.strIdleDict = "" BREAK CASE AP_UNDERWATER_FISH sAnim.strIdleDict = "" BREAK CASE AP_UNDERWATER_KILLERWHALE sAnim.strIdleDict = "" BREAK CASE AP_UNDERWATER_SHARKHAMMER sAnim.strIdleDict = "" BREAK CASE AP_UNDERWATER_SHARKTIGER sAnim.strIdleDict = "" BREAK CASE AP_UNDERWATER_STINGRAY sAnim.strIdleDict = "" BREAK CASE AP_SECRET_SASQUATCH sAnim.strIdleDict = "" BREAK DEFAULT SCRIPT_ASSERT("Get_Pickup_Type_Animal_Idle_Anim_Data: Invalid animal enum passed.") BREAK ENDSWITCH IF NOT IS_STRING_NULL_OR_EMPTY(sAnim.strIdleDict) sAnim.strIdleAnim = "enter" ENDIF CPRINTLN(DEBUG_ANIMAL_MODE, "Selected Animal_Idle_Anim animation data. Dict:", sAnim.strIdleDict, " Anim:", sAnim.strIdleAnim, ".") ENDPROC PROC Get_Pickup_Type_Lead_Out_Anim_Data(AnimalAnimationData &sData, AnimalPickup paramAnimal) sData.strAnim = "wakeup" SWITCH paramAnimal CASE AP_LOWLAND_BOAR sData.strDict = "random@peyote@deer" BREAK CASE AP_LOWLAND_CAT sData.strDict = "random@peyote@cat" BREAK CASE AP_LOWLAND_COW sData.strDict = "random@peyote@deer" BREAK CASE AP_LOWLAND_COYOTE sData.strDict = "random@peyote@dog" BREAK CASE AP_LOWLAND_DEER sData.strDict = "random@peyote@deer" BREAK CASE AP_LOWLAND_HUSKY sData.strDict = "random@peyote@dog" BREAK CASE AP_LOWLAND_MTLION sData.strDict = "random@peyote@cat" BREAK CASE AP_LOWLAND_PIG sData.strDict = "random@peyote@deer" BREAK CASE AP_LOWLAND_POODLE sData.strDict = "random@peyote@dog" BREAK CASE AP_LOWLAND_PUG sData.strDict = "random@peyote@dog" BREAK CASE AP_LOWLAND_RABBIT sData.strDict = "random@peyote@rabbit" BREAK CASE AP_LOWLAND_RETRIEVER sData.strDict = "random@peyote@dog" BREAK CASE AP_LOWLAND_ROTTWEILER sData.strDict = "random@peyote@dog" BREAK CASE AP_LOWLAND_SHEPHERD sData.strDict = "random@peyote@dog" BREAK CASE AP_LOWLAND_WESTY sData.strDict = "random@peyote@dog" BREAK CASE AP_HIGHLAND_CHICKENHAWK sData.strDict = "random@peyote@bird" BREAK CASE AP_HIGHLAND_CORMORANT sData.strDict = "random@peyote@bird" BREAK CASE AP_HIGHLAND_CROW sData.strDict = "random@peyote@bird" BREAK CASE AP_HIGHLAND_HEN sData.strDict = "random@peyote@chicken" BREAK CASE AP_HIGHLAND_PIGEON sData.strDict = "random@peyote@bird" BREAK CASE AP_HIGHLAND_SEAGULL sData.strDict = "random@peyote@bird" BREAK CASE AP_UNDERWATER_DOLPHIN sData.strDict = "random@peyote@fish" BREAK CASE AP_UNDERWATER_FISH sData.strDict = "random@peyote@fish" BREAK CASE AP_UNDERWATER_KILLERWHALE sData.strDict = "random@peyote@fish" BREAK CASE AP_UNDERWATER_SHARKHAMMER sData.strDict = "random@peyote@fish" BREAK CASE AP_UNDERWATER_SHARKTIGER sData.strDict = "random@peyote@fish" BREAK CASE AP_UNDERWATER_STINGRAY sData.strDict = "random@peyote@fish" BREAK CASE AP_SECRET_SASQUATCH sData.strDict = "random@peyote@generic" BREAK DEFAULT SCRIPT_ASSERT("Get_Pickup_Type_Lead_Out_Anim_Data: Invalid animal enum passed.") BREAK ENDSWITCH IF eTriggeredType = APT_UNDERWATER sAnim.strIdleDict = "SWIMMING@BASE" sAnim.strIdleAnim = "DIVE_IDLE" ELSE sAnim.strIdleAnim = "idle_intro" SWITCH eLastPlayerCharacter CASE CHAR_MICHAEL sAnim.strIdleDict = "move_p_m_zero" BREAK CASE CHAR_FRANKLIN sAnim.strIdleDict = "move_p_m_one" BREAK CASE CHAR_TREVOR sAnim.strIdleDict = "move_p_m_two" BREAK DEFAULT SCRIPT_ASSERT("Unknown Character") BREAK ENDSWITCH ENDIF CPRINTLN(DEBUG_ANIMAL_MODE, "Selected lead-out animation data. Dict:", sData.strDict, " Anim:", sData.strAnim, ".") CPRINTLN(DEBUG_ANIMAL_MODE, "Selected idle-out animation data. Dict:", sData.strIdleDict, " Anim:", sData.strIdleAnim, ".") ENDPROC #IF IS_DEBUG_BUILD BOOL bDebugPeyoteKillController = FALSE BOOL bDebugDisplayTriggerZones = FALSE BOOL bDebugDisplayLeaveAreaZones = FALSE BOOL bDebugDisplayPositionDebug = FALSE BOOL bDebugWarpToPickup[APT_COUNT] BOOL bDebugGrabMousePointerCoords[APT_COUNT][ANIMAL_PICKUP_COUNT_MAX] BOOL bDebugRefreshPickupPosition[APT_COUNT][ANIMAL_PICKUP_COUNT_MAX] BOOL bDebugOutputCoords[APT_COUNT][ANIMAL_PICKUP_COUNT_MAX] BOOL bDebugForceWrongTypeSpawns BOOL bDebugIgnoreSecretConditions BOOL bDebugSetSecretConditions INT iDebugWarpSelection[APT_COUNT] BOOL bDebugLinesAndSpheresOn = FALSE INT iBitsetDebugBlipsCreated BLIP_INDEX blipDebug[APT_COUNT][ANIMAL_PICKUP_COUNT_MAX] TEXT_WIDGET_ID twSecretConditionState[5] FUNC STRING Debug_Get_Pickup_Type_String_From_Enum(AnimalPickupType paramType) SWITCH paramType CASE APT_LOWLAND RETURN "Low" BREAK CASE APT_HIGHLAND RETURN "High" BREAK CASE APT_UNDERWATER RETURN "Water" BREAK CASE APT_SECRET RETURN "Secret" BREAK ENDSWITCH ASSERTLN("Debug_Get_Pickup_Type_String_From_Enum: Invalid enum passed. ", paramType) RETURN "INVALID!" ENDFUNC FUNC STRING Debug_Get_Animal_String_From_Pickup_Enum(AnimalPickup paramPickup) SWITCH paramPickup CASE AP_LOWLAND_BOAR RETURN "(0) BOAR" BREAK CASE AP_LOWLAND_CAT RETURN "(1) CAT" BREAK CASE AP_LOWLAND_COW RETURN "(2) COW" BREAK CASE AP_LOWLAND_COYOTE RETURN "(3) COYOTE" BREAK CASE AP_LOWLAND_DEER RETURN "(4) DEER" BREAK CASE AP_LOWLAND_HUSKY RETURN "(5) HUSKY" BREAK CASE AP_LOWLAND_MTLION RETURN "(6) MTLION" BREAK CASE AP_LOWLAND_PIG RETURN "(7) PIG" BREAK CASE AP_LOWLAND_POODLE RETURN "(8) POODLE" BREAK CASE AP_LOWLAND_PUG RETURN "(9) PUG" BREAK CASE AP_LOWLAND_RABBIT RETURN "(10) RABBIT" BREAK CASE AP_LOWLAND_RETRIEVER RETURN "(11) RETRIEVER" BREAK CASE AP_LOWLAND_ROTTWEILER RETURN "(12) ROTTWEILER" BREAK CASE AP_LOWLAND_SHEPHERD RETURN "(13) SHEPHERD" BREAK CASE AP_LOWLAND_WESTY RETURN "(14) WESTY" BREAK CASE AP_HIGHLAND_CHICKENHAWK RETURN "(15) CHICKENHAWK" BREAK CASE AP_HIGHLAND_CORMORANT RETURN "(16) CORMORANT" BREAK CASE AP_HIGHLAND_CROW RETURN "(17) CROW" BREAK CASE AP_HIGHLAND_HEN RETURN "(18) HEN" BREAK CASE AP_HIGHLAND_PIGEON RETURN "(19) PIGEON" BREAK CASE AP_HIGHLAND_SEAGULL RETURN "(20) SEAGULL" BREAK CASE AP_UNDERWATER_DOLPHIN RETURN "(21) DOLPHIN" BREAK CASE AP_UNDERWATER_FISH RETURN "(22) FISH" BREAK CASE AP_UNDERWATER_KILLERWHALE RETURN "(23) KILLERWHALE" BREAK CASE AP_UNDERWATER_SHARKHAMMER RETURN "(24) SHARKHAMMER" BREAK CASE AP_UNDERWATER_SHARKTIGER RETURN "(25) SHARKTIGER" BREAK CASE AP_UNDERWATER_STINGRAY RETURN "(26) STINGRAY" BREAK CASE AP_SECRET_SASQUATCH RETURN "(27) SASQUATCH" BREAK CASE AP_SECRET_CHOP RETURN "(28) CHOP" BREAK CASE AP_UNDERWATER_HUMPBACKWHALE RETURN "(29) HUMPBACKWHALE" BREAK ENDSWITCH ASSERTLN("Debug_Get_Animal_String_From_Pickup_Enum: Invalid enum passed. ", paramPickup) RETURN "INVALID!" ENDFUNC PROC Debug_Display_Pickup_Labels_For_Type(AnimalPickupType paramType) INT iPickupIndex REPEAT Get_Number_Of_Animal_Pickups_Of_Type(paramType) iPickupIndex TEXT_LABEL_31 tDebugLabel = Debug_Get_Pickup_Type_String_From_Enum(paramType) tDebugLabel += "[" tDebugLabel += iPickupIndex tDebugLabel += "]" IF NOT IS_BIT_SET(iBitsetPickupLeaveArea[paramType], iPickupIndex) IF IS_BIT_SET(g_savedGlobals.sAmbient.iPeyotePickupOfTypeFound[paramType], iPickupIndex) AND NOT g_savedGlobals.sAmbient.bPeyoteProgressionComplete tDebugLabel += " Collected" DRAW_DEBUG_TEXT(tDebugLabel, vPickupPos[paramType][iPickupIndex], 0, 255, 0, 150) ELSE DRAW_DEBUG_TEXT(tDebugLabel, vPickupPos[paramType][iPickupIndex]) ENDIF ELSE tDebugLabel += " Leave Area" DRAW_DEBUG_TEXT(tDebugLabel, vPickupPos[paramType][iPickupIndex], 255, 0, 0, 255) ENDIF ENDREPEAT ENDPROC PROC Debug_Display_Leave_Area_Zones() INT iTypeIndex REPEAT APT_COUNT iTypeIndex INT iPickupIndex REPEAT Get_Number_Of_Animal_Pickups_Of_Type(INT_TO_ENUM(AnimalPickupType, iTypeIndex)) iPickupIndex IF IS_BIT_SET(iBitsetPickupLeaveArea[iTypeIndex], iPickupIndex) DRAW_DEBUG_SPHERE(vPickupPos[iTypeIndex][iPickupIndex], fPickupSpawnDist, 255, 0, 0, 75) ENDIF ENDREPEAT ENDREPEAT ENDPROC PROC Debug_Display_Positioning_Debug() INT iTypeIndex REPEAT APT_COUNT iTypeIndex INT iPickupIndex REPEAT Get_Number_Of_Animal_Pickups_Of_Type(INT_TO_ENUM(AnimalPickupType, iTypeIndex)) iPickupIndex IF IS_BIT_SET(iBitsetPickupSpawned[iTypeIndex], iPickupIndex) VECTOR vDirection = GET_HEADING_AS_VECTOR(vPickupRot[iTypeIndex][iPickupIndex].z) vDirection = NORMALISE_VECTOR(vDirection)*-0.6 vDirection.z += 0.15 DRAW_DEBUG_LINE(vPickupPos[iTypeIndex][iPickupIndex],vPickupPos[iTypeIndex][iPickupIndex] + vDirection, 255, 0, 0, 255) DRAW_DEBUG_SPHERE(vPickupPos[iTypeIndex][iPickupIndex] + vDirection, 0.05, 255, 0, 0, 255) ENDIF ENDREPEAT ENDREPEAT ENDPROC FUNC INT Debug_Get_Blip_Colour_For_Type(AnimalPickupType paramType, BOOL paramCollected) IF NOT paramCollected SWITCH paramType CASE APT_LOWLAND RETURN BLIP_COLOUR_GREEN BREAK CASE APT_HIGHLAND RETURN BLIP_COLOUR_YELLOW BREAK CASE APT_UNDERWATER RETURN BLIP_COLOUR_BLUELIGHT BREAK CASE APT_SECRET RETURN BLIP_COLOUR_PURPLE BREAK ENDSWITCH ELSE SWITCH paramType CASE APT_LOWLAND RETURN BLIP_COLOUR_GREENDARK BREAK CASE APT_HIGHLAND RETURN BLIP_COLOUR_YELLOWDARK BREAK CASE APT_UNDERWATER RETURN BLIP_COLOUR_BLUEDARK BREAK CASE APT_SECRET RETURN BLIP_COLOUR_PURPLEDARK BREAK ENDSWITCH ENDIF SCRIPT_ASSERT("Debug_Get_Blip_Colour_For_Type: Invalid enum passed.") RETURN BLIP_COLOUR_DEFAULT ENDFUNC PROC Debug_Create_Pickup_Blips_For_Type(AnimalPickupType paramType) INT iPickupIndex INT iDebugColour = Debug_Get_Blip_Colour_For_Type(paramType, FALSE) INT iDebugColourCollected = Debug_Get_Blip_Colour_For_Type(paramType, TRUE) STRING strDebugLabel = Debug_Get_Pickup_Type_String_From_Enum(paramType) REPEAT Get_Number_Of_Animal_Pickups_Of_Type(paramType) iPickupIndex IF NOT DOES_BLIP_EXIST(blipDebug[paramType][iPickupIndex]) blipDebug[paramType][iPickupIndex] = CREATE_BLIP_FOR_COORD(vPickupPos[paramType][iPickupIndex]) TEXT_LABEL_31 tlDebugName = strDebugLabel tlDebugName += "[" tlDebugName += iPickupIndex tlDebugName += "]" IF IS_BIT_SET(g_savedGlobals.sAmbient.iPeyotePickupOfTypeFound[paramType], iPickupIndex) AND NOT g_savedGlobals.sAmbient.bPeyoteProgressionComplete SET_BLIP_COLOUR(blipDebug[paramType][iPickupIndex], iDebugColourCollected) SET_BLIP_SCALE(blipDebug[paramType][iPickupIndex], 0.4) tlDebugName += " X" ELSE SET_BLIP_COLOUR(blipDebug[paramType][iPickupIndex], iDebugColour) SET_BLIP_SCALE(blipDebug[paramType][iPickupIndex], 0.7) ENDIF SET_BLIP_NAME_FROM_ASCII(blipDebug[paramType][iPickupIndex], tlDebugName) ENDIF ENDREPEAT DISPLAY_PLAYER_NAME_TAGS_ON_BLIPS(TRUE) SET_BIT(iBitsetDebugBlipsCreated, ENUM_TO_INT(paramType)) ENDPROC PROC Debug_Destroy_Pickup_Blips_For_Type(AnimalPickupType paramType) INT iPickupIndex REPEAT Get_Number_Of_Animal_Pickups_Of_Type(paramType) iPickupIndex IF DOES_BLIP_EXIST(blipDebug[paramType][iPickupIndex]) REMOVE_BLIP(blipDebug[paramType][iPickupIndex]) ENDIF ENDREPEAT DISPLAY_PLAYER_NAME_TAGS_ON_BLIPS(FALSE) CLEAR_BIT(iBitsetDebugBlipsCreated, ENUM_TO_INT(paramType)) ENDPROC PROC Debug_Refresh_Pickup_Blips() INT iTypeIndex REPEAT APT_COUNT iTypeIndex IF IS_BIT_SET(iBitsetDebugBlipsCreated, iTypeIndex) Debug_Destroy_Pickup_Blips_For_Type(INT_TO_ENUM(AnimalPickupType, iTypeIndex)) Debug_Create_Pickup_Blips_For_Type(INT_TO_ENUM(AnimalPickupType, iTypeIndex)) ENDIF ENDREPEAT ENDPROC PROC Debug_Create_Widget() CPRINTLN(DEBUG_ANIMAL_MODE, "Creating animal controller widget.") START_WIDGET_GROUP("Player Animal Mode") ADD_WIDGET_BOOL("Kill controller for preview", bDebugPeyoteKillController) ADD_WIDGET_STRING("") ADD_WIDGET_BOOL("Peyote progression complete", g_savedGlobals.sAmbient.bPeyoteProgressionComplete) ADD_WIDGET_BOOL("Display trigger zones", bDebugDisplayTriggerZones) ADD_WIDGET_BOOL("Display leave area zones", bDebugDisplayLeaveAreaZones) ADD_WIDGET_BOOL("Display positioning debug", bDebugDisplayPositionDebug) INT iTypeIndex REPEAT APT_COUNT iTypeIndex AnimalPickupType ePickupType = INT_TO_ENUM(AnimalPickupType, iTypeIndex) STRING strTypeName = Debug_Get_Pickup_Type_String_From_Enum(ePickupType) TEXT_LABEL_31 tlDebug tlDebug = strTypeName tlDebug += " Pickups" START_WIDGET_GROUP(tlDebug) tlDebug = "Label " tlDebug += strTypeName tlDebug += " pickups" ADD_WIDGET_BOOL(tlDebug, g_bDebugPeyotePickupLabels[iTypeIndex]) tlDebug = "Blip " tlDebug += strTypeName tlDebug += " pickups" ADD_WIDGET_BOOL(tlDebug, g_bDebugPeyotePickupBlips[iTypeIndex]) INT iIndex START_NEW_WIDGET_COMBO() REPEAT AP_COUNT iIndex ADD_TO_WIDGET_COMBO(Debug_Get_Animal_String_From_Pickup_Enum(INT_TO_ENUM(AnimalPickup, iIndex))) ENDREPEAT tlDebug = strTypeName tlDebug += " next animal" STOP_WIDGET_COMBO(tlDebug, iNextPickupAnimal[iTypeIndex]) START_NEW_WIDGET_COMBO() REPEAT Get_Number_Of_Animal_Pickups_Of_Type(ePickupType) iIndex tlDebug = strTypeName tlDebug += "[" tlDebug += iIndex tlDebug += "]" ADD_TO_WIDGET_COMBO(tlDebug) ENDREPEAT tlDebug = strTypeName tlDebug += " warp selection" STOP_WIDGET_COMBO(tlDebug, iDebugWarpSelection[iTypeIndex]) tlDebug = "Warp to " tlDebug += strTypeName tlDebug += " pickup" ADD_WIDGET_BOOL(tlDebug, bDebugWarpToPickup[iTypeIndex]) ADD_BIT_FIELD_WIDGET("Pickups found bitset", g_savedGlobals.sAmbient.iPeyotePickupOfTypeFound[iTypeIndex]) tlDebug = strTypeName tlDebug += " positions" START_WIDGET_GROUP(tlDebug) REPEAT Get_Number_Of_Animal_Pickups_Of_Type(ePickupType) iIndex tlDebug = strTypeName tlDebug += "[" tlDebug += iIndex tlDebug += "]" START_WIDGET_GROUP(tlDebug) ADD_WIDGET_FLOAT_SLIDER("Pos X", vPickupPos[iTypeIndex][iIndex].x, -10000, 10000, 0.005) ADD_WIDGET_FLOAT_SLIDER("Pos Y", vPickupPos[iTypeIndex][iIndex].y, -10000, 10000, 0.005) ADD_WIDGET_FLOAT_SLIDER("Pos Z", vPickupPos[iTypeIndex][iIndex].z, -10000, 10000, 0.005) ADD_WIDGET_FLOAT_SLIDER("Rot X", vPickupRot[iTypeIndex][iIndex].x, -360, 360, 0.005) ADD_WIDGET_FLOAT_SLIDER("Rot Y", vPickupRot[iTypeIndex][iIndex].y, -360, 360, 0.005) ADD_WIDGET_FLOAT_SLIDER("Rot Z", vPickupRot[iTypeIndex][iIndex].z, -360, 360, 0.005) ADD_WIDGET_BOOL("Grab mouse coords", bDebugGrabMousePointerCoords[iTypeIndex][iIndex]) ADD_WIDGET_BOOL("Refresh pickup", bDebugRefreshPickupPosition[iTypeIndex][iIndex]) ADD_WIDGET_BOOL("Output positon data", bDebugOutputCoords[iTypeIndex][iIndex]) STOP_WIDGET_GROUP() ENDREPEAT STOP_WIDGET_GROUP() //Highland specific. IF ePickupType = APT_HIGHLAND ADD_WIDGET_BOOL("Force mistmatched highland spawns", bDebugForceWrongTypeSpawns) ENDIF //Secret pickup specific. IF ePickupType = APT_SECRET ADD_WIDGET_BOOL("Ignore Secret Conditions", bDebugIgnoreSecretConditions) ADD_WIDGET_BOOL("Set Secret Conditions", bDebugSetSecretConditions) ADD_WIDGET_STRING("Secret Conditions State") twSecretConditionState[0] = ADD_TEXT_WIDGET("All pickups found") twSecretConditionState[1] = ADD_TEXT_WIDGET("Time 5:30 -> 8:00") twSecretConditionState[2] = ADD_TEXT_WIDGET("Weather is foggy or xmas") twSecretConditionState[3] = ADD_TEXT_WIDGET("TheLastOne RCM done") twSecretConditionState[4] = ADD_TEXT_WIDGET("Weekday pickup active") ENDIF STOP_WIDGET_GROUP() ENDREPEAT ADD_WIDGET_STRING("") ADD_BIT_FIELD_WIDGET("Animals seen", g_savedGlobals.sAmbient.iPeyoteAnimalSeen) STOP_WIDGET_GROUP() ENDPROC PROC Debug_Update_Widget() //Check for requests to toggle debug drawing. IF g_bDebugPeyotePickupLabels[APT_LOWLAND] OR g_bDebugPeyotePickupLabels[APT_HIGHLAND] OR g_bDebugPeyotePickupLabels[APT_UNDERWATER] OR g_bDebugPeyotePickupLabels[APT_SECRET] OR bDebugDisplayLeaveAreaZones OR bDebugDisplayTriggerZones OR bDebugDisplayPositionDebug IF NOT bDebugLinesAndSpheresOn SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(TRUE) bDebugLinesAndSpheresOn = TRUE ENDIF ELIF bDebugLinesAndSpheresOn SET_DEBUG_LINES_AND_SPHERES_DRAWING_ACTIVE(FALSE) bDebugLinesAndSpheresOn = FALSE ENDIF IF bDebugDisplayLeaveAreaZones Debug_Display_Leave_Area_Zones() ENDIF IF bDebugDisplayPositionDebug Debug_Display_Positioning_Debug() ENDIF INT iTypeIndex REPEAT APT_COUNT iTypeIndex AnimalPickupType ePickupType = INT_TO_ENUM(AnimalPickupType, iTypeIndex) //Check for label display requests. IF g_bDebugPeyotePickupLabels[iTypeIndex] Debug_Display_Pickup_Labels_For_Type(ePickupType) ENDIF //Check for blip mode toggling. IF g_bDebugPeyotePickupBlips[iTypeIndex] IF NOT IS_BIT_SET(iBitsetDebugBlipsCreated, iTypeIndex) Debug_Create_Pickup_Blips_For_Type(ePickupType) ENDIF ELSE IF IS_BIT_SET(iBitsetDebugBlipsCreated, iTypeIndex) Debug_Destroy_Pickup_Blips_For_Type(ePickupType) ENDIF ENDIF //Check for warp requests. VECTOR vWarpPosition IF bDebugWarpToPickup[iTypeIndex] IF iDebugWarpSelection[iTypeIndex] >= 0 AND iDebugWarpSelection[iTypeIndex] < Get_Number_Of_Animal_Pickups_Of_Type(ePickupType) vWarpPosition = vPickupPos[iTypeIndex][iDebugWarpSelection[iTypeIndex]] vWarpPosition.x += 1.5 vWarpPosition.y += 1.5 vWarpPosition.z += 1.75 DO_PLAYER_MAP_WARP_WITH_LOAD(vWarpPosition) ELSE SCRIPT_ASSERT("No valid pickup selected in Player Animal Mode widget.") ENDIF bDebugWarpToPickup[iTypeIndex] = FALSE ENDIF //Check for debug menu warp requests. IF g_iDebugPeyoteIndex != -1 //For secret pickups jump to the right day of the week and //force all other conditions to be setup to allow the pickup to spawn. IF g_eDebugPeyoteType = APT_SECRET INT iDayOfWeek = ENUM_TO_INT(GET_CLOCK_DAY_OF_WEEK()) CDEBUG3LN(DEBUG_ANIMAL_MODE, "Day of week is ", iDayOfWeek, ". Target is ", g_iDebugPeyoteIndex, ".") INT iDayOfMonth = GET_CLOCK_DAY_OF_MONTH() INT iDaysInMonth = GET_NUMBER_OF_DAYS_IN_MONTH(GET_CLOCK_MONTH(), GET_CLOCK_YEAR()) CDEBUG3LN(DEBUG_ANIMAL_MODE, "Day of month is ", iDayOfMonth, ". Days in month is ", iDaysInMonth, ".") INT iPositiveDifference = g_iDebugPeyoteIndex - iDayOfWeek INT iNegativeDifference = 7 - iPositiveDifference CDEBUG3LN(DEBUG_ANIMAL_MODE, "Positive diff: ", iPositiveDifference, " Negative diff: ", iNegativeDifference) CDEBUG3LN(DEBUG_ANIMAL_MODE, "Day of month + pos diff = ", iDayOfMonth + iPositiveDifference) CDEBUG3LN(DEBUG_ANIMAL_MODE, "Day of month + neg diff = ", iDayOfMonth - iNegativeDifference) //Extra check for month wrap-around: if we'd need to go back one month IF (iDayOfMonth + iPositiveDifference) < 0 iPositiveDifference = (iPositiveDifference + 7) % 7 CDEBUG3LN(DEBUG_ANIMAL_MODE, "Pos difference is still negative, wrapping around to ",iDayOfMonth + iPositiveDifference) ENDIF IF (iDayOfMonth + iPositiveDifference) < iDaysInMonth CDEBUG3LN(DEBUG_ANIMAL_MODE, "Going with pos difference.") SET_CLOCK_DATE(iDayOfMonth + iPositiveDifference, GET_CLOCK_MONTH(), GET_CLOCK_YEAR()) ELSE CDEBUG3LN(DEBUG_ANIMAL_MODE, "Going with neg difference.") SET_CLOCK_DATE(iDayOfMonth - iNegativeDifference, GET_CLOCK_MONTH(), GET_CLOCK_YEAR()) ENDIF bDebugSetSecretConditions = TRUE ENDIF vWarpPosition = vPickupPos[g_eDebugPeyoteType][g_iDebugPeyoteIndex] vWarpPosition.x += 1.5 vWarpPosition.y += 1.5 vWarpPosition.z += 1.75 DO_PLAYER_MAP_WARP_WITH_LOAD(vWarpPosition) g_iDebugPeyoteIndex = -1 g_eDebugPeyoteType = APT_INVALID ENDIF INT iPickupIndex REPEAT Get_Number_Of_Animal_Pickups_Of_Type(ePickupType) iPickupIndex //Check for coord grab requests. IF bDebugGrabMousePointerCoords[iTypeIndex][iPickupIndex] vPickupPos[iTypeIndex][iPickupIndex] = GET_SCRIPT_MOUSE_POINTER_IN_WORLD_COORDS() //Despawn pickup so it can respawn. IF DOES_ENTITY_EXIST(oPickup[iTypeIndex][iPickupIndex]) DELETE_OBJECT(oPickup[iTypeIndex][iPickupIndex]) ENDIF CLEAR_BIT(iBitsetPickupSpawned[iTypeIndex], iPickupIndex) iBitsetPickupLeaveArea[iTypeIndex] = 0 bDebugGrabMousePointerCoords[iTypeIndex][iPickupIndex] = FALSE ENDIF IF bDebugRefreshPickupPosition[iTypeIndex][iPickupIndex] //Despawn pickup so it can respawn. IF DOES_ENTITY_EXIST(oPickup[iTypeIndex][iPickupIndex]) DELETE_OBJECT(oPickup[iTypeIndex][iPickupIndex]) ENDIF CLEAR_BIT(iBitsetPickupSpawned[iTypeIndex], iPickupIndex) iBitsetPickupLeaveArea[iTypeIndex] = 0 bDebugRefreshPickupPosition[iTypeIndex][iPickupIndex] = FALSE ENDIF //Check for coord output requests. IF bDebugOutputCoords[iTypeIndex][iPickupIndex] //Build string. TEXT_LABEL_63 tlOutput = Debug_Get_Pickup_Type_String_From_Enum(ePickupType) tlOutput += "[" tlOutput += iPickupIndex tlOutput += "] Pos = " tlOutput += VECTOR_TO_STRING(vPickupPos[iTypeIndex][iPickupIndex]) //Output position to console. CPRINTLN(DEBUG_ANIMAL_MODE, tlOutput) //Output to text file. OPEN_DEBUG_FILE() SAVE_STRING_TO_DEBUG_FILE(tlOutput) SAVE_NEWLINE_TO_DEBUG_FILE() CLOSE_DEBUG_FILE() tlOutput = Debug_Get_Pickup_Type_String_From_Enum(ePickupType) tlOutput += "[" tlOutput += iPickupIndex tlOutput += "] Rot = " tlOutput += VECTOR_TO_STRING(vPickupRot[iTypeIndex][iPickupIndex]) //Output rotation to console. CPRINTLN(DEBUG_ANIMAL_MODE, tlOutput) //Output to text file. OPEN_DEBUG_FILE() SAVE_STRING_TO_DEBUG_FILE(tlOutput) SAVE_NEWLINE_TO_DEBUG_FILE() CLOSE_DEBUG_FILE() bDebugOutputCoords[iTypeIndex][iPickupIndex] = FALSE ENDIF ENDREPEAT ENDREPEAT IF g_bDebugPeyoteResetProgression REPEAT APT_COUNT iTypeIndex g_savedGlobals.sAmbient.iPeyotePickupOfTypeFound[iTypeIndex] = 0 iBitsetPickupLeaveArea[iTypeIndex] = 0 ENDREPEAT g_savedGlobals.sAmbient.iPeyoteAnimalSeen = 0 g_savedGlobals.sAmbient.bPeyoteProgressionComplete = FALSE Debug_Refresh_Pickup_Blips() g_bDebugPeyoteResetProgression = FALSE ENDIF IF g_eDebugPeyoteAnimalLowland != AP_INVALID iNextPickupAnimal[APT_LOWLAND] = ENUM_TO_INT(g_eDebugPeyoteAnimalLowland) g_eDebugPeyoteAnimalLowland = AP_INVALID ENDIF IF g_eDebugPeyoteAnimalHighland != AP_INVALID iNextPickupAnimal[APT_HIGHLAND] = ENUM_TO_INT(g_eDebugPeyoteAnimalHighland) g_eDebugPeyoteAnimalHighland = AP_INVALID ENDIF IF g_eDebugPeyoteAnimalUnderwater != AP_INVALID iNextPickupAnimal[APT_UNDERWATER] = ENUM_TO_INT(g_eDebugPeyoteAnimalUnderwater) g_eDebugPeyoteAnimalUnderwater = AP_INVALID ENDIF IF bDebugSetSecretConditions SET_CLOCK_TIME(5, 30, 0) SET_WEATHER_TYPE_NOW("FOGGY") Set_Random_Character_Mission_Complete(RC_THELASTONE, TRUE) g_savedGlobals.sAmbient.bPeyoteProgressionComplete = TRUE iBitsetPickupLeaveArea[APT_SECRET] = 0 bDebugSetSecretConditions = FALSE ENDIF //Update secret pickup states. (Refresh every 120 frames) IF (GET_FRAME_COUNT() % 120) = 0 IF bDebugIgnoreSecretConditions SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[0], "PASS - Debug override active") SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[1], "PASS - Debug override active") SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[2], "PASS - Debug override active") SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[3], "PASS - Debug override active") SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[4], "PASS - Debug override active") iBitsetPickupLeaveArea[APT_SECRET] = 0 ELSE IF g_savedGlobals.sAmbient.bPeyoteProgressionComplete SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[0], "PASS - All pickups found") ELSE SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[0], "FAIL - Not all pickups found") ENDIF TIMEOFDAY eStartTime = GET_CURRENT_TIMEOFDAY() TIMEOFDAY eEndTime = eStartTime SET_TIMEOFDAY_HOUR(eStartTime, 5) SET_TIMEOFDAY_MINUTE(eStartTime, 30) SET_TIMEOFDAY_SECOND(eStartTime, 0) SET_TIMEOFDAY_HOUR(eEndTime, 8) SET_TIMEOFDAY_MINUTE(eEndTime, 0) SET_TIMEOFDAY_SECOND(eEndTime, 0) IF IS_NOW_AFTER_TIMEOFDAY(eStartTime) AND NOT IS_NOW_AFTER_TIMEOFDAY(eEndTime) SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[1], "PASS - Time between 5:30 and 8:00") ELSE SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[1], "FAIL - Time not between 5:30 and 8:00") ENDIF INT iPrevWeather, iNextWeather FLOAT fInterp GET_CURR_WEATHER_STATE(iPrevWeather, iNextWeather, fInterp) IF (iPrevWeather = HASH("FOGGY") AND fInterp <= 0.5) OR (iNextWeather = HASH("FOGGY") AND fInterp >= 0.5) OR (iPrevWeather = HASH("XMAS") AND fInterp <= 0.5) OR (iNextWeather = HASH("XMAS") AND fInterp >= 0.5) SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[2], "PASS - Weather is foggy or XMAS") ELSE SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[2], "FAIL - Weather not foggy or XMAS") ENDIF IF IS_THIS_RANDOM_CHARACTER_MISSION_COMPLETED(RC_THELASTONE) SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[3], "PASS - RC_THELASTONE done.") ELSE SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[3], "FAIL - RC_THELASTONE not done.") ENDIF SWITCH GET_CLOCK_DAY_OF_WEEK() CASE SUNDAY SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[4], "Day is Sun - Secret[0] active") BREAK CASE MONDAY SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[4], "Day is Mon - Secret[1] active") BREAK CASE TUESDAY SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[4], "Day is Tue - Secret[2] active") BREAK CASE WEDNESDAY SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[4], "Day is Wed - Secret[3] active") BREAK CASE THURSDAY SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[4], "Day is Thur - Secret[4] active") BREAK CASE FRIDAY SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[4], "Day is Fri - Secret[5] active") BREAK CASE SATURDAY SET_CONTENTS_OF_TEXT_WIDGET(twSecretConditionState[4], "Day is Sat - Secret[6] active") BREAK ENDSWITCH ENDIF ENDIF ENDPROC #ENDIF PROC Get_And_Update_Peyote_Conversations(AnimalPickup paramAnimalEnum) INT paramAnimal = ENUM_TO_INT(paramAnimalEnum) STRING firstChoice = "" STRING secondChoice = "" SWITCH eLastPlayerCharacter CASE CHAR_MICHAEL SWITCH paramAnimalEnum CASE AP_LOWLAND_BOAR firstChoice = "ANIML_MBOAR" secondChoice = "ANIML_MBOAR2" BREAK CASE AP_LOWLAND_CAT firstChoice = "ANIML_MCAT" secondChoice = "ANIML_MCAT2" BREAK CASE AP_LOWLAND_COW firstChoice = "ANIML_MCOW" secondChoice = "" BREAK CASE AP_LOWLAND_COYOTE firstChoice = "ANIML_MCYT" secondChoice = "ANIML_MCYT2" BREAK CASE AP_LOWLAND_DEER firstChoice = "ANIML_MDEER" secondChoice = "ANIML_MDEER2" BREAK CASE AP_LOWLAND_HUSKY firstChoice = "ANIML_MHSK" secondChoice = "ANIML_MHSK2" BREAK CASE AP_LOWLAND_MTLION firstChoice = "ANIML_MLION" secondChoice = "ANIML_MLION2" BREAK CASE AP_LOWLAND_PIG firstChoice = "ANIML_MPIG" secondChoice = "ANIML_MPIG2" BREAK CASE AP_LOWLAND_POODLE firstChoice = "ANIML_MPDL" secondChoice = "ANIML_MPDL2" BREAK CASE AP_LOWLAND_PUG firstChoice = "ANIML_MPUG" secondChoice = "ANIML_MPUG2" BREAK CASE AP_LOWLAND_RABBIT firstChoice = "ANIML_MBUN" secondChoice = "ANIML_MBUN2" BREAK CASE AP_LOWLAND_RETRIEVER firstChoice = "ANIML_MRET" secondChoice = "ANIML_MRET2" BREAK CASE AP_LOWLAND_ROTTWEILER firstChoice = "ANIML_MRTW" secondChoice = "ANIML_MRTW2" BREAK CASE AP_LOWLAND_SHEPHERD firstChoice = "ANIML_MSPD" secondChoice = "ANIML_MSPD2" BREAK CASE AP_LOWLAND_WESTY firstChoice = "ANIML_MWST" secondChoice = "ANIML_MWST2" BREAK CASE AP_HIGHLAND_CHICKENHAWK firstChoice = "ANIML_MHWK" secondChoice = "ANIML_MHWK2" BREAK CASE AP_HIGHLAND_CORMORANT firstChoice = "ANIML_MCMT" secondChoice = "ANIML_MCMT2" BREAK CASE AP_HIGHLAND_CROW firstChoice = "ANIML_MCROW" secondChoice = "ANIML_MCROW2" BREAK CASE AP_HIGHLAND_HEN firstChoice = "ANIML_MHEN" secondChoice = "ANIML_MHEN2" BREAK CASE AP_HIGHLAND_PIGEON firstChoice = "ANIML_MPGN" secondChoice = "ANIML_MPGN2" BREAK CASE AP_HIGHLAND_SEAGULL firstChoice = "ANIML_MGUL" secondChoice = "ANIML_MGUL2" BREAK CASE AP_UNDERWATER_DOLPHIN firstChoice = "ANIML_MDOL" secondChoice = "ANIML_MDOL2" BREAK CASE AP_UNDERWATER_FISH firstChoice = "ANIML_MFISH" secondChoice = "ANIML_MFISH2" BREAK CASE AP_UNDERWATER_KILLERWHALE firstChoice = "ANIML_MKILL" secondChoice = "ANIML_MKILL2" BREAK CASE AP_UNDERWATER_SHARKHAMMER firstChoice = "ANIML_MHSHK" secondChoice = "ANIML_MHSHK2" BREAK CASE AP_UNDERWATER_SHARKTIGER firstChoice = "ANIML_MTSHK" secondChoice = "ANIML_MTSHK2" BREAK CASE AP_UNDERWATER_STINGRAY firstChoice = "ANIML_MRAY" secondChoice = "ANIML_MRAY2" BREAK CASE AP_SECRET_SASQUATCH firstChoice = "ANIML_MGE" secondChoice = "" BREAK CASE AP_SECRET_CHOP firstChoice = "" secondChoice = "" BREAK ENDSWITCH BREAK CASE CHAR_FRANKLIN SWITCH paramAnimalEnum CASE AP_LOWLAND_BOAR firstChoice = "ANIML_FBOAR" secondChoice = "ANIML_FBOAR2" BREAK CASE AP_LOWLAND_CAT firstChoice = "ANIML_FCAT" secondChoice = "ANIML_FCAT2" BREAK CASE AP_LOWLAND_COW firstChoice = "ANIML_FCOW" secondChoice = "ANIML_FCOW2" BREAK CASE AP_LOWLAND_COYOTE firstChoice = "ANIML_FCYT" secondChoice = "ANIML_FCYT2" BREAK CASE AP_LOWLAND_DEER firstChoice = "ANIML_FDEER" secondChoice = "ANIML_FDEER2" BREAK CASE AP_LOWLAND_HUSKY firstChoice = "ANIML_FHSK" secondChoice = "ANIML_FHSK2" BREAK CASE AP_LOWLAND_MTLION firstChoice = "ANIML_FLION" secondChoice = "ANIML_FLION2" BREAK CASE AP_LOWLAND_PIG firstChoice = "ANIML_FPIG" secondChoice = "ANIML_FPIG2" BREAK CASE AP_LOWLAND_POODLE firstChoice = "ANIML_FPDL" secondChoice = "ANIML_FPDL2" BREAK CASE AP_LOWLAND_PUG firstChoice = "ANIML_FPUG" secondChoice = "ANIML_FPUG2" BREAK CASE AP_LOWLAND_RABBIT firstChoice = "ANIML_FBUN" secondChoice = "ANIML_FBUN2" BREAK CASE AP_LOWLAND_RETRIEVER firstChoice = "ANIML_FRET" secondChoice = "ANIML_FRET2" BREAK CASE AP_LOWLAND_ROTTWEILER firstChoice = "ANIML_FRTW" secondChoice = "ANIML_FRTW2" BREAK CASE AP_LOWLAND_SHEPHERD firstChoice = "ANIML_FSPD" secondChoice = "ANIML_FSPD2" BREAK CASE AP_LOWLAND_WESTY firstChoice = "ANIML_FWST" secondChoice = "ANIML_FWST2" BREAK CASE AP_HIGHLAND_CHICKENHAWK firstChoice = "ANIML_FHWK" secondChoice = "ANIML_FHWK2" BREAK CASE AP_HIGHLAND_CORMORANT firstChoice = "ANIML_FCMT" secondChoice = "ANIML_FCMT2" BREAK CASE AP_HIGHLAND_CROW firstChoice = "ANIML_FCROW" secondChoice = "ANIML_FCROW2" BREAK CASE AP_HIGHLAND_HEN firstChoice = "ANIML_FHEN" secondChoice = "ANIML_FHEN2" BREAK CASE AP_HIGHLAND_PIGEON firstChoice = "ANIML_FPGN" secondChoice = "ANIML_FPGN2" BREAK CASE AP_HIGHLAND_SEAGULL firstChoice = "ANIML_FGUL" secondChoice = "ANIML_FGUL2" BREAK CASE AP_UNDERWATER_DOLPHIN firstChoice = "ANIML_FDOL" secondChoice = "ANIML_FDOL2" BREAK CASE AP_UNDERWATER_FISH firstChoice = "ANIML_FFISH" secondChoice = "ANIML_FFISH2" BREAK CASE AP_UNDERWATER_KILLERWHALE firstChoice = "ANIML_FKILL" secondChoice = "" BREAK CASE AP_UNDERWATER_SHARKHAMMER firstChoice = "ANIML_FHSHK" secondChoice = "ANIML_FHSHK2" BREAK CASE AP_UNDERWATER_SHARKTIGER firstChoice = "ANIML_TSHK" secondChoice = "ANIML_TSHK2" BREAK CASE AP_UNDERWATER_STINGRAY firstChoice = "ANIML_FRAY" secondChoice = "ANIML_FRAY2" BREAK CASE AP_SECRET_SASQUATCH firstChoice = "" secondChoice = "" BREAK CASE AP_SECRET_CHOP firstChoice = "" secondChoice = "" BREAK ENDSWITCH BREAK CASE CHAR_TREVOR SWITCH paramAnimalEnum CASE AP_LOWLAND_BOAR firstChoice = "ANIML_TBOAR" secondChoice = "ANIML_TBOAR2" BREAK CASE AP_LOWLAND_CAT firstChoice = "ANIML_TCAT" secondChoice = "ANIML_TCAT2" BREAK CASE AP_LOWLAND_COW firstChoice = "ANIML_TCOW" secondChoice = "" BREAK CASE AP_LOWLAND_COYOTE firstChoice = "ANIML_TCYT" secondChoice = "ANIML_TCYT2" BREAK CASE AP_LOWLAND_DEER firstChoice = "ANIML_TDEER" secondChoice = "ANIML_TDEER2" BREAK CASE AP_LOWLAND_HUSKY firstChoice = "ANIML_THSK" secondChoice = "ANIML_THSK2" BREAK CASE AP_LOWLAND_MTLION firstChoice = "ANIML_TLION" secondChoice = "ANIML_TLION2" BREAK CASE AP_LOWLAND_PIG firstChoice = "ANIML_TPIG" secondChoice = "ANIML_TPIG2" BREAK CASE AP_LOWLAND_POODLE firstChoice = "ANIML_TPDL" secondChoice = "ANIML_TPDL2" BREAK CASE AP_LOWLAND_PUG firstChoice = "ANIML_TPUG" secondChoice = "ANIML_TPUG2" BREAK CASE AP_LOWLAND_RABBIT firstChoice = "ANIML_TBUN" secondChoice = "ANIML_TBUN2" BREAK CASE AP_LOWLAND_RETRIEVER firstChoice = "ANIML_TRET" secondChoice = "ANIML_TRET2" BREAK CASE AP_LOWLAND_ROTTWEILER firstChoice = "ANIML_TRTW1" secondChoice = "ANIML_TRTW2" BREAK CASE AP_LOWLAND_SHEPHERD firstChoice = "ANIML_TSPD" secondChoice = "ANIML_TSPD2" BREAK CASE AP_LOWLAND_WESTY firstChoice = "ANIML_TWST" secondChoice = "ANIML_TWST2" BREAK CASE AP_HIGHLAND_CHICKENHAWK firstChoice = "ANIML_THWK" secondChoice = "ANIML_THWK2" BREAK CASE AP_HIGHLAND_CORMORANT firstChoice = "ANIML_TCMT" secondChoice = "ANIML_TCMT2" BREAK CASE AP_HIGHLAND_CROW firstChoice = "ANIML_TCROW" secondChoice = "ANIML_TCROW2" BREAK CASE AP_HIGHLAND_HEN firstChoice = "ANIML_THEN" secondChoice = "ANIML_THEN2" BREAK CASE AP_HIGHLAND_PIGEON firstChoice = "ANIML_TPGN" secondChoice = "ANIML_TPGN2" BREAK CASE AP_HIGHLAND_SEAGULL firstChoice = "ANIML_TGUL" secondChoice = "ANIML_TGUL2" BREAK CASE AP_UNDERWATER_DOLPHIN firstChoice = "ANIML_TDOL" secondChoice = "ANIML_TDOL2" BREAK CASE AP_UNDERWATER_FISH firstChoice = "ANIML_TFISH" secondChoice = "ANIML_TFISH2" BREAK CASE AP_UNDERWATER_KILLERWHALE firstChoice = "ANIML_TKILL" secondChoice = "ANIML_TKILL2" BREAK CASE AP_UNDERWATER_SHARKHAMMER firstChoice = "ANIML_HSHK" secondChoice = "ANIML_HSHK2" BREAK CASE AP_UNDERWATER_SHARKTIGER firstChoice = "ANIML_TTSHK" secondChoice = "ANIML_TTSHK2" BREAK CASE AP_UNDERWATER_STINGRAY firstChoice = "ANIML_TRAY" secondChoice = "ANIML_TRAY2" BREAK CASE AP_SECRET_SASQUATCH firstChoice = "" secondChoice = "" BREAK CASE AP_SECRET_CHOP firstChoice = "" secondChoice = "" BREAK ENDSWITCH BREAK ENDSWITCH IF IS_STRING_NULL_OR_EMPTY(firstChoice) currentConversation = "" CPRINTLN(DEBUG_ANIMAL_MODE, "No dialogue found, eLastPlayerCharacter=",eLastPlayerCharacter," paramAnimalEnum=",Debug_Get_Animal_String_From_Pickup_Enum(paramAnimalEnum)) ELIF IS_STRING_NULL_OR_EMPTY(secondChoice) currentConversation = firstChoice CPRINTLN(DEBUG_ANIMAL_MODE, "Only 1 dialogue found, eLastPlayerCharacter=",eLastPlayerCharacter," paramAnimalEnum=",Debug_Get_Animal_String_From_Pickup_Enum(paramAnimalEnum), " currentConversation=",currentConversation) ELSE SWITCH eLastPlayerCharacter CASE CHAR_MICHAEL IF IS_BIT_SET(g_iBitsetPeyoteMichael,paramAnimal) currentConversation = secondChoice CLEAR_BIT(g_iBitsetPeyoteMichael,paramAnimal) CPRINTLN(DEBUG_ANIMAL_MODE, "Choosing 2nd (clear all), eLastPlayerCharacter=",eLastPlayerCharacter," paramAnimalEnum=",Debug_Get_Animal_String_From_Pickup_Enum(paramAnimalEnum), " currentConversation=",currentConversation) ELIF IS_BIT_SET(g_iBitsetPeyoteMichaelSecond,paramAnimal) currentConversation = firstChoice CLEAR_BIT(g_iBitsetPeyoteMichaelSecond,paramAnimal) CPRINTLN(DEBUG_ANIMAL_MODE, "Choosing 1st (clear all), eLastPlayerCharacter=",eLastPlayerCharacter," paramAnimalEnum=",Debug_Get_Animal_String_From_Pickup_Enum(paramAnimalEnum), " currentConversation=",currentConversation) ELSE IF GET_RANDOM_BOOL() currentConversation = firstChoice SET_BIT(g_iBitsetPeyoteMichael,paramAnimal) CPRINTLN(DEBUG_ANIMAL_MODE, "Choosing 1st (set), eLastPlayerCharacter=",eLastPlayerCharacter," paramAnimalEnum=",Debug_Get_Animal_String_From_Pickup_Enum(paramAnimalEnum), " currentConversation=",currentConversation) ELSE currentConversation = secondChoice SET_BIT(g_iBitsetPeyoteMichaelSecond,paramAnimal) CPRINTLN(DEBUG_ANIMAL_MODE, "Choosing 2nd (set), eLastPlayerCharacter=",eLastPlayerCharacter," paramAnimalEnum=",Debug_Get_Animal_String_From_Pickup_Enum(paramAnimalEnum), " currentConversation=",currentConversation) ENDIF ENDIF BREAK CASE CHAR_FRANKLIN IF IS_BIT_SET(g_iBitsetPeyoteFranklin,paramAnimal) currentConversation = secondChoice CLEAR_BIT(g_iBitsetPeyoteFranklin,paramAnimal) CPRINTLN(DEBUG_ANIMAL_MODE, "Choosing 2nd (clear all), eLastPlayerCharacter=",eLastPlayerCharacter," paramAnimalEnum=",Debug_Get_Animal_String_From_Pickup_Enum(paramAnimalEnum), " currentConversation=",currentConversation) ELIF IS_BIT_SET(g_iBitsetPeyoteFranklinSecond,paramAnimal) currentConversation = firstChoice CLEAR_BIT(g_iBitsetPeyoteFranklinSecond,paramAnimal) CPRINTLN(DEBUG_ANIMAL_MODE, "Choosing 1st (clear all), eLastPlayerCharacter=",eLastPlayerCharacter," paramAnimalEnum=",Debug_Get_Animal_String_From_Pickup_Enum(paramAnimalEnum), " currentConversation=",currentConversation) ELSE IF GET_RANDOM_BOOL() currentConversation = firstChoice SET_BIT(g_iBitsetPeyoteFranklin,paramAnimal) CPRINTLN(DEBUG_ANIMAL_MODE, "Choosing 1st (set), eLastPlayerCharacter=",eLastPlayerCharacter," paramAnimalEnum=",Debug_Get_Animal_String_From_Pickup_Enum(paramAnimalEnum), " currentConversation=",currentConversation) ELSE currentConversation = secondChoice SET_BIT(g_iBitsetPeyoteFranklinSecond,paramAnimal) CPRINTLN(DEBUG_ANIMAL_MODE, "Choosing 2nd (set), eLastPlayerCharacter=",eLastPlayerCharacter," paramAnimalEnum=",Debug_Get_Animal_String_From_Pickup_Enum(paramAnimalEnum), " currentConversation=",currentConversation) ENDIF ENDIF BREAK CASE CHAR_TREVOR IF IS_BIT_SET(g_iBitsetPeyoteTrevor,paramAnimal) currentConversation = secondChoice CLEAR_BIT(g_iBitsetPeyoteTrevor,paramAnimal) CPRINTLN(DEBUG_ANIMAL_MODE, "Choosing 2nd (clear all), eLastPlayerCharacter=",eLastPlayerCharacter," paramAnimalEnum=",Debug_Get_Animal_String_From_Pickup_Enum(paramAnimalEnum), " currentConversation=",currentConversation) ELIF IS_BIT_SET(g_iBitsetPeyoteTrevorSecond,paramAnimal) currentConversation = firstChoice CLEAR_BIT(g_iBitsetPeyoteTrevorSecond,paramAnimal) CPRINTLN(DEBUG_ANIMAL_MODE, "Choosing 1st (clear all), eLastPlayerCharacter=",eLastPlayerCharacter," paramAnimalEnum=",Debug_Get_Animal_String_From_Pickup_Enum(paramAnimalEnum), " currentConversation=",currentConversation) ELSE IF GET_RANDOM_BOOL() currentConversation = firstChoice SET_BIT(g_iBitsetPeyoteTrevor,paramAnimal) CPRINTLN(DEBUG_ANIMAL_MODE, "Choosing 1st (set), eLastPlayerCharacter=",eLastPlayerCharacter," paramAnimalEnum=",Debug_Get_Animal_String_From_Pickup_Enum(paramAnimalEnum), " currentConversation=",currentConversation) ELSE currentConversation = secondChoice SET_BIT(g_iBitsetPeyoteTrevorSecond,paramAnimal) CPRINTLN(DEBUG_ANIMAL_MODE, "Choosing 2nd (set), eLastPlayerCharacter=",eLastPlayerCharacter," paramAnimalEnum=",Debug_Get_Animal_String_From_Pickup_Enum(paramAnimalEnum), " currentConversation=",currentConversation) ENDIF ENDIF BREAK ENDSWITCH ENDIF ENDPROC PROC Manage_Dialogue_Model_Change(INT &leg) //hardcoded dialogue changes. In cases where the peyote dialogue references the animal model appearence //B* - 2073112 If rottweiler model matches chop, play chop dialogue. Using AP_COUNT for bitset IF eTriggeredAnimal = AP_LOWLAND_ROTTWEILER IF leg = 0 //matches chop model STRING firstChoice = "" STRING secondChoice = "" INT iChopBitSet = ENUM_TO_INT(AP_COUNT) SWITCH eLastPlayerCharacter CASE CHAR_MICHAEL firstChoice = "ANIML_MCHOP" secondChoice = "ANIML_MCHOP2" IF IS_BIT_SET(g_iBitsetPeyoteMichael,iChopBitSet) currentConversation = secondChoice CLEAR_BIT(g_iBitsetPeyoteMichael,iChopBitSet) ELIF IS_BIT_SET(g_iBitsetPeyoteMichaelSecond,iChopBitSet) currentConversation = firstChoice CLEAR_BIT(g_iBitsetPeyoteMichaelSecond,iChopBitSet) ELSE IF GET_RANDOM_BOOL() currentConversation = firstChoice SET_BIT(g_iBitsetPeyoteMichael,iChopBitSet) ELSE currentConversation = secondChoice SET_BIT(g_iBitsetPeyoteMichaelSecond,iChopBitSet) ENDIF ENDIF BREAK CASE CHAR_FRANKLIN firstChoice = "ANIML_FCHOP" secondChoice = "ANIML_FCHOP2" IF IS_BIT_SET(g_iBitsetPeyoteFranklin,iChopBitSet) currentConversation = secondChoice CLEAR_BIT(g_iBitsetPeyoteFranklin,iChopBitSet) ELIF IS_BIT_SET(g_iBitsetPeyoteFranklinSecond,iChopBitSet) currentConversation = firstChoice CLEAR_BIT(g_iBitsetPeyoteFranklinSecond,iChopBitSet) ELSE IF GET_RANDOM_BOOL() currentConversation = firstChoice SET_BIT(g_iBitsetPeyoteFranklin,iChopBitSet) ELSE currentConversation = secondChoice SET_BIT(g_iBitsetPeyoteFranklinSecond,iChopBitSet) ENDIF ENDIF BREAK CASE CHAR_TREVOR firstChoice = "ANIML_TCHOP" secondChoice = "ANIML_TCHOP2" IF IS_BIT_SET(g_iBitsetPeyoteTrevor,iChopBitSet) currentConversation = secondChoice CLEAR_BIT(g_iBitsetPeyoteTrevor,iChopBitSet) ELIF IS_BIT_SET(g_iBitsetPeyoteTrevorSecond,iChopBitSet) currentConversation = firstChoice CLEAR_BIT(g_iBitsetPeyoteTrevorSecond,iChopBitSet) ELSE IF GET_RANDOM_BOOL() currentConversation = firstChoice SET_BIT(g_iBitsetPeyoteTrevor,iChopBitSet) ELSE currentConversation = secondChoice SET_BIT(g_iBitsetPeyoteTrevorSecond,iChopBitSet) ENDIF ENDIF BREAK ENDSWITCH ENDIF ENDIF //B* - 2066976 If westy dialogue contains reference to colour white, change model to white. IF eTriggeredAnimal = AP_LOWLAND_WESTY IF ARE_STRINGS_EQUAL(currentConversation,"ANIML_FWST") OR ARE_STRINGS_EQUAL(currentConversation,"ANIML_FWST2") OR ARE_STRINGS_EQUAL(currentConversation,"ANIML_TWST2") leg = 0 ENDIF ENDIF ENDPROC PROC Set_Leave_Area_Flag_For_Pickup(INT paramType, INT paramIndex) CDEBUG3LN(DEBUG_ANIMAL_MODE, "Setting leave area flag for pickup ", Debug_Get_Pickup_Type_String_From_Enum(INT_TO_ENUM(AnimalPickupType, paramType)), "[", paramIndex, "].") SET_BIT(iBitsetPickupLeaveArea[paramType], paramIndex) ENDPROC PROC Clear_Leave_Area_Flag_For_Pickup(INT paramType, INT paramIndex) CDEBUG3LN(DEBUG_ANIMAL_MODE, "Clearing leave area flag for pickup ", Debug_Get_Pickup_Type_String_From_Enum(INT_TO_ENUM(AnimalPickupType, paramType)), "[", paramIndex, "].") CLEAR_BIT(iBitsetPickupLeaveArea[paramType], paramIndex) ENDPROC PROC Set_All_Pickup_Leave_Area_Flags() CPRINTLN(DEBUG_ANIMAL_MODE, "Setting all peyote pickup leave area flags.") INT iTypeIndex REPEAT APT_COUNT iTypeIndex INT iPickupIndex REPEAT Get_Number_Of_Animal_Pickups_Of_Type(INT_TO_ENUM(AnimalPickupType, iTypeIndex)) iPickupIndex Set_Leave_Area_Flag_For_Pickup(iTypeIndex, iPickupIndex) ENDREPEAT ENDREPEAT ENDPROC PROC Update_Leave_Area_Flags() IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID()) VECTOR vPlayerPosition = GET_ENTITY_COORDS(PLAYER_PED_ID()) INT iTypeIndex REPEAT APT_COUNT iTypeIndex //Check if the flag needs clearing. IF IS_BIT_SET(iBitsetPickupLeaveArea[iTypeIndex], iCurrentLeaveAreaCheck[iTypeIndex]) IF VDIST2(vPlayerPosition, vPickupPos[iTypeIndex][iCurrentLeaveAreaCheck[iTypeIndex]]) > fPickupSpawnDistSqr OR IS_SCREEN_FADED_OUT() Clear_Leave_Area_Flag_For_Pickup(iTypeIndex, iCurrentLeaveAreaCheck[iTypeIndex]) ENDIF ENDIF //Move the check index on to a new pickup for next frame. iCurrentLeaveAreaCheck[iTypeIndex]++ IF iCurrentLeaveAreaCheck[iTypeIndex] >= Get_Number_Of_Animal_Pickups_Of_Type(INT_TO_ENUM(AnimalPickupType, iTypeIndex)) iCurrentLeaveAreaCheck[iTypeIndex] = 0 ENDIF ENDREPEAT ENDIF ENDPROC FUNC AnimalPickup Get_Random_Animal_Pickup_Of_Type(AnimalPickupType paramType) CDEBUG1LN(DEBUG_ANIMAL_MODE, "Searching for random animal of type ", Debug_Get_Pickup_Type_String_From_Enum(paramType), ".") AnimalPickupType eSelectionType = paramType //Once all pickups have been collected add a 1 in 50 chance that lowland and highland spawns //swap types for added comedy value. IF paramType = APT_HIGHLAND IF (g_savedGlobals.sAmbient.bPeyoteProgressionComplete AND GET_RANDOM_INT_IN_RANGE(0, 51) = 50) #IF IS_DEBUG_BUILD OR bDebugForceWrongTypeSpawns #ENDIF CPRINTLN(DEBUG_ANIMAL_MODE, "1 in 50 chance hit! Switching type from highland to lowland.") eSelectionType = APT_LOWLAND ENDIF ENDIF //Build a list of animals up for selection. CDEBUG1LN(DEBUG_ANIMAL_MODE, "Building animal selection list...") INT iAnimalSelection[ANIMAL_PICKUP_COUNT_MAX] INT iAnimalIndex INT iSelectionCount = 0 REPEAT AP_COUNT iAnimalIndex IF iAnimalIndex != ENUM_TO_INT(AP_SECRET_CHOP) IF Get_Animal_Type(INT_TO_ENUM(AnimalPickup, iAnimalIndex)) = eSelectionType IF NOT IS_BIT_SET(g_savedGlobals.sAmbient.iPeyoteAnimalSeen, iAnimalIndex) OR g_savedGlobals.sAmbient.bPeyoteProgressionComplete CDEBUG1LN(DEBUG_ANIMAL_MODE, "Adding ", Debug_Get_Animal_String_From_Pickup_Enum(INT_TO_ENUM(AnimalPickup, iAnimalIndex)), " at index ", iSelectionCount, ".") iAnimalSelection[iSelectionCount] = iAnimalIndex iSelectionCount++ ENDIF ENDIF ENDIF ENDREPEAT CDEBUG1LN(DEBUG_ANIMAL_MODE, "...List built.") INT iRandomSelection= GET_RANDOM_INT_IN_RANGE(0, iSelectionCount) CDEBUG1LN(DEBUG_ANIMAL_MODE, "Selected index ", iRandomSelection, " which maps to ", Debug_Get_Animal_String_From_Pickup_Enum(INT_TO_ENUM(AnimalPickup, iAnimalSelection[iRandomSelection])), ".") RETURN INT_TO_ENUM(AnimalPickup, iAnimalSelection[iRandomSelection]) ENDFUNC PROC Update_Next_Animal_Pickups() INT iTypeIndex REPEAT APT_COUNT iTypeIndex CPRINTLN(DEBUG_ANIMAL_MODE, "Finding a new animal for pickup type ", Debug_Get_Pickup_Type_String_From_Enum(INT_TO_ENUM(AnimalPickupType, iTypeIndex)), ".") iNextPickupAnimal[iTypeIndex] = ENUM_TO_INT(Get_Random_Animal_Pickup_Of_Type(INT_TO_ENUM(AnimalPickupType, iTypeIndex))) CPRINTLN(DEBUG_ANIMAL_MODE, "Selected animal ", Debug_Get_Animal_String_From_Pickup_Enum(INT_TO_ENUM(AnimalPickup, iNextPickupAnimal[iTypeIndex])), ".") ENDREPEAT ENDPROC FUNC BOOL Is_Secret_Pickup_Available(INT paramPickupIndex) // Clues to the hackers. STRING strMassiveClue = "His quarry seemed familiar." IF IS_STRING_NULL_OR_EMPTY(strMassiveClue) ENDIF //Allow us to override this check in the widget. #IF IS_DEBUG_BUILD IF bDebugIgnoreSecretConditions RETURN TRUE ENDIF #ENDIF IF g_savedGlobals.sAmbient.bPeyoteProgressionComplete TIMEOFDAY eStartTime = GET_CURRENT_TIMEOFDAY() TIMEOFDAY eEndTime = eStartTime SET_TIMEOFDAY_HOUR(eStartTime, 5) SET_TIMEOFDAY_MINUTE(eStartTime, 30) SET_TIMEOFDAY_SECOND(eStartTime, 00) SET_TIMEOFDAY_HOUR(eEndTime, 8) SET_TIMEOFDAY_MINUTE(eEndTime, 00) SET_TIMEOFDAY_SECOND(eEndTime, 00) IF IS_NOW_AFTER_TIMEOFDAY(eStartTime) AND NOT IS_NOW_AFTER_TIMEOFDAY(eEndTime) IF IS_THIS_RANDOM_CHARACTER_MISSION_COMPLETED(RC_THELASTONE) IF ENUM_TO_INT(GET_CLOCK_DAY_OF_WEEK()) = paramPickupIndex INT iPrevWeather, iNextWeather FLOAT fInterp GET_CURR_WEATHER_STATE(iPrevWeather, iNextWeather, fInterp) IF (iPrevWeather = HASH("FOGGY") AND fInterp <= 0.5) OR (iNextWeather = HASH("FOGGY") AND fInterp >= 0.5) OR (iPrevWeather = HASH("XMAS") AND fInterp <= 0.5) OR (iNextWeather = HASH("XMAS") AND fInterp >= 0.5) RETURN TRUE ENDIF ENDIF ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC PROC Set_Models_For_Pickup_Type_As_No_Longer_Needed(AnimalPickupType paramType) INT iAnimalIndex REPEAT AP_COUNT iAnimalIndex AnimalPickup eAnimal = INT_TO_ENUM(AnimalPickup, iAnimalIndex) IF Get_Animal_Type(eAnimal) = paramType SET_MODEL_AS_NO_LONGER_NEEDED(Get_Animal_Model_From_Pickup_Enum(eAnimal)) ENDIF ENDREPEAT ENDPROC PROC Attempt_Create_CullSphere(INT &localCullSphereIndex, VECTOR cullSpherePosition, FLOAT cullSphereSize) INT i IF IS_A_CULLSPHERE_AVAILABLE(i) localCullSphereIndex = i PROCGRASS_ENABLE_CULLSPHERE(localCullSphereIndex,cullSpherePosition,cullSphereSize) ELSE CPRINTLN(DEBUG_ANIMAL_MODE, "No cullspheres available. May cause pickup to be unreachable.") ENDIF ENDPROC PROC Attempt_Remove_CullSphere(INT &localCullSphereIndex) IF localCullSphereIndex > -1 AND localCullSphereIndex < NUMBER_AVAILABLE_CULLSPHERES PROCGRASS_DISABLE_CULLSPHERE(localCullSphereIndex) localCullSphereIndex = -1 ENDIF ENDPROC FUNC BOOL Is_It_Safe_To_Load_Ambient_Animal_Assets() // Don't allow animal pickups to stream in if the player is moving very fast. // The streaming engine will be under too much stress. IF NOT IS_PED_INJURED(PLAYER_PED_ID()) IF VMAG2(GET_ENTITY_VELOCITY(PLAYER_PED_ID())) > AMBIENT_LOAD_PLAYER_SPEED_CUTOFF CDEBUG1LN(DEBUG_ANIMAL_MODE, "The player is moving too fast to stream peyote pickup assets.") RETURN FALSE ENDIF ENDIF RETURN TRUE ENDFUNC PROC Update_Pickup_Spawning() INT iPickupsUpdatedThisFrame = 0 WHILE iPickupsUpdatedThisFrame < ANIMAL_PICKUPS_UPDATED_PER_FRAME iPickupsUpdatedThisFrame++ IF NOT bLoadingPickup iCurrentPickupIndex++ IF iCurrentPickupIndex >= Get_Number_Of_Animal_Pickups_Of_Type(eCurrentPickupType) iCurrentPickupIndex = 0 INT iCurrentTypeIndex = ENUM_TO_INT(eCurrentPickupType) iCurrentTypeIndex++ IF g_savedGlobals.sAmbient.bPeyoteProgressionComplete #IF IS_DEBUG_BUILD OR bDebugIgnoreSecretConditions #ENDIF IF iCurrentTypeIndex >= ENUM_TO_INT(APT_COUNT) iCurrentTypeIndex = 0 ENDIF ELSE IF iCurrentTypeIndex >= ENUM_TO_INT(APT_SECRET) iCurrentTypeIndex = 0 ENDIF ENDIF eCurrentPickupType = INT_TO_ENUM(AnimalPickupType, iCurrentTypeIndex) ENDIF ENDIF IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID()) IF NOT IS_BIT_SET(iBitsetPickupSpawned[eCurrentPickupType], iCurrentPickupIndex) IF NOT IS_BIT_SET(iBitsetPickupLeaveArea[eCurrentPickupType], iCurrentPickupIndex) IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), vPickupPos[eCurrentPickupType][iCurrentPickupIndex]) <= fPickupSpawnDistSqr AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_ANIMAL) AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) AND Is_It_Safe_To_Load_Ambient_Animal_Assets() IF g_savedGlobals.sAmbient.bPeyoteProgressionComplete OR NOT IS_BIT_SET(g_savedGlobals.sAmbient.iPeyotePickupOfTypeFound[eCurrentPickupType], iCurrentPickupIndex) IF eCurrentPickupType != APT_SECRET OR Is_Secret_Pickup_Available(iCurrentPickupIndex) bLoadingPickup = TRUE AnimalPickup eCurrentAnimal = INT_TO_ENUM(AnimalPickup, iNextPickupAnimal[eCurrentPickupType]) MODEL_NAMES eAnimalModel = Get_Animal_Model_From_Pickup_Enum(eCurrentAnimal) MODEL_NAMES ePickupModel = Get_Animal_Pickup_Model(eCurrentPickupType, iCurrentPickupIndex) IF eSoundDataLoaded != eCurrentAnimal IF iPickupSoundID != -1 CPRINTLN(DEBUG_ANIMAL_MODE, "Stopping sound ", sSound.strSound, " as it doesn't match the pickup being spawned.") STOP_SOUND(iPickupSoundID) RELEASE_SOUND_ID(iPickupSoundID) iPickupSoundID = -1 ENDIF IF NOT IS_STRING_NULL_OR_EMPTY(sSound.strBank) IF NOT ARE_STRINGS_EQUAL(sSound.strBank, "NONE") CPRINTLN(DEBUG_ANIMAL_MODE, "Releasing currently loaded script audio bank ", sSound.strBank, " as it doesn't match the pickup being spawned.") RELEASE_NAMED_SCRIPT_AUDIO_BANK(sSound.strBank) ENDIF ENDIF Get_Pickup_Sound_Data(sSound, eAnimalModel) eSoundDataLoaded = eCurrentAnimal ENDIF REQUEST_MODEL(eAnimalModel) REQUEST_MODEL(ePickupModel) BOOL bSoundLoaded = TRUE IF NOT ARE_STRINGS_EQUAL(sSound.strBank, "NONE") bSoundLoaded = REQUEST_SCRIPT_AUDIO_BANK(sSound.strBank) ENDIF BOOL bBarkSoundLoaded = TRUE IF eSoundDataLoaded = AP_SECRET_SASQUATCH bBarkSoundLoaded = REQUEST_SCRIPT_AUDIO_BANK(sSound.strBarkBank) ENDIF IF HAS_MODEL_LOADED(eAnimalModel) AND HAS_MODEL_LOADED(ePickupModel) AND bSoundLoaded AND bBarkSoundLoaded INT iPlacementFlags = 0 SET_BIT(iPlacementFlags, ENUM_TO_INT(PLACEMENT_FLAG_FIXED)) SET_BIT(iPlacementFlags, ENUM_TO_INT(PLACEMENT_FLAG_LOCAL_ONLY)) CPRINTLN(DEBUG_ANIMAL_MODE, "Spawning pickup ", Debug_Get_Pickup_Type_String_From_Enum(eCurrentPickupType), "[", iCurrentPickupIndex,"].") oPickup[eCurrentPickupType][iCurrentPickupIndex] = CREATE_OBJECT(ePickupModel, vPickupPos[eCurrentPickupType][iCurrentPickupIndex]) SET_ENTITY_ROTATION(oPickup[eCurrentPickupType][iCurrentPickupIndex], vPickupRot[eCurrentPickupType][iCurrentPickupIndex]) FREEZE_ENTITY_POSITION(oPickup[eCurrentPickupType][iCurrentPickupIndex], TRUE) //stop procedural generation stuff peyopte pickup Attempt_Create_CullSphere(iCullSpherePeyoteCollect,vPickupPos[eCurrentPickupType][iCurrentPickupIndex],CULL_SPHERE_SIZE) //Start the pickup sound playing. IF NOT ARE_STRINGS_EQUAL(sSound.strBank, "NONE") AND NOT ARE_STRINGS_EQUAL(sSound.strSound, "NONE") CPRINTLN(DEBUG_ANIMAL_MODE, "Starting playing sound ", sSound.strSound, " from pickup object.") iPickupSoundID = GET_SOUND_ID() PLAY_SOUND_FROM_ENTITY(iPickupSoundID, sSound.strSound, oPickup[eCurrentPickupType][iCurrentPickupIndex], "PEYOTE_ATTRACT_SOUNDSET") ENDIF SET_MODEL_AS_NO_LONGER_NEEDED(ePickupModel) SET_BIT(iBitsetPickupSpawned[eCurrentPickupType], iCurrentPickupIndex) bLoadingPickup = FALSE ENDIF ENDIF ENDIF ENDIF ENDIF ELSE IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), vPickupPos[eCurrentPickupType][iCurrentPickupIndex]) >= fPickupDespawnDistSqr OR IS_BIT_SET(iStateBitset, BIT_ANIMAL_CONTROL_PLAYING_AS_ANIMAL) OR NOT Is_It_Safe_To_Load_Ambient_Animal_Assets() CPRINTLN(DEBUG_ANIMAL_MODE, "Cleaning up pickup ", Debug_Get_Pickup_Type_String_From_Enum(eCurrentPickupType), "[", iCurrentPickupIndex,"].") IF iPickupSoundID != -1 CPRINTLN(DEBUG_ANIMAL_MODE, "Stopping sound ", sSound.strSound, " as it's pickup is being destroyed.") STOP_SOUND(iPickupSoundID) RELEASE_SOUND_ID(iPickupSoundID) iPickupSoundID = -1 ENDIF IF DOES_ENTITY_EXIST(oPickup[eCurrentPickupType][iCurrentPickupIndex]) DELETE_OBJECT(oPickup[eCurrentPickupType][iCurrentPickupIndex]) ENDIF //allow procedural generation stuff Attempt_Remove_CullSphere(iCullSpherePeyoteCollect) SET_MODEL_AS_NO_LONGER_NEEDED(Get_Animal_Pickup_Model(eCurrentPickupType, iCurrentPickupIndex)) Set_Models_For_Pickup_Type_As_No_Longer_Needed(eCurrentPickupType) CLEAR_BIT(iBitsetPickupSpawned[eCurrentPickupType], iCurrentPickupIndex) ENDIF ENDIF ENDIF ENDWHILE ENDPROC PROC PRINT_HELP_PEYOTE(STRING helpText) BEGIN_TEXT_COMMAND_DISPLAY_HELP(helpText) END_TEXT_COMMAND_DISPLAY_HELP(HELP_TEXT_SLOT_STANDARD, FALSE, FALSE,-1) ENDPROC PROC SHOW_PEYOTE_HELP_TEXT(TEXT_LABEL_23 helptext) IF IS_USING_KEYBOARD_AND_MOUSE(FRONTEND_CONTROL) helpText += "_PC" ENDIF PRINT_HELP_PEYOTE(helpText) ENDPROC FUNC BOOL IS_PLAYER_WEARING_SCUBA_GEAR() SWITCH eLastPlayerCharacter CASE CHAR_MICHAEL IF IS_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL, SPECIAL_P0_SCUBA_ACCS_1) RETURN TRUE ENDIF BREAK CASE CHAR_FRANKLIN IF IS_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL, SPECIAL_P1_SCUBA_1) RETURN TRUE ENDIF BREAK CASE CHAR_TREVOR IF IS_PED_COMP_ITEM_CURRENT_SP(PLAYER_PED_ID(), COMP_TYPE_SPECIAL, SPECIAL_P2_SCUBA_1) RETURN TRUE ENDIF BREAK ENDSWITCH RETURN FALSE ENDFUNC FUNC BOOL MANAGE_MASK_PEYOTE_SWITCH() IF NOT bWearingScubaGear AND IS_PLAYER_WEARING_SCUBA_GEAR() bWearingScubaGear = TRUE CLEAR_PED_SCUBA_GEAR_VARIATION(PLAYER_PED_ID()) ELIF NOT bWearingScubaGear AND NOT bWearingMask AND IS_PED_WEARING_A_MASK(PLAYER_PED_ID()) bWearingMask = TRUE GET_PED_VARIATIONS(PLAYER_PED_ID(), sPedVariations) SetPedCompItemCurrent fpSetPedCompItemCurrent = &SET_PED_COMP_ITEM_CURRENT_SP REMOVE_ALL_MASKS(PLAYER_PED_ID(),fpSetPedCompItemCurrent) ELIF (NOT bWearingMask AND NOT bWearingScubaGear) OR HAVE_ALL_STREAMING_REQUESTS_COMPLETED(PLAYER_PED_ID()) RETURN TRUE ENDIF RETURN FALSE ENDFUNC PROC Show_Help_Text() TEXT_LABEL_23 helpText SWITCH eTriggeredType CASE APT_UNDERWATER IF eTriggeredAnimal = AP_UNDERWATER_STINGRAY OR eTriggeredAnimal = AP_UNDERWATER_DOLPHIN // no attack helpText = "PEY_W" SHOW_PEYOTE_HELP_TEXT(helpText) ELIF eTriggeredAnimal = AP_UNDERWATER_FISH // no attack, no sprint PRINT_HELP_PEYOTE("PEY_GENERAL") ELSE helpText = "PEY_W_A" SHOW_PEYOTE_HELP_TEXT(helpText) ENDIF BREAK CASE APT_SECRET helpText = "PEY_L_A" SHOW_PEYOTE_HELP_TEXT(helpText) BREAK CASE APT_LOWLAND IF eTriggeredAnimal = AP_LOWLAND_COW OR eTriggeredAnimal = AP_LOWLAND_CAT OR eTriggeredAnimal = AP_LOWLAND_RABBIT //no attack helpText = "PEY_L" SHOW_PEYOTE_HELP_TEXT(helpText) ELSE helpText = "PEY_L_A" SHOW_PEYOTE_HELP_TEXT(helpText) ENDIF BREAK DEFAULT //highland spawn has a 1 in 50 chance to switch to lowland after all peyotes found SWITCH eTriggeredAnimal CASE AP_HIGHLAND_HEN CASE AP_LOWLAND_COW helpText = "PEY_L" SHOW_PEYOTE_HELP_TEXT(helpText) BREAK CASE AP_HIGHLAND_CHICKENHAWK CASE AP_HIGHLAND_CORMORANT CASE AP_HIGHLAND_CROW CASE AP_HIGHLAND_PIGEON CASE AP_HIGHLAND_SEAGULL PRINT_HELP_PEYOTE("PEY_HIGH") BREAK DEFAULT helpText = "PEY_L_A" SHOW_PEYOTE_HELP_TEXT(helpText) BREAK ENDSWITCH BREAK ENDSWITCH ENDPROC PROC Manage_Animal_Bark() IF IS_DISABLED_CONTROL_JUST_PRESSED(PLAYER_CONTROL, INPUT_DUCK) Play_Animal_Sound(sAnim.strBarkDict, sAnim.strBarkAnim, barkTimer, eLastPlayerCharacter,iBarkSoundID, sSound.strBarkSound) ENDIF ENDPROC PROC Start_Animal_Audio_Scene(AnimalPickup paramAnimal) SWITCH Get_Animal_Type(paramAnimal) CASE APT_LOWLAND IF NOT IS_AUDIO_SCENE_ACTIVE("PLAYER_AS_ANIMAL_LAND_SCENE") START_AUDIO_SCENE("PLAYER_AS_ANIMAL_LAND_SCENE") ENDIF BREAK CASE APT_HIGHLAND IF paramAnimal != AP_HIGHLAND_HEN IF NOT IS_AUDIO_SCENE_ACTIVE("PLAYER_AS_ANIMAL_AIR_SCENE") START_AUDIO_SCENE("PLAYER_AS_ANIMAL_AIR_SCENE") ENDIF ELSE IF NOT IS_AUDIO_SCENE_ACTIVE("PLAYER_AS_ANIMAL_LAND_SCENE") START_AUDIO_SCENE("PLAYER_AS_ANIMAL_LAND_SCENE") ENDIF ENDIF BREAK CASE APT_UNDERWATER IF NOT IS_AUDIO_SCENE_ACTIVE("PLAYER_AS_ANIMAL_WATER_SCENE") START_AUDIO_SCENE("PLAYER_AS_ANIMAL_WATER_SCENE") ENDIF BREAK CASE APT_SECRET IF NOT IS_AUDIO_SCENE_ACTIVE("PLAYER_AS_SASQUATCH_SCENE") START_AUDIO_SCENE("PLAYER_AS_SASQUATCH_SCENE") ENDIF BREAK ENDSWITCH ENDPROC FUNC BOOL IS_VEHICLE_A_SEA_PLANE(VEHICLE_INDEX veh) MODEL_NAMES vehModel = GET_ENTITY_MODEL(veh) IF vehModel = DODO RETURN TRUE ENDIF RETURN FALSE ENDFUNC FUNC BOOL IS_VEHICLE_A_SUB(VEHICLE_INDEX veh) MODEL_NAMES vehModel = GET_ENTITY_MODEL(veh) IF vehModel = SUBMERSIBLE2 OR vehModel = SUBMERSIBLE RETURN TRUE ENDIF RETURN FALSE ENDFUNC PROC Reposition_Player_Vehicle_For_Pickup(AnimalPickupType paramType, INT paramPickupIndex) vehPlayer = GET_PLAYERS_LAST_VEHICLE() IF DOES_ENTITY_EXIST(vehPlayer) AND IS_VEHICLE_SEAT_FREE(vehPlayer) IF IS_VEHICLE_DRIVEABLE(vehPlayer) SET_ENTITY_AS_MISSION_ENTITY(vehPlayer, FALSE, TRUE) IF NOT IS_VEHICLE_A_SEA_PLANE(vehPlayer) SET_VEHICLE_ENGINE_ON(vehPlayer, FALSE, TRUE) ENDIF IF NOT IS_THIS_MODEL_A_BOAT(GET_ENTITY_MODEL(vehPlayer)) AND NOT IS_THIS_MODEL_A_PLANE(GET_ENTITY_MODEL(vehPlayer)) AND NOT IS_VEHICLE_A_SUB(vehPlayer) CPRINTLN(DEBUG_ANIMAL_MODE, "Repositioning and setting player vehicle as a vehicle gen.") VECTOR vVehPosition FLOAT fVehHeading IF paramType = APT_HIGHLAND AND IS_THIS_MODEL_A_HELI(GET_ENTITY_MODEL(vehPlayer)) CPRINTLN(DEBUG_ANIMAL_MODE, "Using highland pickup helicopter location.") vVehPosition = Get_Highland_Pickup_Helicopter_Position(paramPickupIndex) fVehHeading = Get_Highland_Pickup_Helicopter_Heading(paramPickupIndex) ELSE CPRINTLN(DEBUG_ANIMAL_MODE, "Using default vehicle location.") vVehPosition = vVehiclePos[paramType][paramPickupIndex] fVehHeading = fVehicleHead[paramType][paramPickupIndex] ENDIF CLEAR_AREA(vVehPosition, 9.0, TRUE, FALSE) vVehPositionOriginalMisc = GET_ENTITY_COORDS(vehPlayer) fVehHeadingOriginalMisc = GET_ENTITY_HEADING(vehPlayer) SET_ENTITY_COORDS(vehPlayer, vVehPosition) SET_ENTITY_HEADING(vehPlayer, fVehHeading) SET_VEHICLE_ON_GROUND_PROPERLY(vehPlayer) IF NOT IS_VEHICLE_A_TAXI_MODEL(vehPlayer) SET_MISSION_VEHICLE_GEN_VEHICLE(vehPlayer, vVehPosition, fVehHeading) vVehPositionOriginalMisc = <<0,0,0>> fVehHeadingOriginalMisc = 0 ELSE CPRINTLN(DEBUG_ANIMAL_MODE, "Vehicle is taxi model, hold off setting vehicle gen.") vVehPositionMisc = vVehPosition fVehHeadingMisc = fVehHeading ENDIF ELSE CPRINTLN(DEBUG_ANIMAL_MODE, "Setting player's boat/plane as a vehicle gen in its current location.") SET_MISSION_VEHICLE_GEN_VEHICLE(vehPlayer, GET_ENTITY_COORDS(vehPlayer), GET_ENTITY_HEADING(vehPlayer)) ENDIF ENDIF ENDIF ENDPROC PROC Toggle_Animal_Respawn_Conditions(BOOL bTurnOn) IF bTurnOn SET_FADE_OUT_AFTER_DEATH(FALSE) SET_FADE_OUT_AFTER_ARREST(FALSE) SET_FADE_IN_AFTER_DEATH_ARREST(FALSE) SET_RESTART_COORD_OVERRIDE(vRespawnPos[eTriggeredType][iTriggeredIndex], fRespawnHead[eTriggeredType][iTriggeredIndex]) ELSE SET_FADE_OUT_AFTER_DEATH(TRUE) SET_FADE_OUT_AFTER_ARREST(TRUE) SET_FADE_IN_AFTER_DEATH_ARREST(TRUE) CLEAR_RESTART_COORD_OVERRIDE() IGNORE_NEXT_RESTART(FALSE) PAUSE_DEATH_ARREST_RESTART(FALSE) ENDIF ENDPROC PROC Switch_To_Player_Cleanup() CDEBUG3LN(DEBUG_ANIMAL_MODE, "Switch_To_Player_Cleanup. Leave ped as animal, SP->MP selector script will take care of switch") CLEAR_HELP() Attempt_Remove_CullSphere(iCullSphereAnimalSpawn) SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), iTriggeredWantedLevel) IF iBarkSoundID != -1 CPRINTLN(DEBUG_ANIMAL_MODE, "Stopping bark sound ", sSound.strBarkSound, " as switching to player.") STOP_SOUND(iBarkSoundID) RELEASE_SOUND_ID(iBarkSoundID) iBarkSoundID = -1 ENDIF IF vehPlayer != NULL AND NOT DOES_ENTITY_EXIST(vehPlayer) CPRINTLN(DEBUG_ANIMAL_MODE, "Create vehicle - cleanup.") SET_VEHICLE_GEN_AVAILABLE(VEHGEN_MISSION_VEH, TRUE) g_sVehicleGenNSData.bLeaveAreaBeforeCreating[VEHGEN_MISSION_VEH] = FALSE ENDIF //Clean autosave flags up. They're pretty dangerous. SET_AUTOSAVE_IGNORES_ON_MISSION_FLAG(FALSE, FALSE) STOP_AUDIO_SCENES() Deactivate_Animal_Restricted_State() Toggle_Animal_Respawn_Conditions(FALSE) SET_MODEL_AS_NO_LONGER_NEEDED(Get_Animal_Model_From_Pickup_Enum(eTriggeredAnimal)) //Restore_Game_State_Snapshot(g_startSnapshot) // MODEL_NAMES ePlayerModel = GET_PLAYER_PED_MODEL(eLastPlayerCharacter) // // Get_Pickup_Type_Lead_Out_Anim_Data(sAnim, eTriggeredAnimal) // // REQUEST_MODEL(ePlayerModel) // // CPRINTLN(DEBUG_ANIMAL_MODE, "Player character model loaded and screen faded. Switching player back to story character.") // WHILE NOT HAS_MODEL_LOADED(ePlayerModel) // CPRINTLN(DEBUG_ANIMAL_MODE, "Peyote force cleanup. ~probably switch to MP. Player PED not loaded, should be preloaded. WAIT(0) This will cause issues.") // //Should be pre-loaded, but if not then wait. Using WAIT when switching to MP causes issue. But no other alternative here. // WAIT(0) // ENDWHILE // SET_PLAYER_MODEL(PLAYER_ID(), ePlayerModel) // // //Inform code that we are no longer an animal. // SET_PLAYER_IS_IN_ANIMAL_FORM(FALSE) // // VECTOR playerPos = GET_ENTITY_COORDS(PLAYER_PED_ID()) // // IF eTriggeredType = APT_UNDERWATER // SET_ENTITY_COORDS(PLAYER_PED_ID(), playerPos) // ELSE // SET_ENTITY_COORDS(PLAYER_PED_ID(), <>) //reset Z coord, make sure player is not through the ground // ENDIF // // //Move the time forward a random amount between 5 and 30 minutes. // TIMEOFDAY todNewTime = GET_CURRENT_TIMEOFDAY() // INT iMinsToAdd = GET_RANDOM_INT_IN_RANGE(5, 30) // ADD_TIME_TO_TIMEOFDAY(todNewTime, 0, iMinsToAdd) // SET_CLOCK_TIME(GET_TIMEOFDAY_HOUR(todNewTime), GET_TIMEOFDAY_MINUTE(todNewTime), GET_TIMEOFDAY_SECOND(todNewTime)) // SET_CLOCK_DATE(GET_TIMEOFDAY_DAY(todNewTime), GET_TIMEOFDAY_MONTH(todNewTime), GET_TIMEOFDAY_YEAR(todNewTime)) // CDEBUG1LN(DEBUG_ANIMAL_MODE, "Added ", iMinsToAdd, " minutes to the peyote dream start time.") // // //Restore the camera view the player was using before the animal. // SET_FOLLOW_PED_CAM_VIEW_MODE(eTriggeredCameraView) // SET_GAMEPLAY_CAM_RELATIVE_HEADING() // SET_GAMEPLAY_CAM_RELATIVE_PITCH() // SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) // // //Clean autosave flags up. They're pretty dangerous. // SET_AUTOSAVE_IGNORES_ON_MISSION_FLAG(FALSE, FALSE) // // //Randomise the next animals every time we turn back to human. // Update_Next_Animal_Pickups() // // IF NOT DOES_ENTITY_EXIST(vehPlayer) // SET_VEHICLE_GEN_AVAILABLE(VEHGEN_MISSION_VEH, TRUE) // g_sVehicleGenNSData.bLeaveAreaBeforeCreating[VEHGEN_MISSION_VEH] = FALSE // ENDIF // // STOP_AUDIO_SCENES() // // Deactivate_Animal_Restricted_State() // Toggle_Animal_Respawn_Conditions(FALSE) // // SET_MODEL_AS_NO_LONGER_NEEDED(Get_Animal_Model_From_Pickup_Enum(eTriggeredAnimal)) // // TRIGGER_MUSIC_EVENT("PEYOTE_TRIPS_STOP") ENDPROC FUNC BOOL IS_PLAYER_MOVEMENT_DETECTED() IF IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_MOVE_UP_ONLY) OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_MOVE_DOWN_ONLY) OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_MOVE_LEFT_ONLY) OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_MOVE_RIGHT_ONLY) OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_ATTACK) OR IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_RELOAD) RETURN TRUE ENDIF RETURN FALSE ENDFUNC FUNC BOOL Switch_To_Player() CDEBUG3LN(DEBUG_ANIMAL_MODE, "Attempting to switch player model to a story character.") MODEL_NAMES ePlayerModel = GET_PLAYER_PED_MODEL(eLastPlayerCharacter) IF NOT IS_BIT_SET(iStateBitset, BIT_SELECTED_TRANSFORM_OUT_DATA) IF NOT IS_STRING_NULL_OR_EMPTY(sAnim.strIdleDict) REMOVE_ANIM_DICT(sAnim.strIdleDict) ENDIF Get_Pickup_Type_Lead_Out_Anim_Data(sAnim, eTriggeredAnimal) SET_BIT(iStateBitset, BIT_SELECTED_TRANSFORM_OUT_DATA) ENDIF IF iBarkSoundID != -1 CPRINTLN(DEBUG_ANIMAL_MODE, "Stopping bark sound ", sSound.strBarkSound, " as switching to player.") STOP_SOUND(iBarkSoundID) RELEASE_SOUND_ID(iBarkSoundID) iBarkSoundID = -1 ENDIF BOOL animSound = TRUE IF ARE_STRINGS_EQUAL(sAnim.strDict,"random@peyote@generic") animSound = REQUEST_SCRIPT_AUDIO_BANK("Taxi_Vomit") ENDIF REQUEST_ANIM_DICT(sAnim.strIdleDict) REQUEST_ANIM_DICT(sAnim.strDict) REQUEST_MODEL(ePlayerModel) IF IS_PLAYER_PLAYING(PLAYER_ID()) IF NOT IS_BIT_SET(iStateBitset, BIT_PRIMED_TRANSFORM_OUT_ANIMATION) REPLAY_PREVENT_RECORDING_AND_UI_THIS_FRAME() IF ANIMPOSTFX_IS_RUNNING("PeyoteEndIn") AND GET_GAME_TIMER() > myTimer-500 IF NOT drawRect INIT_DRAW_WHITE_RECT_FADE_IN() ENDIF ENDIF IF ANIMPOSTFX_IS_RUNNING("PeyoteEndIn") AND GET_GAME_TIMER() > myTimer //IS_SCREEN_FADED_OUT() OR bSkipFade IF NOT IS_NEW_LOAD_SCENE_ACTIVE() CDEBUG1LN(DEBUG_ANIMAL_MODE, "Starting new load scene.") CLEAR_HELP() SET_ENTITY_COORDS(PLAYER_PED_ID(), vRespawnPos[eTriggeredType][iTriggeredIndex]) SET_ENTITY_HEADING(PLAYER_PED_ID(), fRespawnHead[eTriggeredType][iTriggeredIndex]) //allow procedural generation stuff Attempt_Remove_CullSphere(iCullSphereAnimalSpawn) PROCGRASS_DISABLE_CULLSPHERE(1) NEW_LOAD_SCENE_START_SPHERE(vRespawnPos[eTriggeredType][iTriggeredIndex],1000.0) iLoadSceneTimer = GET_GAME_TIMER() ELIF (IS_NEW_LOAD_SCENE_LOADED() OR (GET_GAME_TIMER() - iLoadSceneTimer) > ANIMAL_MODE_LOAD_SCENE_TIMEOUT) AND HAS_MODEL_LOADED(ePlayerModel) AND HAS_ANIM_DICT_LOADED(sAnim.strDict) AND HAS_ANIM_DICT_LOADED(sAnim.strIdleDict) AND animSound CPRINTLN(DEBUG_ANIMAL_MODE, "Player character model loaded and screen faded. Switching player back to story character.") SET_PLAYER_CONTROL(PLAYER_ID(), FALSE) SET_PLAYER_MODEL(PLAYER_ID(), ePlayerModel) //Inform code that we are no longer an animal. SET_PLAYER_IS_IN_ANIMAL_FORM(FALSE) NEW_LOAD_SCENE_STOP() CLEAR_AREA(vRespawnPos[eTriggeredType][iTriggeredIndex], 30.0, TRUE) SET_SCENARIO_TYPE_ENABLED("WORLD_MOUNTAIN_LION_REST",FALSE) SET_SCENARIO_TYPE_ENABLED("WORLD_MOUNTAIN_LION_WANDER",FALSE) Restore_Game_State_Snapshot(g_startSnapshot) SET_PLAYER_WANTED_LEVEL(PLAYER_ID(), iTriggeredWantedLevel) //Move the time forward a random amount between 5 and 30 minutes. TIMEOFDAY todNewTime = GET_CURRENT_TIMEOFDAY() INT iMinsToAdd = GET_RANDOM_INT_IN_RANGE(5, 30) ADD_TIME_TO_TIMEOFDAY(todNewTime, 0, iMinsToAdd) SET_CLOCK_TIME(GET_TIMEOFDAY_HOUR(todNewTime), GET_TIMEOFDAY_MINUTE(todNewTime), GET_TIMEOFDAY_SECOND(todNewTime)) SET_CLOCK_DATE(GET_TIMEOFDAY_DAY(todNewTime), GET_TIMEOFDAY_MONTH(todNewTime), GET_TIMEOFDAY_YEAR(todNewTime)) CDEBUG1LN(DEBUG_ANIMAL_MODE, "Added ", iMinsToAdd, " minutes to the peyote dream start time.") SET_ENTITY_COORDS(PLAYER_PED_ID(), vRespawnPos[eTriggeredType][iTriggeredIndex]) SET_ENTITY_HEADING(PLAYER_PED_ID(), fRespawnHead[eTriggeredType][iTriggeredIndex]) //Set the leave area flag for this pickup. SET_BIT(iBitsetPickupLeaveArea[eTriggeredType], iTriggeredIndex) SET_BIT(iStateBitset, BIT_PRIMED_TRANSFORM_OUT_ANIMATION) CLEAR_BIT(iStateBitset, BIT_STARTED_TRANSFORM_OUT_ANIMATION) CLEAR_BIT(iStateBitset, BIT_ENDED_TRANSFORM_OUT_ANIMATION) CLEAR_BIT(iStateBitset, BIT_ANIMAL_CONTROL_PLAYING_AS_ANIMAL) ELSE CDEBUG1LN(DEBUG_ANIMAL_MODE, "Waiting for new load scene and model/anim loads before switching model to player.") ENDIF ELSE CDEBUG1LN(DEBUG_ANIMAL_MODE, "Waiting for screen to be faded before switching model to player.") ENDIF ELIF NOT IS_BIT_SET(iStateBitset, BIT_STARTED_TRANSFORM_OUT_ANIMATION) REPLAY_PREVENT_RECORDING_AND_UI_THIS_FRAME() IF HAVE_ALL_STREAMING_REQUESTS_COMPLETED(PLAYER_PED_ID()) CDEBUG1LN(DEBUG_ANIMAL_MODE, "Streaming requests finished. Fading in and starting lead out anim.") //Restore the camera view the player was using before the animal. SET_FOLLOW_PED_CAM_VIEW_MODE(eTriggeredCameraView) SET_GAMEPLAY_CAM_RELATIVE_HEADING() SET_GAMEPLAY_CAM_RELATIVE_PITCH() SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) //Clean autosave flags up. They're pretty dangerous. SET_AUTOSAVE_IGNORES_ON_MISSION_FLAG(FALSE, FALSE) //Randomise the next animals every time we turn back to human. Update_Next_Animal_Pickups() IF vehPlayer != NULL AND NOT DOES_ENTITY_EXIST(vehPlayer) CPRINTLN(DEBUG_ANIMAL_MODE, "Create vehicle.") SET_VEHICLE_GEN_AVAILABLE(VEHGEN_MISSION_VEH, TRUE) g_sVehicleGenNSData.bLeaveAreaBeforeCreating[VEHGEN_MISSION_VEH] = FALSE ENDIF STOP_AUDIO_SCENES() Deactivate_Animal_Restricted_State() Toggle_Animal_Respawn_Conditions(FALSE) TRIGGER_MUSIC_EVENT("PEYOTE_TRIPS_STOP") IF NOT HAS_ANIM_DICT_LOADED(sAnim.strDict) SCRIPT_ASSERT("whaaatt?? HAS_ANIM_DICT_LOADED(sAnim.strDict) = false.... ") ENDIF VECTOR syncScenePos = vRespawnPos[eTriggeredType][iTriggeredIndex] //GET_ENTITY_COORDS(PLAYER_PED_ID()) IF eTriggeredType != APT_UNDERWATER syncScenePos.Z += 0.25 GET_GROUND_Z_FOR_3D_COORD(syncScenePos,syncScenePos.Z) ENDIF VECTOR syncSceneRot = <<0,0,fRespawnHead[eTriggeredType][iTriggeredIndex]>> iSyncSceneID = CREATE_SYNCHRONIZED_SCENE(syncScenePos, syncSceneRot) SET_SYNCHRONIZED_SCENE_HOLD_LAST_FRAME(iSyncSceneID, TRUE) SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneID, FALSE) TASK_SYNCHRONIZED_SCENE(PLAYER_PED_ID(), iSyncSceneID, sAnim.strDict, sAnim.strAnim, INSTANT_BLEND_IN,SLOW_BLEND_OUT) FORCE_PED_AI_AND_ANIMATION_UPDATE(PLAYER_PED_ID()) CDEBUG1LN(DEBUG_ANIMAL_MODE, "Starting to wait for anim to start.") INIT_DRAW_WHITE_RECT_FADE_OUT() ANIMPOSTFX_STOP("PeyoteEndIn") ANIMPOSTFX_PLAY("PeyoteEndOut", 0, FALSE) SET_BIT(iStateBitset, BIT_STARTED_TRANSFORM_OUT_ANIMATION) ELSE CDEBUG1LN(DEBUG_ANIMAL_MODE, "Waiting for player streaming requests to finish before fading in.") ENDIF ELIF NOT IS_BIT_SET(iStateBitset, BIT_ENDED_TRANSFORM_OUT_ANIMATION) IF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), sAnim.strDict, sAnim.strAnim) IF HAS_ANIM_EVENT_FIRED(PLAYER_PED_ID(), GET_HASH_KEY("interrupt")) CPRINTLN(DEBUG_ANIMAL_MODE, "'interrupt' event firing.") IF NOT g_savedGlobals.sAmbient.bPeyoteProgressionComplete bDisplaySplash = TRUE bMessageOnDisplay = TRUE CPRINTLN(DEBUG_ANIMAL_MODE, "Triggered splash screen displaying.") ENDIF CDEBUG1LN(DEBUG_ANIMAL_MODE, "Lead out animation finished. Transition over.") SET_BIT(iStateBitset, BIT_INTERRUPT_EVENT_FIRED) SET_BIT(iStateBitset, BIT_ENDED_TRANSFORM_OUT_ANIMATION) ENDIF ELSE SET_BIT(iStateBitset, BIT_ENDED_TRANSFORM_OUT_ANIMATION) ENDIF ELIF IS_BIT_SET(iStateBitset, BIT_INTERRUPT_EVENT_FIRED) IF IS_BIT_SET(iStateBitset, BIT_IDLE_ANIM_STARTED) IF GET_SCRIPT_TASK_STATUS(PLAYER_PED_ID(),SCRIPT_TASK_PLAY_ANIM) = FINISHED_TASK CLEAR_BIT(iStateBitset, BIT_INTERRUPT_EVENT_FIRED) CPRINTLN(DEBUG_ANIMAL_MODE, "Clearing BIT_INTERRUPT_EVENT_FIRED, seq finished") ENDIF ELIF GET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneID) = 1.0 //GET_SCRIPT_TASK_STATUS(PLAYER_PED_ID(),SCRIPT_TASK_SYNCHRONIZED_SCENE) != PERFORMING_TASK IF NOT IS_BIT_SET(iStateBitset, BIT_IDLE_ANIM_STARTED) TASK_PLAY_ANIM(PLAYER_PED_ID(), sAnim.strIdleDict, sAnim.strIdleAnim,SLOW_BLEND_IN,SLOW_BLEND_OUT) CPRINTLN(DEBUG_ANIMAL_MODE, "Starting idle anim") SET_BIT(iStateBitset, BIT_IDLE_ANIM_STARTED) ENDIF ENDIF IF IS_PLAYER_MOVEMENT_DETECTED() IF GET_SCRIPT_TASK_STATUS(PLAYER_PED_ID(),SCRIPT_TASK_SYNCHRONIZED_SCENE) = PERFORMING_TASK STOP_SYNCHRONIZED_ENTITY_ANIM(PLAYER_PED_ID(),-0.5,TRUE) CPRINTLN(DEBUG_ANIMAL_MODE, "Stopping synched scene") ELIF IS_ENTITY_PLAYING_ANIM(PLAYER_PED_ID(), sAnim.strIdleDict, sAnim.strIdleAnim) STOP_ENTITY_ANIM(PLAYER_PED_ID(), sAnim.strIdleAnim, sAnim.strIdleDict,-0.5) CPRINTLN(DEBUG_ANIMAL_MODE, "Stopping idle anim") ENDIF CLEAR_PED_TASKS(PLAYER_PED_ID()) CLEAR_BIT(iStateBitset, BIT_INTERRUPT_EVENT_FIRED) CPRINTLN(DEBUG_ANIMAL_MODE, "Clearing BIT_INTERRUPT_EVENT_FIRED, player interrupted") ENDIF ELSE CPRINTLN(DEBUG_ANIMAL_MODE, "Lead-out transition ended.") REMOVE_ANIM_DICT(sAnim.strDict) REMOVE_ANIM_DICT(sAnim.strIdleDict) IF NOT IS_STRING_NULL_OR_EMPTY(sAnim.strBarkDict) REMOVE_ANIM_DICT(sAnim.strBarkDict) sAnim.strBarkDict = "" sAnim.strBarkAnim = "" ENDIF CLEAR_BIT(iStateBitset, BIT_SELECTED_TRANSFORM_OUT_DATA) CLEAR_BIT(iStateBitset, BIT_PRIMED_TRANSFORM_OUT_ANIMATION) CLEAR_BIT(iStateBitset, BIT_STARTED_TRANSFORM_OUT_ANIMATION) CLEAR_BIT(iStateBitset, BIT_ENDED_TRANSFORM_OUT_ANIMATION) CLEAR_BIT(iStateBitset, BIT_IDLE_ANIM_STARTED) SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) RESET_SCENARIO_TYPES_ENABLED() //Restore the camera view the player was using before the animal. IF eTriggeredCameraView = CAM_VIEW_MODE_FIRST_PERSON SET_FOLLOW_PED_CAM_VIEW_MODE(eTriggeredCameraView) SET_GAMEPLAY_CAM_RELATIVE_HEADING() SET_GAMEPLAY_CAM_RELATIVE_PITCH() ENDIF wantedTimer = -1 currentConversation = "" SET_SCRIPTS_SAFE_FOR_CUTSCENE(FALSE) //Enable stats STAT_ENABLE_STATS_TRACKING() RETURN TRUE ENDIF ELSE CDEBUG1LN(DEBUG_ANIMAL_MODE, "Waiting for player to be playing before switching model to player.") ENDIF RETURN FALSE ENDFUNC PROC UPDATE_SHAKE_CAMERA() FLOAT fStartShake = 1.0 INT iTimeDelay = 100 FLOAT fMaxShake = 4.0 IF DOES_CAM_EXIST(camSyncScene) IF NOT IS_CAM_SHAKING(camSyncScene) fDrunkCameraShake = fStartShake SHAKE_CAM(camSyncScene, "DRUNK_SHAKE", fDrunkCameraShake) cameraTimer = GET_GAME_TIMER() + iTimeDelay ELSE fDrunkCameraShake = CLAMP(fDrunkCameraShake +@0.4, fStartShake, fMaxShake) IF fDrunkCameraShake < fMaxShake AND ( GET_GAME_TIMER() > cameraTimer) SET_CAM_SHAKE_AMPLITUDE(camSyncScene,fDrunkCameraShake) cameraTimer = GET_GAME_TIMER() + iTimeDelay ENDIF ENDIF ENDIF ENDPROC PROC Non_Active_Taxi_Check() IF DOES_ENTITY_EXIST(vehPlayer) AND NOT IS_ENTITY_DEAD(vehPlayer) AND IS_VEHICLE_A_TAXI_MODEL(vehPlayer) SET_MISSION_VEHICLE_GEN_VEHICLE(vehPlayer, vVehPositionMisc, fVehHeadingMisc) vVehPositionMisc = <<0,0,0>> fVehHeadingMisc = 0 vVehPositionOriginalMisc = <<0,0,0>> fVehHeadingOriginalMisc = 0 CPRINTLN(DEBUG_ANIMAL_MODE, "last used vehicle is non active taxi") ENDIF ENDPROC PROC Active_Taxi_Check() IF DOES_ENTITY_EXIST(vehPlayer) AND NOT IS_ENTITY_DEAD(vehPlayer) AND NOT IS_VEHICLE_SEAT_FREE(vehPlayer) SET_ENTITY_COORDS(vehPlayer, vVehPositionOriginalMisc) SET_ENTITY_HEADING(vehPlayer, fVehHeadingOriginalMisc) SET_VEHICLE_ON_GROUND_PROPERLY(vehPlayer) SET_VEHICLE_AS_NO_LONGER_NEEDED(vehPlayer) vehPlayer = null vVehPositionMisc = <<0,0,0>> fVehHeadingMisc = 0 vVehPositionOriginalMisc = <<0,0,0>> fVehHeadingOriginalMisc = 0 CPRINTLN(DEBUG_ANIMAL_MODE, "last used vehicle is taxi/ being used, get rid of it. vehPlayer = null") ENDIF ENDPROC FUNC BOOL Switch_To_Animal() CDEBUG3LN(DEBUG_ANIMAL_MODE, "Attempting to switch player model to a ", Debug_Get_Animal_String_From_Pickup_Enum(eTriggeredAnimal), ".") MODEL_NAMES eAnimalModel = Get_Animal_Model_From_Pickup_Enum(eTriggeredAnimal) REQUEST_MODEL(eAnimalModel) IF NOT IS_BIT_SET(iStateBitset, BIT_SELECTED_TRANSFORM_IN_DATA) Get_Pickup_Type_Lead_In_Anim_Data(sAnim, Get_Animal_Pickup_Model(eTriggeredType, iTriggeredIndex)) Get_Pickup_Type_Bark_Anim_Data(sAnim.strBarkDict,sAnim.strBarkAnim,eAnimalModel) Get_Pickup_Type_Animal_Idle_Anim_Data() Get_And_Update_Peyote_Conversations(eTriggeredAnimal) SET_BIT(iStateBitset, BIT_SELECTED_TRANSFORM_IN_DATA) ENDIF IF IS_BIT_SET(iStateBitset, BIT_STARTED_TRANSFORM_IN_ANIMATION) THEFEED_HIDE_THIS_FRAME() ENDIF IF NOT IS_BIT_SET(iStateBitset, BIT_STARTED_TRANSFORM_IN_ANIMATION) REQUEST_ANIM_DICT(sAnim.strDict) REQUEST_MODEL(chunkyModel) BOOL animalBarkAnim = TRUE IF NOT IS_STRING_NULL_OR_EMPTY(sAnim.strBarkDict) REQUEST_ANIM_DICT(sAnim.strBarkDict) animalBarkAnim = HAS_ANIM_DICT_LOADED(sAnim.strBarkDict) ENDIF BOOL animalIdleAnim = TRUE IF NOT IS_STRING_NULL_OR_EMPTY(sAnim.strIdleDict) REQUEST_ANIM_DICT(sAnim.strIdleDict) animalIdleAnim = HAS_ANIM_DICT_LOADED(sAnim.strIdleDict) ENDIF CPRINTLN(DEBUG_ANIMAL_MODE,". LOAD_STREAM(PEYOTE_TRANSITION_IN) = = ", LOAD_STREAM("PEYOTE_TRANSITION_IN")) IF HAS_ANIM_DICT_LOADED(sAnim.strDict) AND animalBarkAnim AND animalIdleAnim AND HAS_MODEL_LOADED(chunkyModel) AND LOAD_STREAM("PEYOTE_TRANSITION_IN") AND MANAGE_MASK_PEYOTE_SWITCH() CPRINTLN(DEBUG_ANIMAL_MODE, "Starting transform in animation.") Reposition_Player_Vehicle_For_Pickup(eTriggeredType, iTriggeredIndex) SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE) STOP_FIRE_IN_RANGE(vPickupPos[eTriggeredType][iTriggeredIndex],10) IF NOT IS_PED_INJURED(PLAYER_PED_ID()) SET_CURRENT_PED_WEAPON(PLAYER_PED_ID(), WEAPONTYPE_UNARMED, TRUE) SET_ENTITY_INVINCIBLE(PLAYER_PED_ID(), TRUE) CLEAR_AREA(GET_ENTITY_COORDS(PLAYER_PED_ID()), 2.0, TRUE) ENDIF DISPLAY_RADAR(FALSE) THEFEED_PAUSE() iSyncSceneID = CREATE_SYNCHRONIZED_SCENE(vPickupPos[eTriggeredType][iTriggeredIndex], vPickupRot[eTriggeredType][iTriggeredIndex]) camSyncScene = CREATE_CAM("DEFAULT_ANIMATED_CAMERA", TRUE) SET_SYNCHRONIZED_SCENE_HOLD_LAST_FRAME(iSyncSceneID, FALSE) SET_SYNCHRONIZED_SCENE_LOOPED(iSyncSceneID, FALSE) // just always clear ped task imm. Stops anim messing up if ped is ragdolling/ getting out of a vehicle ontop of a peyote pickup CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID()) // SET_BLOCKING_OF_NON_TEMPORARY_EVENTS(PLAYER_PED_ID(),TRUE) // SET_PED_COMBAT_ATTRIBUTES(PLAYER_PED_ID(),CA_PLAY_REACTION_ANIMS,FALSE) // CLEAR_AREA(GET_ENTITY_COORDS(PLAYER_PED_ID()), 2.0, TRUE) // CLEAR_AREA_OF_PROJECTILES(GET_ENTITY_COORDS(PLAYER_PED_ID()), 2.0) // //AF_PRIORITY_HIGH SET_PLAYER_CONTROL(PLAYER_ID(), FALSE) TASK_SYNCHRONIZED_SCENE(PLAYER_PED_ID(), iSyncSceneID, sAnim.strDict, sAnim.strAnim, INSTANT_BLEND_IN, INSTANT_BLEND_OUT) PLAY_SYNCHRONIZED_CAM_ANIM(camSyncScene, iSyncSceneID, sAnim.strCamAnim, sAnim.strDict) SET_SYNCHRONIZED_SCENE_PHASE(iSyncSceneID,0.1) RENDER_SCRIPT_CAMS(TRUE, FALSE) IF NOT IS_AUDIO_SCENE_ACTIVE("PEYOTE_TRANSITION_IN_SCENE") START_AUDIO_SCENE("PEYOTE_TRANSITION_IN_SCENE") ENDIF IF LOAD_STREAM("PEYOTE_TRANSITION_IN") PLAY_STREAM_FRONTEND() ENDIF SET_BIT(iStateBitset, BIT_STARTED_TRANSFORM_IN_ANIMATION) ENDIF ELIF NOT IS_BIT_SET(iStateBitset, BIT_ENDED_TRANSFORM_IN_ANIMATION) IF HAS_ANIM_EVENT_FIRED(PLAYER_PED_ID(), GET_HASH_KEY("Create_Peyote")) CPRINTLN(DEBUG_ANIMAL_MODE, "Create_Peyote!!!!") IF NOT DOES_ENTITY_EXIST(oChunky) oChunky = CREATE_OBJECT(chunkyModel, vPickupPos[eTriggeredType][iTriggeredIndex]) SET_MODEL_AS_NO_LONGER_NEEDED(chunkyModel) ENDIF ENDIF IF DOES_ENTITY_EXIST(oChunky) IF NOT IS_ENTITY_ATTACHED(oChunky) ATTACH_ENTITY_TO_ENTITY(oChunky, PLAYER_PED_ID(), GET_PED_BONE_INDEX(PLAYER_PED_ID(), BONETAG_PH_R_HAND), <<0,0,0>>, <<0,0,0>>) ENDIF ENDIF IF HAS_ANIM_EVENT_FIRED(PLAYER_PED_ID(), GET_HASH_KEY("Destroy_Peyote")) CPRINTLN(DEBUG_ANIMAL_MODE, "Destroy_Peyote !!!!") IF DOES_ENTITY_EXIST(oChunky) IF IS_ENTITY_ATTACHED(oChunky) DETACH_ENTITY(oChunky) DELETE_OBJECT(oChunky) ANIMPOSTFX_PLAY("PeyoteIn", 0, FALSE) myTimer = GET_GAME_TIMER() + 10000 CPRINTLN(DEBUG_ANIMAL_MODE, "Starting fade out during transform in animation.") SET_BIT(iStateBitset, BIT_ENDED_TRANSFORM_IN_ANIMATION) ENDIF ENDIF ENDIF ENDIF IF IS_BIT_SET(iStateBitset, BIT_ENDED_TRANSFORM_IN_ANIMATION) IF NOT IS_BIT_SET(iStateBitset, BIT_RAGDOLLED_TRANSFORM_IN_ANIMATION) IF HAS_ANIM_EVENT_FIRED(PLAYER_PED_ID(), GET_HASH_KEY("Ragdoll")) CPRINTLN(DEBUG_ANIMAL_MODE, "Ragdolling transform in animation.") SET_PED_TO_RAGDOLL(PLAYER_PED_ID(),4000,5000,TASK_NM_SCRIPT,TRUE,TRUE,FALSE) CREATE_NM_MESSAGE(NM_START_START, NM_RELAX_MSG) GIVE_PED_NM_MESSAGE(PLAYER_PED_ID()) SET_BIT(iStateBitset, BIT_RAGDOLLED_TRANSFORM_IN_ANIMATION) ENDIF ENDIF IF ANIMPOSTFX_IS_RUNNING("PeyoteIn") AND GET_GAME_TIMER() > myTimer-9750 IF (eTriggeredType = APT_HIGHLAND AND iTriggeredIndex = 3) OR (eTriggeredType = APT_LOWLAND AND iTriggeredIndex = 2) CPRINTLN(DEBUG_ANIMAL_MODE, "Disable shake cam.") ELSE UPDATE_SHAKE_CAMERA() //NOT IF: highland 3 B*-2058353 ENDIF ENDIF IF ANIMPOSTFX_IS_RUNNING("PeyoteIn") AND GET_GAME_TIMER() > myTimer-500 IF NOT drawRect INIT_DRAW_WHITE_RECT_FADE_IN() ENDIF ENDIF IF HAS_MODEL_LOADED(eAnimalModel) IF IS_PLAYER_PLAYING(PLAYER_ID()) IF ANIMPOSTFX_IS_RUNNING("PeyoteIn") AND GET_GAME_TIMER() > myTimer IF IS_SYNCHRONIZED_SCENE_RUNNING(iSyncSceneID) CLEAR_PED_TASKS_IMMEDIATELY(PLAYER_PED_ID()) REMOVE_ANIM_DICT(sAnim.strDict) ENDIF IF NOT IS_NEW_LOAD_SCENE_ACTIVE() CDEBUG1LN(DEBUG_ANIMAL_MODE, "Starting new load scene.") SET_ENTITY_COORDS(PLAYER_PED_ID(), vSpawnPos[eTriggeredType][iTriggeredIndex]) SET_ENTITY_HEADING(PLAYER_PED_ID(), fSpawnHead[eTriggeredType][iTriggeredIndex]) NEW_LOAD_SCENE_START(vSpawnPos[eTriggeredType][iTriggeredIndex],<<0,0,fSpawnHead[eTriggeredType][iTriggeredIndex]>>,1000.0) iLoadSceneTimer = GET_GAME_TIMER() ELIF IS_NEW_LOAD_SCENE_LOADED() OR (GET_GAME_TIMER() - iLoadSceneTimer) > ANIMAL_MODE_LOAD_SCENE_TIMEOUT IF NOT IS_AUTOSAVE_REQUEST_IN_PROGRESS() //Wait 1 second for the animal to settle before fading in. IF iFadeInTimer = -1 CDEBUG1LN(DEBUG_ANIMAL_MODE, "Starting fade-in timer.") iFadeInTimer = GET_GAME_TIMER() //Reset mask IF bWearingMask SET_PED_VARIATIONS(PLAYER_PED_ID(), sPedVariations) bWearingMask = FALSE ENDIF //reset scuba gear IF bWearingScubaGear SET_PED_SCUBA_GEAR_VARIATION(PLAYER_PED_ID()) bWearingScubaGear = FALSE ENDIF //Store the player's state so we can reinstate it later. Store_Game_State_Snapshot_For_Start("animal_controller", TRUE) //Remember the wanted level the player had in case they die and lose it. iTriggeredWantedLevel = GET_PLAYER_WANTED_LEVEL(PLAYER_ID()) //Remember the camera view the player was using. eTriggeredCameraView = GET_FOLLOW_PED_CAM_VIEW_MODE() SET_PLAYER_CONTROL(PLAYER_ID(), FALSE) SET_GAMEPLAY_CAM_RELATIVE_HEADING() SET_GAMEPLAY_CAM_RELATIVE_PITCH(fSpawnPitch[eTriggeredType][iTriggeredIndex]) //Swap the model out. SET_PLAYER_MODEL(PLAYER_ID(), eAnimalModel) //Configure animal's variations. AnimalVariationData sVariations SET_PED_DEFAULT_COMPONENT_VARIATION(PLAYER_PED_ID()) Get_Number_Of_Variations_For_Animal(sVariations, eTriggeredAnimal) INT iLeg = GET_RANDOM_INT_IN_RANGE(0, sVariations.iLeg) Manage_Dialogue_Model_Change(iLeg) SET_PED_COMPONENT_VARIATION(PLAYER_PED_ID(), PED_COMP_HEAD, 0, GET_RANDOM_INT_IN_RANGE(0, sVariations.iHead), 0) SET_PED_COMPONENT_VARIATION(PLAYER_PED_ID(), PED_COMP_TORSO, 0, GET_RANDOM_INT_IN_RANGE(0, sVariations.iTorso), 0) SET_PED_COMPONENT_VARIATION(PLAYER_PED_ID(), PED_COMP_LEG, 0, iLeg, 0) //Tell code we're now an animal. SET_PLAYER_IS_IN_ANIMAL_FORM(TRUE) Activate_Animal_Restricted_State(Get_Animal_Model_From_Pickup_Enum(eTriggeredAnimal)) Toggle_Animal_Respawn_Conditions(TRUE) CLEAR_AREA(vSpawnPos[eTriggeredType][iTriggeredIndex], ANIMAL_PICKUP_CLEAR_AREA_DIST, TRUE) IF IS_ENTITY_ALIVE( PLAYER_PED_ID() ) SET_PED_CAN_RAGDOLL( PLAYER_PED_ID(), FALSE ) SET_ENTITY_INVINCIBLE( PLAYER_PED_ID(), TRUE ) ENDIF SET_ENTITY_COORDS(PLAYER_PED_ID(), vSpawnPos[eTriggeredType][iTriggeredIndex]) SET_ENTITY_HEADING(PLAYER_PED_ID(), fSpawnHead[eTriggeredType][iTriggeredIndex]) //stop procedural generation stuff, animal spawn Attempt_Create_Cullsphere(iCullSphereAnimalSpawn,vSpawnPos[eTriggeredType][iTriggeredIndex],CULL_SPHERE_SIZE) RENDER_SCRIPT_CAMS(FALSE, FALSE) DESTROY_CAM(camSyncScene) SET_BIT(iStateBitset, BIT_ANIMAL_CONTROL_PLAYING_AS_ANIMAL) iClearupPickupIndex = -1 ELIF (GET_GAME_TIMER() - iFadeInTimer) > 250 IF HAVE_ALL_STREAMING_REQUESTS_COMPLETED(PLAYER_PED_ID()) CDEBUG1LN(DEBUG_ANIMAL_MODE, "Fade-in timer finished. Ending transition.") NEW_LOAD_SCENE_STOP() IF eTriggeredCameraView = CAM_VIEW_MODE_THIRD_PERSON_FAR OR Get_Animal_Type(eTriggeredAnimal) = APT_HIGHLAND SET_FOLLOW_PED_CAM_VIEW_MODE(CAM_VIEW_MODE_THIRD_PERSON_FAR) ELSE SET_FOLLOW_PED_CAM_VIEW_MODE(CAM_VIEW_MODE_THIRD_PERSON) ENDIF SET_GAMEPLAY_CAM_RELATIVE_HEADING() SET_GAMEPLAY_CAM_RELATIVE_PITCH(fSpawnPitch[eTriggeredType][iTriggeredIndex]) SET_PLAYER_CONTROL(PLAYER_ID(), TRUE) SET_MODEL_AS_NO_LONGER_NEEDED(eAnimalModel) REMOVE_ANIM_DICT(sAnim.strDict) CLEAR_BIT(iStateBitset, BIT_SELECTED_TRANSFORM_IN_DATA) CLEAR_BIT(iStateBitset, BIT_STARTED_TRANSFORM_IN_ANIMATION) CLEAR_BIT(iStateBitset, BIT_ENDED_TRANSFORM_IN_ANIMATION) CLEAR_BIT(iStateBitset, BIT_RAGDOLLED_TRANSFORM_IN_ANIMATION) SET_ANIMAL_MOOD(PLAYER_PED_ID(), AUD_ANIMAL_MOOD_PLAYFUL) Start_Animal_Audio_Scene(eTriggeredAnimal) IF NOT IS_STRING_NULL_OR_EMPTY(sAnim.strIdleDict) TASK_PLAY_ANIM(PLAYER_PED_ID(), sAnim.strIdleDict, sAnim.strIdleAnim,INSTANT_BLEND_IN) ENDIF INIT_DRAW_WHITE_RECT_FADE_OUT() ANIMPOSTFX_STOP("PeyoteIn") ANIMPOSTFX_PLAY("PeyoteOut", 0, FALSE) TRIGGER_MUSIC_EVENT("PEYOTE_TRIPS_START") IF NOT IS_STRING_NULL_OR_EMPTY(currentConversation) STRING sPlayer INT iPlayer SWITCH eLastPlayerCharacter CASE CHAR_MICHAEL sPlayer = "MICHAEL" iPlayer = 0 BREAK CASE CHAR_FRANKLIN sPlayer = "FRANKLIN" iPlayer = 1 BREAK CASE CHAR_TREVOR sPlayer = "TREVOR" iPlayer = 1 BREAK ENDSWITCH ADD_PED_FOR_DIALOGUE(sConversationPeds,iPlayer,PLAYER_PED_ID(),sPlayer,FALSE,FALSE) ELSE SET_BIT(iStateBitset,BIT_CONVERSATION_STARTED) ENDIF iFadeInTimer = -1 SET_SCRIPTS_SAFE_FOR_CUTSCENE(FALSE) IF IS_ENTITY_ALIVE ( PLAYER_PED_ID() ) SET_PED_CAN_RAGDOLL( PLAYER_PED_ID(), TRUE ) SET_ENTITY_INVINCIBLE( PLAYER_PED_ID(), FALSE ) ENDIF RETURN TRUE ELSE CDEBUG1LN(DEBUG_ANIMAL_MODE, "Waiting for player streaming requests to finish before fading in.") ENDIF ENDIF ELSE CDEBUG1LN(DEBUG_ANIMAL_MODE, "Waiting for autosave request to finish before switching model to animal..") ENDIF ELSE CDEBUG1LN(DEBUG_ANIMAL_MODE, "Waiting for new load scene before switching model to animal.") ENDIF ELSE CDEBUG1LN(DEBUG_ANIMAL_MODE, "Waiting for screen to be faded before switching model to animal.") ENDIF ELSE CDEBUG1LN(DEBUG_ANIMAL_MODE, "Waiting for player to be playing before switching model to animal.") ENDIF ELSE CDEBUG1LN(DEBUG_ANIMAL_MODE, "Waiting for model to load before switching model to animal.") ENDIF ENDIF RETURN FALSE ENDFUNC PROC Preload_Character_Model_For_Character(enumCharacterList paramCharacter) IF IS_PLAYER_PED_PLAYABLE(paramCharacter) IF IS_BIT_SET(iStateBitset, BIT_ANIMAL_CONTROL_LOADED_PLAYER_MODEL) CPRINTLN(DEBUG_ANIMAL_MODE, "Discarding old preloaded character model for ", GET_PLAYER_PED_STRING(eLastPlayerCharacter), ".") SET_MODEL_AS_NO_LONGER_NEEDED(GET_PLAYER_PED_MODEL(eLastPlayerCharacter)) ENDIF eLastPlayerCharacter = paramCharacter REQUEST_MODEL(GET_PLAYER_PED_MODEL(eLastPlayerCharacter)) CPRINTLN(DEBUG_ANIMAL_MODE, "Preloading player model for ", GET_PLAYER_PED_STRING(eLastPlayerCharacter), ".") SET_BIT(iStateBitset, BIT_ANIMAL_CONTROL_LOADED_PLAYER_MODEL) ELSE SCRIPT_ASSERT("Preload_Character_Model_For_Character: Tried to preload a character model that was not a SP story character.") ENDIF ENDPROC PROC Check_For_Peyote_Progression_Completion() CDEBUG3LN(DEBUG_ANIMAL_MODE, "Checking for peyote progression completion...") INT iTypeIndex INT iPickupIndex REPEAT APT_SECRET iTypeIndex REPEAT Get_Number_Of_Animal_Pickups_Of_Type(INT_TO_ENUM(AnimalPickupType, iTypeIndex)) iPickupIndex IF NOT IS_BIT_SET(g_savedGlobals.sAmbient.iPeyotePickupOfTypeFound[iTypeIndex], iPickupIndex) CDEBUG3LN(DEBUG_ANIMAL_MODE, "Peyote progression not complete. ", Debug_Get_Pickup_Type_String_From_Enum(INT_TO_ENUM(AnimalPickupType, iTypeIndex)), "[", iPickupIndex, "] has not been collected yet.") EXIT ENDIF ENDREPEAT ENDREPEAT CPRINTLN(DEBUG_ANIMAL_MODE, "All initial peyote pickups found. Peyote progression has been completed!") g_savedGlobals.sAmbient.bPeyoteProgressionComplete = TRUE Update_Next_Animal_Pickups() //reset animal pickups, avoids issue of spawning as (0) boar everywhere MAKE_AUTOSAVE_REQUEST() ENDPROC PROC Animal_Mode_Normal_Exit() ANIMPOSTFX_PLAY("PeyoteEndIn", 0, FALSE) IF NOT IS_AUDIO_SCENE_ACTIVE("PEYOTE_TRANSITION_OUT_SCENE") START_AUDIO_SCENE("PEYOTE_TRANSITION_OUT_SCENE") ENDIF IF LOAD_STREAM("PEYOTE_TRANSITION_OUT") PLAY_STREAM_FRONTEND() ENDIF myTimer = GET_GAME_TIMER() + 2500 SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE) KILL_FACE_TO_FACE_CONVERSATION() ENDPROC PROC Run_Animal_Controller_Respawn_After_Death_Arrest() CPRINTLN(DEBUG_ANIMAL_MODE, "Running respawn routine for the animal controller.") //Failsafe for animal dying on spawn to stop post fx and return player to not invicible. B* 2468768 IF eState != ACS_SWITCHING_FROM_ANIMAL ANIMPOSTFX_STOP_ALL() ENDIF IF IS_ENTITY_ALIVE( PLAYER_PED_ID() ) SET_PED_CAN_RAGDOLL( PLAYER_PED_ID(), TRUE ) SET_ENTITY_INVINCIBLE( PLAYER_PED_ID(), FALSE ) ENDIF IF NOT ANIMPOSTFX_IS_RUNNING("PeyoteEndIn") ANIMPOSTFX_PLAY("PeyoteEndIn", 0, FALSE) IF NOT IS_AUDIO_SCENE_ACTIVE("PEYOTE_TRANSITION_OUT_SCENE") START_AUDIO_SCENE("PEYOTE_TRANSITION_OUT_SCENE") ENDIF IF LOAD_STREAM("PEYOTE_TRANSITION_OUT") PLAY_STREAM_FRONTEND() ENDIF myTimer = GET_GAME_TIMER() + 2500 CPRINTLN(DEBUG_ANIMAL_MODE, "Starting to fade screen out.") //DO_SCREEN_FADE_OUT(DEFAULT_FADE_TIME) ENDIF SET_SCRIPTS_SAFE_FOR_CUTSCENE(TRUE) WHILE GET_GAME_TIMER() < myTimer IF GET_GAME_TIMER() > myTimer-500 IF NOT drawRect INIT_DRAW_WHITE_RECT_FADE_IN() ENDIF DRAW_WHITE_RECT() ENDIF CDEBUG3LN(DEBUG_ANIMAL_MODE, "Waiting for screen to fade out.") Update_Animal_Restricted_State(Get_Animal_Model_From_Pickup_Enum(eTriggeredAnimal),wantedTimer) WAIT(0) ENDWHILE //Clean up any pickups we've created. INT iTypeIndex, iPickupIndex REPEAT APT_COUNT iTypeIndex REPEAT Get_Number_Of_Animal_Pickups_Of_Type(INT_TO_ENUM(AnimalPickupType, iTypeIndex)) iPickupIndex IF DOES_ENTITY_EXIST(oPickup[iTypeIndex][iPickupIndex]) CDEBUG1LN(DEBUG_ANIMAL_MODE, "Removing pickup for ", Debug_Get_Pickup_Type_String_From_Enum(INT_TO_ENUM(AnimalPickupType, iTypeIndex)), "[", iPickupIndex, "].") DELETE_OBJECT(oPickup[iTypeIndex][iPickupIndex]) //allow procedural generation stuff Attempt_Remove_CullSphere(iCullSpherePeyoteCollect) ENDIF ENDREPEAT ENDREPEAT SET_MODEL_AS_NO_LONGER_NEEDED(PROP_PEYOTE_LOWLAND_01) SET_MODEL_AS_NO_LONGER_NEEDED(PROP_PEYOTE_LOWLAND_02) SET_MODEL_AS_NO_LONGER_NEEDED(PROP_PEYOTE_HIGHLAND_01) SET_MODEL_AS_NO_LONGER_NEEDED(PROP_PEYOTE_HIGHLAND_02) SET_MODEL_AS_NO_LONGER_NEEDED(PROP_PEYOTE_WATER_01) SET_MODEL_AS_NO_LONGER_NEEDED(PROP_PEYOTE_GOLD_01) BOOL ignoreRestart = FALSE WHILE NOT IS_PLAYER_PLAYING(PLAYER_ID()) CPRINTLN(DEBUG_ANIMAL_MODE, "Waiting for player to be alive again.") IF NOT ignoreRestart CPRINTLN(DEBUG_ANIMAL_MODE, "IGNORE_NEXT_RESTART(TRUE), PAUSE_DEATH_ARREST_RESTART(FALSE)") IGNORE_NEXT_RESTART(TRUE) PAUSE_DEATH_ARREST_RESTART(FALSE) ignoreRestart = TRUE ENDIF DRAW_WHITE_RECT() WAIT(0) ENDWHILE iFadeInTimer = -1 eState = ACS_SWITCHING_FROM_ANIMAL CPRINTLN(DEBUG_ANIMAL_MODE, "Animal respawn done.") ENDPROC PROC Update_Pickups_Found_Stat() CPRINTLN(DEBUG_ANIMAL_MODE, "Updating number of peyote pickups found stat.") INT iTypeIndex, iPickupIndex INT iPickupsFound = 0 REPEAT (ENUM_TO_INT(APT_COUNT) - 1) iTypeIndex REPEAT Get_Number_Of_Animal_Pickups_Of_Type(INT_TO_ENUM(AnimalPickupType, iTypeIndex)) iPickupIndex IF IS_BIT_SET(g_savedGlobals.sAmbient.iPeyotePickupOfTypeFound[iTypeIndex], iPickupIndex) CDEBUG1LN(DEBUG_ANIMAL_MODE, "Peyote pickup ", Debug_Get_Pickup_Type_String_From_Enum(INT_TO_ENUM(AnimalPickupType, iTypeIndex)), "[", iPickupIndex, "] has been collected.") iPickupsFound++ ENDIF ENDREPEAT ENDREPEAT CPRINTLN(DEBUG_ANIMAL_MODE, "Counted ", iPickupsFound, " pickups as found. Updating NUM_HIDDEN_PACKAGES_5.") STAT_SET_INT(NUM_HIDDEN_PACKAGES_5, iPickupsFound) ENDPROC FUNC BOOL Has_Player_Triggered_Peyote(INT paramTypeIndex, INT paramPickupIndex) IF DOES_ENTITY_EXIST(oPickup[paramTypeIndex][paramPickupIndex]) IF NOT IS_PED_INJURED(PLAYER_PED_ID()) AND NOT IS_PED_IN_ANY_VEHICLE(PLAYER_PED_ID(),TRUE) AND NOT IS_CUSTOM_MENU_ON_SCREEN() AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) AND NOT HAS_DIRECTOR_MODE_BEEN_LAUNCHED_BY_CODE() VECTOR vTriggerPos = vPickupPos[paramTypeIndex][paramPickupIndex] vTriggerPos.z += 0.8 FLOAT triggerDistSqr = ANIMAL_PICKUP_TRIGGER_DIST_SQR IF paramTypeIndex = 2 //underwater triggerDistSqr = ANIMAL_PICKUP_TRIGGER_DIST_SQR_LARGE ENDIF #IF IS_DEBUG_BUILD FLOAT triggerDist = ANIMAL_PICKUP_TRIGGER_DIST IF paramTypeIndex = 2 //underwater triggerDist = ANIMAL_PICKUP_TRIGGER_DIST_LARGE ENDIF #ENDIF #IF IS_DEBUG_BUILD IF bDebugDisplayTriggerZones DRAW_DEBUG_SPHERE(vTriggerPos, triggerDist, 0, 0, 255, 75) ENDIF #ENDIF IF ARE_VECTORS_EQUAL(vPossibleTrigger,<<0,0,0>>) vPossibleTrigger = vTriggerPos ENDIF IF ARE_VECTORS_EQUAL(vPossibleTrigger,vTriggerPos) IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), vPossibleTrigger) < triggerDistSqr IF contextId = -1 REGISTER_CONTEXT_INTENTION(contextId,CP_LOW_PRIORITY,"PEY_PICKUP") ELSE IF HAS_CONTEXT_BUTTON_TRIGGERED(contextId) RELEASE_CONTEXT_INTENTION(contextId) vPossibleTrigger = <<0,0,0>> RETURN TRUE ENDIF ENDIF ELSE IF contextId != -1 RELEASE_CONTEXT_INTENTION(contextId) CPRINTLN(DEBUG_ANIMAL_MODE,"RELEASE IT") ENDIF vPossibleTrigger = <<0,0,0>> ENDIF ELSE IF VDIST2(GET_ENTITY_COORDS(PLAYER_PED_ID()), vPossibleTrigger) > fPickupSpawnDistSqr IF contextId != -1 RELEASE_CONTEXT_INTENTION(contextId) CPRINTLN(DEBUG_ANIMAL_MODE,"RELEASE IT") ENDIF vPossibleTrigger = <<0,0,0>> ENDIF ENDIF ENDIF ENDIF RETURN FALSE ENDFUNC PROC Script_Cleanup() CPRINTLN(DEBUG_ANIMAL_MODE, "Animal controller is cleaning up.") //Clean up any pickups we've created. INT iTypeIndex, iPickupIndex REPEAT APT_COUNT iTypeIndex REPEAT Get_Number_Of_Animal_Pickups_Of_Type(INT_TO_ENUM(AnimalPickupType, iTypeIndex)) iPickupIndex IF DOES_ENTITY_EXIST(oPickup[iTypeIndex][iPickupIndex]) CDEBUG1LN(DEBUG_ANIMAL_MODE, "Removing pickup for ", Debug_Get_Pickup_Type_String_From_Enum(INT_TO_ENUM(AnimalPickupType, iTypeIndex)), "[", iPickupIndex, "].") DELETE_OBJECT(oPickup[iTypeIndex][iPickupIndex]) //allow procedural generation stuff Attempt_Remove_CullSphere(iCullSpherePeyoteCollect) ENDIF ENDREPEAT ENDREPEAT IF IS_PLAYER_PLAYING(PLAYER_ID()) IF IS_BIT_SET(iStateBitset, BIT_ANIMAL_CONTROL_PLAYING_AS_ANIMAL) Switch_To_Player_Cleanup() ENDIF ENDIF //Reset mask if needed IF bWearingMask SET_PED_VARIATIONS(PLAYER_PED_ID(), sPedVariations) ENDIF //reset scuba gear if needed IF bWearingScubaGear SET_PED_SCUBA_GEAR_VARIATION(PLAYER_PED_ID()) bWearingScubaGear = FALSE ENDIF //Deactivate this again to make sure the state is cleared. // Deactivate_Animal_Restricted_State() // Toggle_Animal_Respawn_Conditions(FALSE) IF g_iAnimalShockingEvent != 0 REMOVE_SHOCKING_EVENT(g_iAnimalShockingEvent) ENDIF //Ensure all pickup models are out of memory. SET_MODEL_AS_NO_LONGER_NEEDED(PROP_PEYOTE_LOWLAND_01) SET_MODEL_AS_NO_LONGER_NEEDED(PROP_PEYOTE_LOWLAND_02) SET_MODEL_AS_NO_LONGER_NEEDED(PROP_PEYOTE_HIGHLAND_01) SET_MODEL_AS_NO_LONGER_NEEDED(PROP_PEYOTE_HIGHLAND_02) SET_MODEL_AS_NO_LONGER_NEEDED(PROP_PEYOTE_WATER_01) SET_MODEL_AS_NO_LONGER_NEEDED(PROP_PEYOTE_GOLD_01) IF IS_BIT_SET(iStateBitset, BIT_ANIMAL_CONTROL_LOADED_PLAYER_MODEL) CPRINTLN(DEBUG_ANIMAL_MODE, "Discarding preloaded character model for ", GET_PLAYER_PED_STRING(eLastPlayerCharacter), ".") SET_MODEL_AS_NO_LONGER_NEEDED(GET_PLAYER_PED_MODEL(eLastPlayerCharacter)) CLEAR_BIT(iStateBitset, BIT_ANIMAL_CONTROL_LOADED_PLAYER_MODEL) ENDIF IF iCandidateID != NO_CANDIDATE_ID CPRINTLN(DEBUG_ANIMAL_MODE, "Cleaning up the animal mode mission state.") Deactivate_Animal_Restricted_State() Toggle_Animal_Respawn_Conditions(FALSE) Mission_Over(iCandidateID) ENDIF IF iPickupSoundID != -1 CPRINTLN(DEBUG_ANIMAL_MODE, "Stopping sound ", sSound.strSound, " as script cleans up.") STOP_SOUND(iPickupSoundID) RELEASE_SOUND_ID(iPickupSoundID) iPickupSoundID = -1 ENDIF IF NOT IS_STRING_NULL_OR_EMPTY(sSound.strBank) IF NOT ARE_STRINGS_EQUAL(sSound.strBank, "NONE") CPRINTLN(DEBUG_ANIMAL_MODE, "Releasing currently loaded script audio bank ", sSound.strBank, " as script cleans up.") RELEASE_NAMED_SCRIPT_AUDIO_BANK(sSound.strBank) ENDIF ENDIF IF contextId != -1 RELEASE_CONTEXT_INTENTION(contextId) ENDIF //Enable stats IF NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) AND NOT HAS_DIRECTOR_MODE_BEEN_LAUNCHED_BY_CODE() STAT_ENABLE_STATS_TRACKING() ENDIF iClearupPickupIndex = -1 STOP_AUDIO_SCENES() RESET_SCENARIO_TYPES_ENABLED() IF NOT IS_STRING_NULL_OR_EMPTY(currentConversation) KILL_FACE_TO_FACE_CONVERSATION() currentConversation = "" ENDIF IF NOT IS_STRING_NULL_OR_EMPTY(sAnim.strBarkDict) REMOVE_ANIM_DICT(sAnim.strBarkDict) ENDIF IF NOT IS_STRING_NULL_OR_EMPTY(sAnim.strIdleDict) REMOVE_ANIM_DICT(sAnim.strIdleDict) ENDIF IF NOT IS_STRING_NULL_OR_EMPTY(sAnim.strDict) REMOVE_ANIM_DICT(sAnim.strDict) ENDIF SET_SCRIPTS_SAFE_FOR_CUTSCENE(FALSE,DEFAULT,FALSE) RENDER_SCRIPT_CAMS(FALSE, FALSE) IF DOES_CAM_EXIST(camSyncScene) DESTROY_CAM(camSyncScene) ENDIF ALLOW_DIALOGUE_IN_WATER(FALSE) SET_AUDIO_FLAG("DisableReplayScriptStreamRecording", FALSE) CPRINTLN(DEBUG_ANIMAL_MODE, "Animal controller terminating.") TERMINATE_THIS_THREAD() ENDPROC PROC Set_Current_Peyote_Uncollected IF NOT g_savedGlobals.sAmbient.bPeyoteProgressionComplete AND iClearupPickupIndex != -1 AND iClearupPickupIndex = iTriggeredIndex IF IS_BIT_SET(g_savedGlobals.sAmbient.iPeyotePickupOfTypeFound[eTriggeredType], iClearupPickupIndex) CPRINTLN(DEBUG_ANIMAL_MODE, "cleanup occurred before animal transformation, set current peyote to uncollected") CPRINTLN(DEBUG_ANIMAL_MODE, "Clearing bit ", Debug_Get_Pickup_Type_String_From_Enum(eTriggeredType), "[", iClearupPickupIndex, "] set to animal ", Debug_Get_Animal_String_From_Pickup_Enum(eTriggeredAnimal),".") CLEAR_BIT(g_savedGlobals.sAmbient.iPeyotePickupOfTypeFound[eTriggeredType], iClearupPickupIndex) CLEAR_BIT(g_savedGlobals.sAmbient.iPeyoteAnimalSeen, iNextPickupAnimal[eTriggeredType]) STAT_GET_INT(NUM_HIDDEN_PACKAGES_5,data) data-- STAT_SET_INT(NUM_HIDDEN_PACKAGES_5, data) ENDIF ENDIF ENDPROC #IF FEATURE_SP_DLC_DIRECTOR_MODE BOOL bDMUnlockedPreviously = FALSE #ENDIF SCRIPT CPRINTLN(DEBUG_ANIMAL_MODE, "Animal controller started running.") IF IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) OR HAS_DIRECTOR_MODE_BEEN_LAUNCHED_BY_CODE() CPRINTLN(DEBUG_ANIMAL_MODE, "Kill Animal controller, director mode active.") TERMINATE_THIS_THREAD() ENDIF #IF IS_DEBUG_BUILD Debug_Create_Widget() #ENDIF Initialise_Pickup_Data() Set_All_Pickup_Leave_Area_Flags() Update_Next_Animal_Pickups() g_iAnimalShockingEvent = 0 g_iAnimalWaterTimer = -1 bLoadingPickup = FALSE SET_AUDIO_FLAG("DisableReplayScriptStreamRecording", TRUE) WHILE TRUE IF NOT bForceCleanupSetup CPRINTLN(DEBUG_ANIMAL_MODE, "Setting up new force cleanup.") bForceCleanupSetup = TRUE IF HAS_FORCE_CLEANUP_OCCURRED(FORCE_CLEANUP_FLAG_SP_TO_MP|FORCE_CLEANUP_FLAG_REPEAT_PLAY|FORCE_CLEANUP_FLAG_DEBUG_MENU) Set_Current_Peyote_Uncollected() //Failsafe for animal dying on spawn to stop post fx and return player to not invicible. B* 2468768 ANIMPOSTFX_STOP_ALL() IF IS_ENTITY_ALIVE( PLAYER_PED_ID() ) SET_PED_CAN_RAGDOLL( PLAYER_PED_ID(), TRUE ) SET_ENTITY_INVINCIBLE( PLAYER_PED_ID(), FALSE ) ENDIF CPRINTLN(DEBUG_ANIMAL_MODE, "Animal controller cleaning up due to force cleanup.") Script_Cleanup() iClearupPickupIndex = -1 ENDIF ENDIF //Special processing of death/arrest in a different context IF g_bAnimalControllerFakeDeath OR NOT IS_PLAYER_PLAYING(PLAYER_ID()) CPRINTLN(DEBUG_ANIMAL_MODE, "Detected player died while in animal mode (g_bAnimalControllerFakeDeath: ",g_bAnimalControllerFakeDeath,")") g_bAnimalControllerFakeDeath = FALSE IF IS_BIT_SET(iStateBitset, BIT_ANIMAL_CONTROL_PLAYING_AS_ANIMAL) CPRINTLN(DEBUG_ANIMAL_MODE, "Animal controller running respawn routine after death/arrest while animal.") Run_Animal_Controller_Respawn_After_Death_Arrest() iClearupPickupIndex = -1 ELSE //If cleanup occurred before animal transformation, set current peyote to uncollected Set_Current_Peyote_Uncollected() //Failsafe for animal dying on spawn to stop post fx and return player to not invicible. B* 2468768 ANIMPOSTFX_STOP_ALL() IF IS_ENTITY_ALIVE( PLAYER_PED_ID() ) SET_PED_CAN_RAGDOLL( PLAYER_PED_ID(), TRUE ) SET_ENTITY_INVINCIBLE( PLAYER_PED_ID(), FALSE ) ENDIF CPRINTLN(DEBUG_ANIMAL_MODE, "Animal controller cleaning up due to force cleanup.") Script_Cleanup() iClearupPickupIndex = -1 ENDIF ENDIF #IF IS_DEBUG_BUILD Debug_Update_Widget() IF bDebugPeyoteKillController g_iDebugPeyoteBlockControllerUntil = GET_GAME_TIMER() + 8000 CPRINTLN(DEBUG_ANIMAL_MODE, "Animal controller cleaning up due to debug widget.") Script_Cleanup() ENDIF #ENDIF Update_Leave_Area_Flags() Update_Pickup_Spawning() //Check if another mission launches that we can't launch over. If so clean up. IF (NOT CAN_MISSION_TYPE_START_AGAINST_CURRENT_TYPE(MISSION_TYPE_ANIMAL) AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_ANIMAL) AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) AND NOT IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_SWITCH)) OR (IS_CURRENTLY_ON_MISSION_OF_TYPE(MISSION_TYPE_DIRECTOR) OR HAS_DIRECTOR_MODE_BEEN_LAUNCHED_BY_CODE()) CPRINTLN(DEBUG_ANIMAL_MODE, "Animal controller cleaning up due to mission launching.") Script_Cleanup() ENDIF //Keep the player's current story character model preloaded at all times. //Allows us to switch back quickly if we need to clean up fast. enumCharacterList eCurrentPlayer = GET_PLAYER_PED_ENUM(PLAYER_PED_ID()) IF eCurrentPlayer != NO_CHARACTER IF eCurrentPlayer != eLastPlayerCharacter Preload_Character_Model_For_Character(eCurrentPlayer) ENDIF ENDIF //Main state machine. SWITCH eState CASE ACS_INITIALISING IF IS_BIT_SET(iStateBitset, BIT_ANIMAL_CONTROL_LOADED_PLAYER_MODEL) IF HAS_MODEL_LOADED(GET_PLAYER_PED_MODEL(eLastPlayerCharacter)) CPRINTLN(DEBUG_ANIMAL_MODE, "Starting to wait for pickup.") eState = ACS_WAIT_FOR_PICKUP ENDIF ENDIF BREAK CASE ACS_WAIT_FOR_PICKUP INT iTypeIndex, iPickupIndex REPEAT APT_COUNT iTypeIndex INT iTypeCount iTypeCount = Get_Number_Of_Animal_Pickups_Of_Type(INT_TO_ENUM(AnimalPickupType, iTypeIndex)) REPEAT iTypeCount iPickupIndex IF eState = ACS_WAIT_FOR_PICKUP IF Has_Player_Triggered_Peyote(iTypeIndex, iPickupIndex) eTriggeredAnimal = INT_TO_ENUM(AnimalPickup, iNextPickupAnimal[iTypeIndex]) eTriggeredType = INT_TO_ENUM(AnimalPickupType, iTypeIndex) iTriggeredIndex = iPickupIndex CPRINTLN(DEBUG_ANIMAL_MODE, "Player triggered pickup ", Debug_Get_Pickup_Type_String_From_Enum(eTriggeredType), "[", iTriggeredIndex, "] set to animal ", Debug_Get_Animal_String_From_Pickup_Enum(eTriggeredAnimal),".") IF NOT g_savedGlobals.sAmbient.bPeyoteProgressionComplete SET_BIT(g_savedGlobals.sAmbient.iPeyotePickupOfTypeFound[iTypeIndex], iPickupIndex) SET_BIT(g_savedGlobals.sAmbient.iPeyoteAnimalSeen, iNextPickupAnimal[iTypeIndex]) iClearupPickupIndex = iPickupIndex Update_Pickups_Found_Stat() ENDIF // Silently unlock the animal in Director Mode. We'll // display the feed message as we come out of animal form. #IF FEATURE_SP_DLC_DIRECTOR_MODE eUnlockAnimal = PRIVATE_Get_Director_Animal_Unlock_From_Animal_Pickup( eTriggeredAnimal ) bDMUnlockedPreviously = IS_BIT_SET( g_savedGlobals.sDirectorModeData.iBitsetCharacterAnimalUnlock, ENUM_TO_INT( eUnlockAnimal ) ) UNLOCK_DIRECTOR_ANIMAL_CHAR_FROM_ANIMAL_PICKUP(eTriggeredAnimal, TRUE) #ENDIF // Rumble on collection. SET_CONTROL_SHAKE(PLAYER_CONTROL, PICKUP_RUMBLE_DURATION, PICKUP_RUMBLE_FREQ) //Disable stats STAT_DISABLE_STATS_TRACKING() #IF IS_DEBUG_BUILD Debug_Refresh_Pickup_Blips() #ENDIF HANG_UP_AND_PUT_AWAY_PHONE(TRUE) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_PHONE) eState = ACS_GO_ON_MISSION ENDIF ENDIF ENDREPEAT ENDREPEAT //Every 1000 frames check if the initial pickup progression has been completed. IF NOT g_savedGlobals.sAmbient.bPeyoteProgressionComplete IF (GET_FRAME_COUNT() % 1000) = 0 Check_For_Peyote_Progression_Completion() ENDIF ENDIF BREAK CASE ACS_GO_ON_MISSION SWITCH Request_Mission_Launch(iCandidateID, MCTID_CONTACT_POINT, MISSION_TYPE_ANIMAL) CASE MCRET_ACCEPTED CPRINTLN(DEBUG_ANIMAL_MODE, "Sucessfully secured the candidate ID as MISSION_TYPE_ANIMAL.") REQUEST_MODEL(Get_Animal_Model_From_Pickup_Enum(eTriggeredAnimal)) //If all pickups haven't been collected, save that we found a new pickup //as we go on mission. IF NOT g_savedGlobals.sAmbient.bPeyoteProgressionComplete SET_AUTOSAVE_IGNORES_ON_MISSION_FLAG(TRUE, TRUE) MAKE_AUTOSAVE_REQUEST() CPRINTLN(DEBUG_ANIMAL_MODE, "Autosave Request") ENDIF eState = ACS_SWITCHING_TO_ANIMAL BREAK CASE MCRET_DENIED CPRINTLN(DEBUG_ANIMAL_MODE, "Failed to secure the candidate ID as MISSION_TYPE_ANIMAL.") eState = ACS_WAIT_FOR_PICKUP BREAK ENDSWITCH DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_PHONE) BREAK CASE ACS_SWITCHING_TO_ANIMAL IF Switch_To_Animal() CPRINTLN(DEBUG_ANIMAL_MODE, "Player is now playing as the animal.") //Display initial help text. Show_help_text() Non_Active_Taxi_Check() eState = ACS_PLAYING_AS_ANIMAL ENDIF DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_PHONE) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SELECT_WEAPON) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_CHARACTER_WHEEL) HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_WEAPON_ICON) Active_Taxi_Check() BREAK CASE ACS_PLAYING_AS_ANIMAL Update_Animal_Restricted_State(Get_Animal_Model_From_Pickup_Enum(eTriggeredAnimal),wantedTimer) Manage_Animal_Bark() IF NOT IS_BIT_SET(iStateBitset,BIT_CONVERSATION_STARTED) IF CREATE_CONVERSATION(sConversationPeds,"ANIMLAU",currentConversation,CONV_PRIORITY_AMBIENT_MEDIUM) SET_BIT(iStateBitset,BIT_CONVERSATION_STARTED) ENDIF ENDIF LOAD_STREAM("PEYOTE_TRANSITION_OUT") //Exit animal mode if the context button is held for a time. IF IS_CONTROL_PRESSED(PLAYER_CONTROL, INPUT_CONTEXT) IF iExitButtonTimer = -1 iExitButtonTimer = GET_GAME_TIMER() ELIF (GET_GAME_TIMER() - iExitButtonTimer) > ANIMAL_MODE_EXIT_HOLD_TIME CPRINTLN(DEBUG_ANIMAL_MODE, "Animal mode deactivated with button press.") Animal_Mode_Normal_Exit() eState = ACS_SWITCHING_FROM_ANIMAL ENDIF ELIF iExitButtonTimer != -1 iExitButtonTimer = -1 ENDIF IF Should_Animal_Mode_Exit(crushDepthTimer) CPRINTLN(DEBUG_ANIMAL_MODE, "Animal mode deactivating due to exit condition.") IF NOT IS_ENTITY_DEAD(PLAYER_PED_ID()) //Force the animal to ragdoll as we exit. Stops the player seeing the animal exit //water safely making the exit reason seem unfair. SET_PED_TO_RAGDOLL(PLAYER_PED_ID(), 1000, 3000, TASK_RELAX) ENDIF Animal_Mode_Normal_Exit() eState = ACS_SWITCHING_FROM_ANIMAL ENDIF BREAK CASE ACS_SWITCHING_FROM_ANIMAL IF Switch_To_Player() CPRINTLN(DEBUG_ANIMAL_MODE, "Player is now playing as their story character.") CPRINTLN(DEBUG_ANIMAL_MODE, "Releasing mission state and returning to waiting for pickup.") // Display the feed message for unlocking the Director Mode animal here. // We actually silently unlocked the animal as soon as the Peyote was collected. #IF FEATURE_SP_DLC_DIRECTOR_MODE IF eUnlockAnimal != DU_ANIMAL_INVALID AND NOT bDMUnlockedPreviously PRIVATE_Display_Director_Character_Unlock_Feed_Message(PRIVATE_Get_Director_Animal_Name_Label(eUnlockAnimal)) ENDIF #ENDIF CLEAR_BIT(iStateBitset,BIT_CONVERSATION_STARTED) Mission_Over(iCandidateID) eState = ACS_WAIT_FOR_PICKUP ELSE //While changing back, disable first person car camera and camera change control DISABLE_CINEMATIC_BONNET_CAMERA_THIS_UPDATE() DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_NEXT_CAMERA) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_ENTER) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_PHONE) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_SELECT_WEAPON) DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_CHARACTER_WHEEL) HIDE_HUD_COMPONENT_THIS_FRAME(NEW_HUD_WEAPON_ICON) ENDIF BREAK ENDSWITCH //Update the pickup splash screen if requested. UPDATE_DISPLAY_MESSAGE(bDisplaySplash, bMessageOnDisplay, iSplashTimer, SCRAP_PEYOTE, iSplashStage, siPickupSplash, "PEY_TITLE", "PEY_COLLECT") //Update white box transition DRAW_WHITE_RECT() //stop player switching if help text showing/registered IF contextId != -1 DISABLE_CONTROL_ACTION(PLAYER_CONTROL, INPUT_CHARACTER_WHEEL) DISABLE_SELECTOR_THIS_FRAME() ENDIF WAIT(0) ENDWHILE ENDSCRIPT