Grinch_ Posted May 8, 2021 Share Posted May 8, 2021 PyLoader PyLoader (totally !not a ripoff of some other plugin with similar name xD) is a Python script loader for GTA SanAndreas. That means now you can write scripts for SA using Python!!. If you've used MoonLoader before the concept is exactly the same but for Python. Just a heads up, this is mostly work in progress so crashes might occur or stuff might stop working at any time forward. Let me know if you find any bugs or have suggestions Here's a sample script, import common, hud print("Working directory: {}".format(common.get_working_dir())) print("Game directory: {}".format(common.get_game_dir())) while True: if (common.key_pressed(0x09)): hud.set_help_message("Hello World", False, False, False) common.wait(0) More examples are here Installation: 1. Install vs redist 2019 x86 and asi loader 2. Download PyLoader.7z and extract everything in game directory. Python Version: 3.8x Minimum windows: 7 Supported version: SA 1.0 GitHub: here Wiki: here XG417, ghost66, indirivacua and 15 others 16 1 1 Link to comment Share on other sites More sharing options...
loms Posted May 9, 2021 Share Posted May 9, 2021 Nice have to test later! Link to comment Share on other sites More sharing options...
Grinch_ Posted June 22, 2021 Author Share Posted June 22, 2021 Some more recent changes, 1. Scripts can now be loaded/unloaded during runtime. Example here 2. Added opcodes to set & get script name, version, author, desc etc. 3. Added all the CLEO4 bass opcodes 4. Added few callback function aka events - scriptTerminateEvent, pedCreateEvent, pedRenderEvent, pedDestroyEvent, objCreateEvent, objRenderEvent, objDestroyEvent, vehCreateEvent, vehRenderEvent, vehDestroyEvent. 5. Improved intellisense suggestions and bug fixes Examples are here RyanDri3957V 1 Link to comment Share on other sites More sharing options...
fott Posted July 11, 2021 Share Posted July 11, 2021 Is it possible to implement the execution of a function on a command (in chat), and not on pressing a key? Link to comment Share on other sites More sharing options...
gta.bullet Posted September 24, 2021 Share Posted September 24, 2021 How to call opcodes in event callbacks? It looks like none of opcodes working in event callbacks. (Like in on_veh_create() etc.) Link to comment Share on other sites More sharing options...
Grinch_ Posted September 25, 2021 Author Share Posted September 25, 2021 9 hours ago, gta.bullet said: How to call opcodes in event callbacks? It looks like none of opcodes working in event callbacks. (Like in on_veh_create() etc.) Haven't tried it out yet. But you can try storing a state flag and running opcodes from the main function I guess. Link to comment Share on other sites More sharing options...
gta.bullet Posted September 27, 2021 Share Posted September 27, 2021 (edited) What about more object oriented style instead of a huge opcodes.py? If anyone interested i can create more classes, you can request from the author if he have time, or even you can create yourself using this sample, just put the classes in lib directory. vehicle.py import sys sys.path.append("../libstd") import opcodes, cleo class Vehicle(): def __init__(self, model, x, y, z): self.handle = opcodes.create_car(model, x, y, z) def remove(self): opcodes.delete_car(self.handle) def explode(self): opcodes.explode_car(self.handle) def freeze(self, freeze): opcodes.freeze_car_position(self.handle, freeze) def get_model(self): return opcodes.get_car_model(self.handle) def exists(self): return cleo.get_car_pointer(self.handle) != 0 def set_forward_speed(self, speed): opcodes.set_car_forward_speed(self.handle, speed) def get_model_name(self): return cleo.get_vehicle_model_name(self.get_model()) def wander_randomly(self): opcodes.car_wander_randomly(self.handle) usage #import necessary stuff car = Vehicle(400, 0.0, 0.0, 0.0) car.freeze() car.explode() car.remove() Note to author: This is much more fun than cleo or lua, i hope you continue development. Edited September 27, 2021 by gta.bullet Link to comment Share on other sites More sharing options...
Grinch_ Posted September 27, 2021 Author Share Posted September 27, 2021 @gta.bullet My initial plan was to expose the plugin-sdk classes to python with ctypes. Something like this, Spoiler # Function definations for the intellisense # Author: Grinch_ # Last updated on: 05/06/2021 import ctypes, cleo class CHud: m_BigMessage = ctypes.c_char.from_address(0xBAACC0) bScriptDontDisplayAreaName = ctypes.c_bool.from_address(0xBAA3F8) bScriptDontDisplayVehicleName = ctypes.c_bool.from_address(0xBAA3F9) bScriptForceDisplayWithCounters = ctypes.c_bool.from_address(0xBAA3FA) m_LastBreathTime = ctypes.c_int.from_address(0xBAA3FC) bDrawClock = ctypes.c_bool.from_address(0xBAA400) m_WeaponState = ctypes.c_int.from_address(0xBAA404) m_WeaponFadeTimer = ctypes.c_int.from_address(0xBAA408) m_WeaponTimer = ctypes.c_int.from_address(0xBAA40C) m_LastWeapon = ctypes.c_int.from_address(0xBAA410) m_WantedState = ctypes.c_int.from_address(0xBAA414) m_WantedFadeTimer = ctypes.c_int.from_address(0xBAA418) m_WantedTimer = ctypes.c_int.from_address(0xBAA41C) m_LastWanted = ctypes.c_int.from_address(0xBAA420) m_DisplayScoreState = ctypes.c_int.from_address(0xBAA424) m_DisplayScoreFadeTimer = ctypes.c_int.from_address(0xBAA428) m_DisplayScoreTimer = ctypes.c_int.from_address(0xBAA42C) m_LastDisplayScore = ctypes.c_int.from_address(0xBAA430) m_EnergyLostState = ctypes.c_int.from_address(0xBAA434) m_EnergyLostFadeTimer = ctypes.c_int.from_address(0xBAA438) m_EnergyLostTimer = ctypes.c_int.from_address(0xBAA43C) m_LastTimeEnergyLost = ctypes.c_int.from_address(0xBAA440) # char *&m_pVehicleNameToPrint = *(char **)0xBAA444; m_VehicleState = ctypes.c_int.from_address(0xBAA448) m_VehicleFadeTimer = ctypes.c_int.from_address(0xBAA44C) m_VehicleNameTimer = ctypes.c_int.from_address(0xBAA450) # char *&m_pLastVehicleName = *(char **)0xBAA454; m_bDraw3dMarkers = ctypes.c_bool.from_address(0xBAA45C) m_Wants_To_Draw_Hud = ctypes.c_bool.from_address(0xBAA45D) m_fHelpMessageTime = ctypes.c_float.from_address(0xBAA460) m_fHelpMessageBoxWidth = ctypes.c_float.from_address(0x8D0934) m_bHelpMessagePermanent = ctypes.c_bool.from_address(0xBAA464) m_fHelpMessageStatUpdateValue = ctypes.c_float.from_address(0xBAA468) m_nHelpMessageMaxStatValue = ctypes.c_ushort.from_address(0xBAA46C) m_nHelpMessageStatId = ctypes.c_ushort.from_address(0xBAA470) m_bHelpMessageQuick = ctypes.c_bool.from_address(0xBAA472) m_nHelpMessageState = ctypes.c_int.from_address(0xBAA474) m_nHelpMessageFadeTimer = ctypes.c_int.from_address(0xBAA478) m_nHelpMessageTimer = ctypes.c_int.from_address(0xBAA47C) m_pHelpMessageToPrint = ctypes.c_char.from_address(0xBAA480) m_pLastHelpMessage = ctypes.c_char.from_address(0xBAA610) m_pHelpMessage = ctypes.c_char.from_address(0xBAA7A0) m_ZoneState = ctypes.c_int.from_address(0xBAA930) m_ZoneFadeTimer = ctypes.c_int.from_address(0xBAA934) m_ZoneNameTimer = ctypes.c_int.from_address(0xBAA938) m_Message = ctypes.c_char.from_address(0xBAB040) # char *&m_ZoneToPrint = *(char **)0xBAB1D0; # char *&m_pLastZoneName = *(char **)0xBAB1D4; # char *&m_pZoneName = *(char **)0xBAB1D8; m_ItemToFlash = ctypes.c_short.from_address(0xBAB1DC) bDrawingVitalStats = ctypes.c_bool.from_address(0xBAB1DE) # CSprite2d *Sprites = (CSprite2d *)0xBAB1FC; TimerMainCounterHideState = ctypes.c_short.from_address(0xBAA388) TimerMainCounterWasDisplayed = ctypes.c_bool.from_address(0xBAA38A) TimerCounterHideState = ctypes.c_short.from_address(0xBAA38C) TimerCounterWasDisplayed = ctypes.c_short.from_address(0xBAA394) OddJob2OffTimer = ctypes.c_int.from_address(0xBAA398) OddJob2Timer = ctypes.c_int.from_address(0xBAA3A0) OddJob2XOffset = ctypes.c_float.from_address(0xBAA39C) BigMessageAlpha = ctypes.c_float.from_address(0xBAA3A4) BigMessageInUse = ctypes.c_float.from_address(0xBAA3C0) BigMessageX = ctypes.c_float.from_address(0xBAA3DC) LastBigMessage = ctypes.c_float.from_address(0xBAABC0) OddJob2On = ctypes.c_ushort.from_address(0xBAB1E0) PagerXOffset = ctypes.c_float.from_address(0x8D0938) def set_help_message(message :str, quick_msg :bool = False, permanent :bool = False, add_to_brief :bool = False) -> None: '''Shows a game hud help popup on top left corner of the screen with provided message string''' cleo.call_function(0x588BE0, 4, 0, message, quick_msg, permanent, add_to_brief) There was an issue with both call_function & call_method with char* param which I'm yet to fix. Likely something in between yours & this one is the way to go. Feel free to make a PR on GitHub when you're done. Link to comment Share on other sites More sharing options...
Grinch_ Posted September 27, 2021 Author Share Posted September 27, 2021 PyLoader v0.07 1. Fixed path issue 2. Added some missing python modules 3. Added on_restart & on_load_save events 4. Fix issue with char* call_function & call_method 5. Added a new hud class Download from here Link to comment Share on other sites More sharing options...
gta.bullet Posted September 29, 2021 Share Posted September 29, 2021 I added a pull request for basic vehicle, ped and camera classes. Link to comment Share on other sites More sharing options...
Grinch_ Posted October 6, 2021 Author Share Posted October 6, 2021 PyLoader v0.08 Add reload_all with new scripts support Added force shutdown for infinite looping scripts Added psdk classes - CClock, CHud, CSprite2d, CTimer, RwTexture, RwTexDictionary, RwRaster, RwObject, RwLLLink, RwLinkist Added helper classes - camera, ped, vehicle Rename cleo module to addition Moved call_function, call_method, free_library, load_library, get_proc_address to memory module Moved test_cheat to common module Fixed bugs with call_function, call_method, get_raw, write_float, set_area_visible Code refactoring Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now