Forked from JuniorDjjr/Reload Mod (Junior_Djjr).sc
Last active
September 15, 2026 21:28
-
-
Save SandeMC/4c6d52a05f71af24702eaa28f6b692cf to your computer and use it in GitHub Desktop.
Fixed Reload Mod by Junior_Djjr, details in comments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Originally made by Junior_Djjr - https://www.mixmods.com.br/2019/07/reload-mod.html | |
| // Fixed by GillianMC - https://gist.github.com/SandeMC/4c6d52a05f71af24702eaa28f6b692cf | |
| CONST_INT OFFSET_PED_ACTIVE_WEAPON_SLOT 0x718 | |
| CONST_INT OFFSET_PED_WEAPONS 0x5A0 | |
| CONST_INT SIZEOF_CWEAPON 0x1C | |
| CONST_INT OFFSET_WEAPON_STATE 0x04 | |
| CONST_INT OFFSET_WEAPON_AMMO_CLIP 0x08 | |
| CONST_INT OFFSET_WEAPON_TOTAL_AMMO 0x0C | |
| CONST_INT OFFSET_WEAPON_SHOT_TIMER 0x10 | |
| CONST_INT OFFSET_WEAPONINFO_CLIP_SIZE 0x20 | |
| CONST_INT ADDR_TIMER_MS 0xB7CB84 | |
| CONST_INT FUNC_PED_GETSKILL 0x5E3B60 | |
| CONST_INT FUNC_WEAPONINFO_GETINFO 0x743C60 | |
| CONST_INT FUNC_WEAPONINFO_GETRELOADTIME 0x743D70 | |
| CONST_INT PATCH_VEHICLE_RELOAD 0x7422A6 | |
| CONST_INT PATCH_SCROLL_RELOAD 0x60B4FA | |
| // Custom Weapon IDs | |
| CONST_INT WEP_FLAMETHROWER 37 | |
| CONST_INT WEP_MINIGUN 38 | |
| CONST_INT WEP_SPRAYCAN 41 | |
| CONST_INT WEP_EXTINGUISHER 42 | |
| CONST_INT WEP_CAMERA 43 | |
| SCRIPT_START | |
| { | |
| // 31 local variable registers used (Engine limit: 32) | |
| LVAR_INT iCmds[2] iLastCurAmmo[2] iLastTotalAmmo[2] iLastWeapon[2] | |
| LVAR_INT bDontReloadIfFull bDisableWeaponsWithoutAnim bRealisticReload bDisabledOnSAMP bKeepNoAmmo bDisableScrollReload bDisableVehicleAutoReload bDisablePickupClipRefill | |
| LVAR_INT i j iPlayerIdx iCmd scplayer pPed pWeapon iCurWeapon pWeaponInfo iMaxAmmo iCurAmmo iState iTotalAmmo iReloadTime iGameTime | |
| // INI Parser (Split across two blocks to honor 8-condition engine limit) | |
| i = 0 | |
| IF NOT READ_INT_FROM_INI_FILE "CLEO/Reload Mod.ini" "Controls" "CMD_Player1" (iCmds[0]) | |
| OR NOT READ_INT_FROM_INI_FILE "CLEO/Reload Mod.ini" "Controls" "CMD_Player2" (iCmds[1]) | |
| OR NOT READ_INT_FROM_INI_FILE "CLEO/Reload Mod.ini" "Settings" "DontReloadIfFull" (bDontReloadIfFull) | |
| OR NOT READ_INT_FROM_INI_FILE "CLEO/Reload Mod.ini" "Settings" "DisableWeaponsWithoutAnim" (bDisableWeaponsWithoutAnim) | |
| OR NOT READ_INT_FROM_INI_FILE "CLEO/Reload Mod.ini" "Settings" "RealisticReload" (bRealisticReload) | |
| OR NOT READ_INT_FROM_INI_FILE "CLEO/Reload Mod.ini" "Settings" "DisabledOnSAMP" (bDisabledOnSAMP) | |
| OR NOT READ_INT_FROM_INI_FILE "CLEO/Reload Mod.ini" "Settings" "KeepNoAmmo" (bKeepNoAmmo) | |
| i = 1 | |
| ENDIF | |
| IF NOT READ_INT_FROM_INI_FILE "CLEO/Reload Mod.ini" "Settings" "DisableScrollReload" (bDisableScrollReload) | |
| OR NOT READ_INT_FROM_INI_FILE "CLEO/Reload Mod.ini" "Settings" "DisableVehicleAutoReload" (bDisableVehicleAutoReload) | |
| OR NOT READ_INT_FROM_INI_FILE "CLEO/Reload Mod.ini" "Settings" "DisablePickupClipRefill" (bDisablePickupClipRefill) | |
| OR i = 1 | |
| timera = 0 | |
| WHILE timera < 3000 | |
| WAIT 0 | |
| PRINT_STRING_NOW "Error: Fail to read 'Reload Mod.ini'" 1000 | |
| ENDWHILE | |
| TERMINATE_THIS_CUSTOM_SCRIPT | |
| ENDIF | |
| IF bRealisticReload = TRUE | |
| bDisablePickupClipRefill = TRUE | |
| ENDIF | |
| // SAMP Compatibility Check | |
| IF bDisabledOnSAMP = TRUE | |
| IF LOAD_DYNAMIC_LIBRARY "kernel32" (i) | |
| GET_DYNAMIC_LIBRARY_PROCEDURE "GetModuleHandleA" i (j) | |
| IF j > 0 | |
| CALL_FUNCTION_RETURN j 1 0 ("SAMP.dll")(j) | |
| IF j > 0 | |
| FREE_DYNAMIC_LIBRARY i | |
| TERMINATE_THIS_CUSTOM_SCRIPT | |
| ENDIF | |
| ENDIF | |
| FREE_DYNAMIC_LIBRARY i | |
| ENDIF | |
| ENDIF | |
| // KeepNoAmmo Hook | |
| IF bKeepNoAmmo = TRUE | |
| IF LOAD_DYNAMIC_LIBRARY "KeepNoAmmo.SA.asi" (i) | |
| IF GET_DYNAMIC_LIBRARY_PROCEDURE "PatchNoReload" i (j) | |
| CALL_FUNCTION j 0 0 | |
| ENDIF | |
| FREE_DYNAMIC_LIBRARY i | |
| ENDIF | |
| WRITE_MEMORY PATCH_SCROLL_RELOAD 6 (0x90) TRUE | |
| ENDIF | |
| // Memory Patches | |
| IF bRealisticReload = TRUE | |
| WRITE_MEMORY PATCH_VEHICLE_RELOAD 3 (0x90) TRUE | |
| WRITE_MEMORY PATCH_SCROLL_RELOAD 6 (0x90) TRUE | |
| ELSE | |
| IF bDisableScrollReload = TRUE | |
| WRITE_MEMORY PATCH_SCROLL_RELOAD 6 (0x90) TRUE | |
| ENDIF | |
| IF bDisableVehicleAutoReload = TRUE | |
| WRITE_MEMORY PATCH_VEHICLE_RELOAD 3 (0x90) TRUE | |
| ENDIF | |
| ENDIF | |
| // Initialize tracking arrays | |
| iLastCurAmmo[0] = 0 | |
| iLastCurAmmo[1] = 0 | |
| iLastTotalAmmo[0] = 0 | |
| iLastTotalAmmo[1] = 0 | |
| iLastWeapon[0] = 0 | |
| iLastWeapon[1] = 0 | |
| // Main Loop | |
| WHILE TRUE | |
| WAIT 0 | |
| IF IS_PLAYER_CONTROL_ON 0 | |
| GET_PLAYER_CHAR 0 (scplayer) | |
| iCmd = iCmds[0] | |
| iPlayerIdx = 0 | |
| GOSUB ProcessReload | |
| ENDIF | |
| IF IS_2PLAYER_GAME_GOING_ON | |
| IF IS_PLAYER_CONTROL_ON 1 | |
| GET_PLAYER_CHAR 1 (scplayer) | |
| iCmd = iCmds[1] | |
| iPlayerIdx = 1 | |
| GOSUB ProcessReload | |
| ENDIF | |
| ENDIF | |
| ENDWHILE | |
| // Subroutine: Reload Handler | |
| ProcessReload: | |
| IF IS_CHAR_DEAD scplayer | |
| RETURN | |
| ENDIF | |
| // Check button / key press (j stores whether trigger button is pressed) | |
| j = FALSE | |
| IF iCmd <= 19 | |
| IF IS_BUTTON_PRESSED iPlayerIdx iCmd | |
| j = TRUE | |
| ENDIF | |
| ELSE | |
| IF IS_KEY_PRESSED iCmd | |
| j = TRUE | |
| ENDIF | |
| ENDIF | |
| GET_PED_POINTER scplayer (pPed) | |
| i = pPed + OFFSET_PED_ACTIVE_WEAPON_SLOT | |
| READ_MEMORY i 1 FALSE (i) | |
| IF i = 0 | |
| RETURN | |
| ENDIF | |
| pWeapon = i * SIZEOF_CWEAPON | |
| pWeapon += pPed | |
| pWeapon += OFFSET_PED_WEAPONS | |
| GET_CURRENT_CHAR_WEAPON scplayer (iCurWeapon) | |
| // Weapons without reload animations | |
| IF bDisableWeaponsWithoutAnim = TRUE | |
| IF iCurWeapon = WEP_FLAMETHROWER | |
| OR iCurWeapon = WEP_MINIGUN | |
| OR iCurWeapon = WEP_EXTINGUISHER | |
| OR iCurWeapon = WEP_SPRAYCAN | |
| OR iCurWeapon = WEP_CAMERA | |
| RETURN | |
| ENDIF | |
| ENDIF | |
| // Fetch Weapon Capacity & Info | |
| CALL_METHOD_RETURN FUNC_PED_GETSKILL pPed 1 0 (iCurWeapon)(i) | |
| CALL_FUNCTION_RETURN FUNC_WEAPONINFO_GETINFO 2 2 (i iCurWeapon)(pWeaponInfo) | |
| i = pWeaponInfo + OFFSET_WEAPONINFO_CLIP_SIZE | |
| READ_MEMORY i 2 FALSE (iMaxAmmo) | |
| IF iMaxAmmo <= 1 | |
| RETURN | |
| ENDIF | |
| i = pWeapon + OFFSET_WEAPON_AMMO_CLIP | |
| READ_MEMORY i 4 FALSE (iCurAmmo) | |
| i = pWeapon + OFFSET_WEAPON_TOTAL_AMMO | |
| READ_MEMORY i 4 FALSE (iTotalAmmo) | |
| i = pWeapon + OFFSET_WEAPON_STATE | |
| READ_MEMORY i 4 FALSE (iState) | |
| // Pickup Magazine Watcher | |
| // iTotalAmmo includes clip ammo, so a reload never bumps it, only a pickup does. | |
| IF bDisablePickupClipRefill = TRUE | |
| IF iCurWeapon = iLastWeapon[iPlayerIdx] | |
| AND iTotalAmmo > iLastTotalAmmo[iPlayerIdx] | |
| AND iCurAmmo > iLastCurAmmo[iPlayerIdx] | |
| AND NOT iState = 2 | |
| AND iLastTotalAmmo[iPlayerIdx] > 0 | |
| iCurAmmo = iLastCurAmmo[iPlayerIdx] | |
| i = pWeapon + OFFSET_WEAPON_AMMO_CLIP | |
| WRITE_MEMORY i 4 iCurAmmo FALSE | |
| ENDIF | |
| iLastWeapon[iPlayerIdx] = iCurWeapon | |
| iLastCurAmmo[iPlayerIdx] = iCurAmmo | |
| iLastTotalAmmo[iPlayerIdx] = iTotalAmmo | |
| ENDIF | |
| // In a vehicle, reload triggers if the player presses the key OR if the clip hits 0 | |
| IF IS_CHAR_IN_ANY_CAR scplayer | |
| IF j = FALSE | |
| IF NOT iCurAmmo = 0 | |
| RETURN | |
| ENDIF | |
| ENDIF | |
| ELSE | |
| // On foot, reload is triggered strictly via user key press | |
| IF j = FALSE | |
| RETURN | |
| ENDIF | |
| ENDIF | |
| // Abort if clip is already full (and configured not to reload) | |
| IF bDontReloadIfFull = TRUE | |
| IF iCurAmmo = iMaxAmmo | |
| RETURN | |
| ENDIF | |
| ENDIF | |
| // Abort if no reserve ammunition remains | |
| IF iTotalAmmo <= iCurAmmo | |
| RETURN | |
| ENDIF | |
| READ_MEMORY ADDR_TIMER_MS 4 FALSE (iGameTime) | |
| // Vehicle Drive-By Reload Handler | |
| IF IS_CHAR_IN_ANY_CAR scplayer | |
| i = pWeapon + OFFSET_WEAPON_SHOT_TIMER | |
| READ_MEMORY i 4 FALSE (j) | |
| // Still cooling down from a previous shot or reload | |
| IF iGameTime < j | |
| RETURN | |
| ENDIF | |
| CALL_METHOD_RETURN FUNC_WEAPONINFO_GETRELOADTIME pWeaponInfo 0 0 ()(iReloadTime) | |
| j = iGameTime + iReloadTime | |
| i = pWeapon + OFFSET_WEAPON_SHOT_TIMER | |
| WRITE_MEMORY i 4 j FALSE | |
| // Realistic reload: discard active clip bullets | |
| IF bRealisticReload = TRUE | |
| IF iTotalAmmo < 25000 | |
| iTotalAmmo -= iCurAmmo | |
| IF iTotalAmmo < 0 | |
| iTotalAmmo = 0 | |
| ENDIF | |
| i = pWeapon + OFFSET_WEAPON_TOTAL_AMMO | |
| WRITE_MEMORY i 4 iTotalAmmo FALSE | |
| ENDIF | |
| iCurAmmo = 0 | |
| ENDIF | |
| // Refill clip directly | |
| IF iTotalAmmo >= iMaxAmmo | |
| iCurAmmo = iMaxAmmo | |
| ELSE | |
| iCurAmmo = iTotalAmmo | |
| ENDIF | |
| i = pWeapon + OFFSET_WEAPON_AMMO_CLIP | |
| WRITE_MEMORY i 4 iCurAmmo FALSE | |
| IF bDisablePickupClipRefill = TRUE | |
| iLastCurAmmo[iPlayerIdx] = iCurAmmo | |
| iLastTotalAmmo[iPlayerIdx] = iTotalAmmo | |
| ENDIF | |
| RETURN | |
| ENDIF | |
| // On-Foot Reload Handler | |
| IF iState = 2 | |
| RETURN | |
| ENDIF | |
| CALL_METHOD_RETURN FUNC_WEAPONINFO_GETRELOADTIME pWeaponInfo 0 0 ()(iReloadTime) | |
| j = iGameTime + iReloadTime | |
| i = pWeapon + OFFSET_WEAPON_SHOT_TIMER | |
| WRITE_MEMORY i 4 j FALSE | |
| IF bRealisticReload = TRUE | |
| IF iTotalAmmo < 25000 | |
| iTotalAmmo -= iCurAmmo | |
| IF iTotalAmmo < 0 | |
| iTotalAmmo = 0 | |
| ENDIF | |
| i = pWeapon + OFFSET_WEAPON_TOTAL_AMMO | |
| WRITE_MEMORY i 4 iTotalAmmo FALSE | |
| ENDIF | |
| i = pWeapon + OFFSET_WEAPON_AMMO_CLIP | |
| WRITE_MEMORY i 4 0 FALSE | |
| ENDIF | |
| // Initiate On-Foot Reload State | |
| i = pWeapon + OFFSET_WEAPON_STATE | |
| WRITE_MEMORY i 4 2 FALSE | |
| RETURN | |
| } | |
| SCRIPT_END |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Update
most of this was done by Gemini
@JuniorDjjr