The code has been released.
NOTE: The code has not yet been released, but posted to search for bugs. Please do not use it right now as it may contain bugs. It should only be used for testing. On the other hand, if you are testing, then please report any found bugs so that they can be fixed. It will be released soon.
Guys, help me test.
Hey guys, after seeing so many badly-made property scripts (reaching the game's pickup limit, pickups getting stuck in the saved game, etc.), I decided to write a template script without any of the common problems associated with such scripts. It is easily configurable, so you can set it up to your liking.
Requirements:
Sanny Builder (to compile the script).
CLEO+ (to run the script).
Code:
Código: Selecionar tudo
{$CLEO .cs}
{$USE CLEO+}
// Author: [your name]
// template by: HzanRsxa2959
// https://forum.mixmods.com.br/f16-utilidades/t5341-cleo-property-template
// a big feature of this code is that a workaround is used to avoid hitting the pickup limit:
// property and save pickups only spawn when camera is near the pickups' draw distance, and looking at its location
// revenue pickup is spawned only when camera is near the pickup's draw distance
// another big feature is that none of the entities will stay in the saved game; everything is saved using CLEO's save system
// your settings >
const
// -1: unavailable
// false: available
// true: bought
iInitialState = false
// after which city is unlocked will this property unlock, use for a simple unlock system
// -1: any
// 0: Los Santos
// 1: Countryside
// 2: San Fierro
// 3: Desert
// 4: Las Venturas
iUnlockedAfter = 0
// set this to true to call a gosub to the label :unlock
// the property will unlock after the label returns true AND the city set above is unlocked
bCallUnlockLabel = false
fPropertyPickupX = 154.2453
fPropertyPickupY = -1941.8450
fPropertyPickupZ = 3.7734
iPropertyPickupPrice = 1000
iSavePickupModel = 1277
fSavePickupX = fPropertyPickupX
fSavePickupY = -1946.1300
fSavePickupZ = 5.0847
// https://wiki.multitheftauto.com/wiki/Radar_Blips
iPropertyBlipIcon = 31
iPropertyUnavailableBlipIcon = 32
// below constants can use above constants recursively
fPropertyBlipX = fPropertyPickupX
fPropertyBlipY = fPropertyPickupY
bPropertyBlipShort = true
iSaveBlipIcon = 35
fSaveBlipX = fSavePickupX
fSaveBlipY = fSavePickupY
bSaveBlipShort = true
fRevenuePickupX = 148.5995
fRevenuePickupY = -1944.9918
fRevenuePickupZ = 3.7734
iRevenuePickupCashMax = 1000
// seems like a multiplier for above value, e.g., putting twice the value of revenue here will make it generate twice as fast, see here: https://gtaforums.com/topic/899307-asset-money-generator/?do=findComment&comment=1069911289
iRevenuePickupCashRate = 1000
fRevenuePickupCameraX = fRevenuePickupX
fRevenuePickupCameraY = -1942.9918
fRevenuePickupCameraZ = fRevenuePickupZ
iRevenuePickupCameraInterior = 0
sRevenuePickupText = 'ASS_LUV'
iRevenuePickupTextTime = 6000
fBuyCameraPutX = 122.9681
fBuyCameraPutY = -1911.1543
fBuyCameraPutZ = 62.1727
fBuyCameraPointX = 154.6919
fBuyCameraPointY = -1950.5173
fBuyCameraPointZ = 29.2899
fSavePutX = fPropertyPickupX
fSavePutY = fPropertyPickupY
fSavePutZ = fPropertyPickupZ
fSavePutAngle = 0
fInteriorEnterX = 151.1769
fInteriorEnterY = -1937.2605
fInteriorEnterZ = 3.7734
fInteriorEnterAngle = 0
// https://wiki.multitheftauto.com/wiki/Interior_IDs
iInteriorEnterInterior = 0
fInteriorEnterRadiusX = 1.0
fInteriorEnterRadiusY = 1.0
fInteriorEnterRadiusZ = 1.0
sInteriorEnterName = '' // case matters; always use uppercase
bInteriorEnterTeleportGang = true // warp player group
bInteriorEnterTeleportBike = true // warp if on bike
iInteriorEnterTimeOn = 0
iInteriorEnterTimeOff = 11
iInteriorEnterPedsAmount = 8 // default 8; use 0 to have no peds (scripted peds still appear); idk about using values other than 8
iInteriorEnterSkyColor = 4
fInteriorExitX = 150.0916
fInteriorExitY = -1932.1672
fInteriorExitZ = 3.7696
fInteriorExitAngle = 180.0
iInteriorExitInterior = 0
fInteriorExitRadiusX = 1.0
fInteriorExitRadiusY = 1.0
fInteriorExitRadiusZ = 1.0
sInteriorExitName = ''
bInteriorExitTeleportGang = true
bInteriorExitTeleportBike = true
iInteriorExitTimeOn = 12
iInteriorExitTimeOff = 23
iInteriorExitPedsAmount = 8
iInteriorExitSkyColor = 0
end
goto @start // do not remove or game will crash
//03A4: script_name 'PRO_TEM'
// uncomment above and set thread name to manage from another script
// thread name must be unique, you may prefer the pickup object method below
// the pickup (property / save and revenue) object (CPickup + 0x4) has an extended var (use 0E1C) with id "PROPERTYTEMPLATE" that contains this script's pointer
// use the pointer to manage this script from another script
// below are subroutines that are called at certain times, you may put your code there, they are called in the order they are written in
// 15@ is player ped handle
// 16@ is current save slot (use only in :save)
// use 17@ - 33@ as you like
:save // called just before game is saved, you may want to revert your changes (e.g. delete stuff) here so that they don't stay stuck in the save game
0ED0: return_script_event
:once // called once at start of script, and never again, same as :onceBefore
return
:onceBefore // called once before property is bought, and never again, same as :once
return
:onceAfter // called once after property is bought, and never again
return
:load // called once after game is loaded
return
:loadBefore // called once after game is loaded before property is bought
return
:loadAfter // called once after game is loaded after property is bought
return
:frame // called every frame
return
:frameBefore // called every frame before property is bought
return
:frameAfter // called every frame after property is bought
return
:unlock // property becomes available after this returns true
return
// you can also enable / disable certain features by uncommenting / commenting the code from below
// such code has comments above and below it. uncomment / comment all the lines between the comments to enable / disable features
// example 1: comment all the lines between "// save pickup >" and "// <" to disable a save pickup being spawned at the specified coordinates after buying the property
// example 2: uncomment all the lines between "// revenue pickup >" and "// <" to enable a revenue pickup being spawned at the specified coordinates
// be careful when commenting / uncommenting the code as it may cause bugs
// < your settings
:start
const
bBought = 0@
iPrice = 1@
fRevenueCurrent = 2@
iFlags = 3@
bOnce = 0
bOnceBefore = 1
bOnceAfter = 2
bSave = 3
bLoad = 4
bLoadBefore = 5
bLoadAfter = 6
bEntered = 7
bExited = 8
bUnlockAfter = 9
bRevenuePickupCamera = 10
bEntry = 11
bExit = 12
hPickup = 4@
hBlip = 5@
hRevenuePickup = 6@
bOnMission = 7@
fPickupsDrawDistance = 8@
bHidePickup = 9@
bHideRevenuePickup = 10@
pThread = 11@
t0 = 12@
t1 = 13@
t2 = 14@
hPlayerPed = 15@
vSaveSlot = 16@
end
bBought = iInitialState
iPrice = iPropertyPickupPrice
fRevenueCurrent = 0
iFlags = 0
08BD: set iFlags bit bEntered
08BD: set iFlags bit bExited
if bBought == true
then
08BD: set iFlags bit bRevenuePickupCamera
end
0A95: enable_thread_saving
while true
0AC6: t0 = label @launch offset
0A8D: t1 = read_memory t0 size 1 virtual_protect 0
if t1 == 0
then
0A8C: write_memory t0 size 1 value 1 virtual_protect 0
0ED1: set_script_event_save_confirmation true label @onSave args t0
08C3: clear iFlags bit bSave
08C3: clear iFlags bit bLoad
08C3: clear iFlags bit bLoadBefore
08C3: clear iFlags bit bLoadAfter
08C3: clear iFlags bit bEntry
08C3: clear iFlags bit bExit
hPickup = -1
hBlip = -1
hRevenuePickup = -1
bOnMission = true
bHidePickup = true
bHideRevenuePickup = true
0A9F: pThread = current_thread_pointer
01F5: hPlayerPed = get_player_actor 0
0D4C: t0 = string sInteriorEnterName length
if t0 > 0
then
gosub @initEntry
end
0D4C: t0 = string sInteriorExitName length
if t0 > 0
then
gosub @initExit
end
end
if 0E1D: is_on_mission
then
if bOnMission == false
then
bOnMission = true
if bBought == true
then
gosub @destroyPickup
end
gosub @destroyBlip
end
else
bOnMission = false
end
0A8D: fPickupsDrawDistance = read_memory 0x454CC9 size 4 virtual_protect 0
0A8D: fPickupsDrawDistance = read_memory fPickupsDrawDistance size 4 virtual_protect 0
if bBought <> true
then
t0 = fPropertyPickupX
t1 = fPropertyPickupY
t2 = fPropertyPickupZ
else
t0 = fSavePickupX
t1 = fSavePickupY
t2 = fSavePickupZ
end
bHidePickup = false
if 80C2: not sphere_onscreen t0 t1 t2 radius 2.0
then
gosub @hidePickup
else
if 8EBE: not locate_camera_distance_to_coordinates t0 t1 t2 radius fPickupsDrawDistance
then
gosub @hidePickup
else
if and
bBought == true
08B4: test $391 bit 25
then
gosub @hidePickup
end
end
end
if bHidePickup == false
then
if or
bOnMission == false
bBought <> true
then
if hPickup == -1
then
if bBought == false
then
0518: hPickup = create_available_asset_pickup 'PROP_3' at fPropertyPickupX fPropertyPickupY fPropertyPickupZ price iPrice
else
if bBought == -1
then
0517: hPickup = create_unavailable_asset_pickup 'PROP_4' at fPropertyPickupX fPropertyPickupY fPropertyPickupZ
///* save pickup >
else
0213: hPickup = create_pickup iSavePickupModel type 3 at fSavePickupX fSavePickupY fSavePickupZ
// < */
end
end
gosub @setExtendedVars
end
end
end
if bOnMission == false
then
if hBlip == -1
then
if bBought == false
then
///* property blip >
0E2A: add_cleo_blip iPropertyBlipIcon position fPropertyBlipX fPropertyBlipY is_short bPropertyBlipShort RGBA 255 255 255 255 store_to hBlip
else
if bBought == -1
then
0E2A: add_cleo_blip iPropertyUnavailableBlipIcon position fPropertyBlipX fPropertyBlipY is_short bPropertyBlipShort RGBA 255 255 255 255 store_to hBlip
// < */
///* save blip >
else
0E2A: add_cleo_blip iSaveBlipIcon position fSaveBlipX fSaveBlipY is_short bSaveBlipShort RGBA 255 255 255 255 store_to hBlip
end
// < */
end
end
end
/* revenue pickup >
if bBought == true
then
if 8EBE: not locate_camera_distance_to_coordinates fRevenuePickupX fRevenuePickupY fRevenuePickupZ radius fPickupsDrawDistance
then
if bHideRevenuePickup == false
then
bHideRevenuePickup = true
gosub @destroyRevenuePickup
end
else
bHideRevenuePickup = false
end
if and
bHideRevenuePickup == false
hRevenuePickup == -1
then
04A6: hRevenuePickup = create_asset_money_pickup_at fRevenuePickupX fRevenuePickupY fRevenuePickupZ money iRevenuePickupCashMax iRevenuePickupCashRate
if fRevenueCurrent <> 0
then
0E38: get_pickup_pointer hRevenuePickup store_to t0
0A8C: write_memory t0 size 4 value fRevenueCurrent virtual_protect 0
end
0E38: get_pickup_pointer hRevenuePickup store_to t0
gosub @setExtendedVars
end
end
// < */
/* revenue pickup camera >
if and
88B7: not test iFlags bit bRevenuePickupCamera
bBought == true
then
08BD: set iFlags bit bRevenuePickupCamera
04A6: hRevenuePickup = create_asset_money_pickup_at fRevenuePickupX fRevenuePickupY fRevenuePickupZ money iRevenuePickupCashMax iRevenuePickupCashRate
01B4: set_player 0 can_move 0
02A3: enable_widescreen 1
015F: set_camera_position fRevenuePickupCameraX fRevenuePickupCameraY fRevenuePickupCameraZ rotation 0 0 0
0160: set_camera_point_at fRevenuePickupX fRevenuePickupY fRevenuePickupZ switchstyle 2
t0 = iRevenuePickupCameraInterior
if t0 <> -1
then
077E: get_active_interior_to t2
04BB: select_interior t0
end
03CB: set_rendering_origin_at fRevenuePickupCameraX fRevenuePickupCameraY fRevenuePickupCameraZ
01E5: show_text_1number_highpriority GXT sRevenuePickupText number iRevenuePickupCashMax time iRevenuePickupTextTime flag 1
wait iRevenuePickupTextTime
gosub @destroyRevenuePickup
01B4: set_player 0 can_move 1
02A3: enable_widescreen 0
02EB: restore_camera_with_jumpcut
if t0 <> -1
then
04BB: select_interior t2
end
068D: get_camera_position_to t0 t1 t2
03CB: set_rendering_origin_at t0 t1 t2
end
// < */
/* interior teleport >
if and
bBought == true
09E7: player 0 not_frozen
then
0E40: get_current_hour t0
if and
t0 >= iInteriorEnterTimeOn
t0 <= iInteriorEnterTimeOff
then
if and
00C2: sphere_onscreen fInteriorEnterX fInteriorEnterY fInteriorEnterZ radius 1.0
0EBE: locate_camera_distance_to_coordinates fInteriorEnterX fInteriorEnterY fInteriorEnterZ radius 50.0
then
03A1: show_sphere_at fInteriorEnterX fInteriorEnterY fInteriorEnterZ radius 1.0
end
if 00FE: actor hPlayerPed sphere 0 in_sphere fInteriorEnterX fInteriorEnterY fInteriorEnterZ radius fInteriorEnterRadiusX fInteriorEnterRadiusY fInteriorEnterRadiusZ
then
t0 = bInteriorEnterTeleportBike
if or
847A: not actor hPlayerPed driving_bike
t0 == true
then
if and
03EE: player 0 controllable
02A0: actor hPlayerPed stopped
then
if 88B7: not test iFlags bit bExited
then
08BD: set iFlags bit bEntered
01B4: set_player 0 can_move 0
016A: fade 0 time 250
wait 350
t0 = iInteriorEnterInterior
if t0 <> -1
then
04BB: select_interior t0
0860: link_actor hPlayerPed to_interior t0
end
03CB: set_rendering_origin_at fInteriorExitX fInteriorExitY fInteriorExitZ
t0 = bInteriorEnterTeleportGang
if t0 == true
then
0972: put_actor hPlayerPed at fInteriorExitX fInteriorExitY fInteriorExitZ no_offset
else
09BC: put_actor hPlayerPed at fInteriorExitX fInteriorExitY fInteriorExitZ no_offset_and_dont_warp_gang
end
0173: set_actor hPlayerPed Z_angle_to fInteriorExitAngle
0373: set_camera_directly_behind_player
wait 350
016A: fade 1 time 250
01B4: set_player 0 can_move 1
if gosub @setEntry
then
0A19: display_zone_text sInteriorEnterName
end
end
end
end
else
08C3: clear iFlags bit bExited
end
end
if and
t0 >= iInteriorExitTimeOn
t0 <= iInteriorExitTimeOff
then
if and
00C2: sphere_onscreen fInteriorExitX fInteriorExitY fInteriorExitZ radius 1.0
0EBE: locate_camera_distance_to_coordinates fInteriorExitX fInteriorExitY fInteriorExitZ radius 50.0
then
03A1: show_sphere_at fInteriorExitX fInteriorExitY fInteriorExitZ radius 1.0
end
if 00FE: actor hPlayerPed sphere 0 in_sphere fInteriorExitX fInteriorExitY fInteriorExitZ radius fInteriorExitRadiusX fInteriorExitRadiusY fInteriorExitRadiusZ
then
t0 = bInteriorExitTeleportBike
if or
847A: not actor hPlayerPed driving_bike
t0 == true
then
if and
03EE: player 0 controllable
02A0: actor hPlayerPed stopped
then
if 88B7: not test iFlags bit bEntered
then
08BD: set iFlags bit bExited
01B4: set_player 0 can_move 0
016A: fade 0 time 250
wait 350
t0 = iInteriorExitInterior
if t0 <> -1
then
04BB: select_interior t0
0860: link_actor hPlayerPed to_interior t0
end
03CB: set_rendering_origin_at fInteriorEnterX fInteriorEnterY fInteriorEnterZ no_offset
t0 = bInteriorExitTeleportGang
if t0 == true
then
0972: put_actor hPlayerPed at fInteriorEnterX fInteriorEnterY fInteriorEnterZ no_offset
else
09BC: put_actor hPlayerPed at fInteriorEnterX fInteriorEnterY fInteriorEnterZ no_offset_and_dont_warp_gang
end
0173: set_actor hPlayerPed Z_angle_to fInteriorEnterAngle
0373: set_camera_directly_behind_player
wait 350
016A: fade 1 time 250
01B4: set_player 0 can_move 1
if gosub @setExit
then
0A19: display_zone_text sInteriorExitName
end
end
end
end
else
08C3: clear iFlags bit bEntered
end
end
end
// < */
if and
hPickup <> -1
0214: pickup hPickup picked_up
then
gosub @destroyPickup
gosub @destroyBlip
if bBought == false
then
bBought = true
01B4: set_player 0 can_move 0
02A3: enable_widescreen 1
015F: set_camera_position fBuyCameraPutX fBuyCameraPutY fBuyCameraPutZ rotation 0 0 0
0160: set_camera_point_at fBuyCameraPointX fBuyCameraPointY fBuyCameraPointZ switchstyle 2
00BA: show_text_styled GXT 'BUYPRO' time 5000 style 2
0394: play_music 2
wait 5000
01B4: set_player 0 can_move 1
02A3: enable_widescreen 0
02EB: restore_camera_with_jumpcut
else
$ONMISSION = 1
016A: fade 0 time 250
wait 350
0395: clear_area 1 at fSavePutX fSavePutY fSavePutZ radius 1.0
0972: put_actor hPlayerPed at fSavePutX fSavePutY fSavePutZ no_offset
0173: set_actor hPlayerPed Z_angle_to fSavePutAngle
0373: set_camera_directly_behind_player
$ONMISSION = 0
03D8: show_save_screen
wait 0
0173: set_actor hPlayerPed Z_angle_to fSavePutAngle
wait 350
016A: fade 1 time 250
end
end
if 88B7: not test iFlags bit bSave
then
08BD: set iFlags bit bSave
0ED1: set_script_event_save_confirmation true label @save args vSaveSlot
end
if 88B7: not test iFlags bit bOnce
then
08BD: set iFlags bit bOnce
gosub @once
end
if bBought <> true
then
if 88B7: not test iFlags bit bOnceBefore
then
08BD: set iFlags bit bOnceBefore
gosub @onceBefore
end
else
if 88B7: not test iFlags bit bOnceAfter
then
08BD: set iFlags bit bOnceAfter
gosub @onceAfter
end
end
if 88B7: not test iFlags bit bLoad
then
08BD: set iFlags bit bLoad
gosub @load
end
if bBought <> true
then
if 88B7: not test iFlags bit bLoadBefore
then
08BD: set iFlags bit bLoadBefore
gosub @loadBefore
end
else
if 88B7: not test iFlags bit bLoadAfter
then
08BD: set iFlags bit bLoadAfter
gosub @loadAfter
end
end
gosub @frame
if bBought <> true
then
gosub @frameBefore
else
gosub @frameAfter
end
if bBought == -1
then
t0 = false
if 88B7: not test iFlags bit bUnlockAfter
then
t1 = iUnlockedAfter
if t1 == -1
then
08BD: set iFlags bit bUnlockAfter
t0 = true
else
0652: t1 = integer_stat 181
if t1 >= iUnlockedAfter
then
08BD: set iFlags bit bUnlockAfter
t0 = true
end
end
else
t0 = true
end
if t0 == true
then
t1 = bCallUnlockLabel
if t1 == true
then
if gosub @unlock
then
else
t0 = false
end
end
end
if t0 == true
then
gosub @destroyPickup
gosub @destroyBlip
bBought = false
end
end
wait 0
if 08B7: test iFlags bit bEntry
then
gosub @setEntry
08C3: clear iFlags bit bEntry
end
if 08B7: test iFlags bit bExit
then
gosub @setExit
08C3: clear iFlags bit bExit
end
end
:launch
hex
00
end
:setExtendedVars
if hPickup <> -1
then
0E38: get_pickup_pointer hPickup store_to t0
0D4E: t0 = read_struct t0 offset 0x4 size 4
0AEC: t0 = object_struct t0 handle
0E1A: init_extended_object_vars t0 id "PROPERTYTEMPLATE" new_vars 1
0E1B: set_extended_object_var t0 id "PROPERTYTEMPLATE" var 1 value pThread
end
return
:destroyPickup
if hPickup <> -1
then
if bBought == false
then
0E38: get_pickup_pointer hPickup store_to t0
0D4E: iPrice = read_struct t0 offset 0x8 size 4
end
0215: destroy_pickup hPickup
hPickup = -1
end
return
:destroyBlip
if hBlip <> -1
then
0E2B: remove_cleo_blip hBlip
hBlip = -1
end
return
:onSave
gosub @destroyPickup
gosub @destroyRevenuePickup
0A96: t0 = ped hPlayerPed struct
t0 += 0x78C
0A8D: t1 = read_memory t0 size 4 virtual_protect 0
0AC6: t2 = label @entry pointer
if 003B: t1 == t2
then
0A8C: write_memory t0 size 4 value 0 virtual_protect 0
08BD: set iFlags bit bEntry
else
0AC6: t2 = label @exit pointer
if 003B: t1 == t2
then
0A8C: write_memory t0 size 4 value 0 virtual_protect 0
08BD: set iFlags bit bExit
end
end
0ED0: return_script_event
:hidePickup
gosub @destroyPickup
bHidePickup = true
return
:destroyRevenuePickup
if hRevenuePickup <> -1
then
0E38: get_pickup_pointer hRevenuePickup store_to t0
0A8D: fRevenueCurrent = read_memory t0 size 4 virtual_protect 0
0215: destroy_pickup hRevenuePickup
hRevenuePickup = -1
end
return
:entry
hex
000000000000000000000000000000000000000000000000000000000000
end
:initEntry
0AC6: t0 = label @entry pointer
0AC8: t1 = allocate_memory_size 255
0D4D: copy_string sInteriorEnterName to t1
0EC2: set_string_upper t1
0A8D: t2 = read_memory t1 size 4 virtual_protect 0
0A8C: write_memory t0 size 4 value t2 virtual_protect 0
t0 += 0x4
t1 += 0x4
0A8D: t2 = read_memory t1 size 4 virtual_protect 0
0A8C: write_memory t0 size 4 value t2 virtual_protect 0
t0 += 0x4
0AC9: free_allocated_memory t1
t1 = fInteriorEnterX
t1 -= fInteriorEnterRadiusX
0A8C: write_memory t0 size 4 value t1 virtual_protect 0
t0 += 0x4
t1 = fInteriorEnterZ
t1 -= fInteriorEnterRadiusZ
0A8C: write_memory t0 size 4 value t1 virtual_protect 0
t0 += 0x4
t1 = fInteriorEnterX
t1 += fInteriorEnterRadiusX
0A8C: write_memory t0 size 4 value t1 virtual_protect 0
t0 += 0x4
t1 = fInteriorEnterZ
t1 += fInteriorEnterZ
0A8C: write_memory t0 size 4 value t1 virtual_protect 0
t0 += 0x4
0A8C: write_memory t0 size 4 value fInteriorEnterZ virtual_protect 0
t0 += 0x4
0A8C: write_memory t0 size 4 value fInteriorEnterAngle virtual_protect 0
t0 += 0x4
0A8C: write_memory t0 size 4 value fInteriorExitX virtual_protect 0
t0 += 0x4
0A8C: write_memory t0 size 4 value fInteriorExitY virtual_protect 0
t0 += 0x4
0A8C: write_memory t0 size 4 value fInteriorExitZ virtual_protect 0
t0 += 0x4
0A8C: write_memory t0 size 4 value fInteriorExitAngle virtual_protect 0
t0 += 0x4
0A8C: write_memory t0 size 2 value 0 virtual_protect 0
t0 += 0x2
0A8C: write_memory t0 size 1 value iInteriorEnterInterior virtual_protect 0
t0 += 0x1
0A8C: write_memory t0 size 1 value iInteriorEnterSkyColor virtual_protect 0
t0 += 0x1
0A8C: write_memory t0 size 1 value iInteriorEnterTimeOn virtual_protect 0
t0 += 0x1
0A8C: write_memory t0 size 1 value iInteriorEnterTimeOff virtual_protect 0
t0 += 0x1
0A8C: write_memory t0 size 1 value iInteriorEnterPedsAmount virtual_protect 0
t0 += 0x1
0A8C: write_memory t0 size 1 value 0 virtual_protect 0
t0 += 0x1
0A8C: write_memory t0 size 4 value 0 virtual_protect 0
return
:exit
hex
000000000000000000000000000000000000000000000000000000000000
end
:initExit
0AC6: t0 = label @exit pointer
0AC8: t1 = allocate_memory_size 255
0D4D: copy_string sInteriorExitName to t1
0EC2: set_string_upper t1
0A8D: t2 = read_memory t1 size 4 virtual_protect 0
0A8C: write_memory t0 size 4 value t2 virtual_protect 0
t0 += 0x4
t1 += 0x4
0A8D: t2 = read_memory t1 size 4 virtual_protect 0
0A8C: write_memory t0 size 4 value t2 virtual_protect 0
t0 += 0x4
0AC9: free_allocated_memory t1
t1 = fInteriorExitX
t1 -= fInteriorExitRadiusX
0A8C: write_memory t0 size 4 value t1 virtual_protect 0
t0 += 0x4
t1 = fInteriorExitZ
t1 -= fInteriorExitRadiusZ
0A8C: write_memory t0 size 4 value t1 virtual_protect 0
t0 += 0x4
t1 = fInteriorExitX
t1 += fInteriorExitRadiusX
0A8C: write_memory t0 size 4 value t1 virtual_protect 0
t0 += 0x4
t1 = fInteriorExitZ
t1 += fInteriorExitZ
0A8C: write_memory t0 size 4 value t1 virtual_protect 0
t0 += 0x4
0A8C: write_memory t0 size 4 value fInteriorExitZ virtual_protect 0
t0 += 0x4
0A8C: write_memory t0 size 4 value fInteriorExitAngle virtual_protect 0
t0 += 0x4
0A8C: write_memory t0 size 4 value fInteriorEnterX virtual_protect 0
t0 += 0x4
0A8C: write_memory t0 size 4 value fInteriorEnterY virtual_protect 0
t0 += 0x4
0A8C: write_memory t0 size 4 value fInteriorEnterZ virtual_protect 0
t0 += 0x4
0A8C: write_memory t0 size 4 value fInteriorEnterAngle virtual_protect 0
t0 += 0x4
0A8C: write_memory t0 size 2 value 0 virtual_protect 0
t0 += 0x2
0A8C: write_memory t0 size 1 value iInteriorExitInterior virtual_protect 0
t0 += 0x1
0A8C: write_memory t0 size 1 value iInteriorExitSkyColor virtual_protect 0
t0 += 0x1
0A8C: write_memory t0 size 1 value iInteriorExitTimeOn virtual_protect 0
t0 += 0x1
0A8C: write_memory t0 size 1 value iInteriorExitTimeOff virtual_protect 0
t0 += 0x1
0A8C: write_memory t0 size 1 value iInteriorExitPedsAmount virtual_protect 0
t0 += 0x1
0A8C: write_memory t0 size 1 value 0 virtual_protect 0
t0 += 0x1
0A8C: write_memory t0 size 4 value 0 virtual_protect 0
return
:setEntry
0D4C: t0 = string sInteriorEnterName length
if t0 > 0
then
0AC6: t0 = label @entry pointer
04F9: set_sky_color iInteriorEnterSkyColor fade 0
t2 = true
else
t0 = 0
04FA: reset_sky_colors_with_fade 0
t2 = false
end
0A96: t1 = ped hPlayerPed struct
t1 += 0x78C
0A8C: write_memory t1 size 4 value t0 virtual_protect 0
075E: load_shopping_data_PRICES_subsection sInteriorEnterName
t2 == true
return
:setExit
0D4C: t0 = string sInteriorExitName length
if t0 > 0
then
0AC6: t0 = label @exit pointer
04F9: set_sky_color iInteriorExitSkyColor fade 0
t2 = true
else
t0 = 0
04FA: reset_sky_colors_with_fade 0
t2 = false
end
0A96: t1 = ped hPlayerPed struct
t1 += 0x78C
0A8C: write_memory t1 size 4 value t0 virtual_protect 0
075E: load_shopping_data_PRICES_subsection sInteriorExitName
t2 == true
return
Copy the code above to Sanny Builder (it will be easy to read).
Edit the constants, subroutines and features to your liking. The default values set up the
Santa Maria Lighthouse as a buyable property with a cost of $1000 and a save pickup after buying.
Compile the script.
The code has been well-commented and is easy to read. Regardless, if you have any questions, I will be glad to answer them.