-
-
Save SandeMC/4c6d52a05f71af24702eaa28f6b692cf to your computer and use it in GitHub Desktop.
| // 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 |
The disabled weapons are checked by ID, if this is important (what is the issue? CJ does some animation that does nothing?), is better to change it to check by flags (I don't know exactly, need to do some research), because whatever you can reload or not is defined by flag (check weapon.dat). That way will be adapted for added weapons without replacing or weapon mods that may make it possible/impossible to reload some gun.
what is the issue? CJ does some animation that does nothing?
There's no animation at all, the ammo count just gets refilled (and the ones disabled do have a magazine for whatever reason)
I left a comment in the libertycity page but I'll copy paste here too and include a video:
I have a bug that I also had with Junior_Djjr's version where if I empty the clip of a gun and then immediately swap weapons (before the reload), when I go back to that gun it will appear as reloaded and will do the shooting animations but no actual bullets will be shot and no sound will play either, basically softlocking this gun. I'm using the KeepNoAmmo integration (this bug doesn't seem to happen without it).
gta.mp4
I would also love if there was an option to make it so you can't reload by swapping weapons, this way you'll always have to press R and go through the reload animation to reload a weapon.
I left a comment in the libertycity page but I'll copy paste here too and include a video: I have a bug that I also had with Junior_Djjr's version where if I empty the clip of a gun and then immediately swap weapons (before the reload), when I go back to that gun it will appear as reloaded and will do the shooting animations but no actual bullets will be shot and no sound will play either, basically softlocking this gun. I'm using the KeepNoAmmo integration (this bug doesn't seem to happen without it).
gta.mp4
I would also love if there was an option to make it so you can't reload by swapping weapons, this way you'll always have to press R and go through the reload animation to reload a weapon.
I think it's a bug with KeepNoAmmo script itself rather than mine - I don't think I can fix it
The only way to fix it would be to avoid restoring ammo when switching weapons, but I have no idea how to implement that and the only script that did online doesn't have some source code to look at
@The-Haxor Hey, try the updated version, I've found some code I could put
But this is already fixed by MixSets.
I want everything related to the script to be a part of the same script - telling people to download multiple mods just to fix a bug isn't it
I want everything related to the script to be a part of the same script - telling people to download multiple mods just to fix a bug isn't it
I think you don't know MixSets. The goal of MixSets is literally what you said right now, is almost 300 tweak options (including dozens of fixes) in the same mod so people don't need to download multiple mods to fix the game.
So, just like you said, use MixSets instead of adding multiple mods to fix the game.
I want everything related to the script to be a part of the same script - telling people to download multiple mods just to fix a bug isn't it
I think you don't know MixSets. The goal of MixSets is literally what you said right now, is almost 300 tweak options (including dozens of fixes) in the same mod so people don't need to download multiple mods to fix the game.
So, just like you said, use MixSets instead of adding multiple mods to fix the game.
I think you didn't understand the problem. It comes from KeepNoAmmo and Reload Mod cross-compatibility - we don't have MixSets installed here (let's assume we don't, anyway). When the ammo stays at 0 it doesn't auto-reload and KeepNoAmmo expects that - but it breaks when the ammo refills by scrolling the wheel.
What you suggest is for that person to install MixSets (again, in the scenario let's assume it isn't already) just to fix the issue that comes from two existing mods, whereas I can simply integrate it into this script and keep it at two. Which I did.
P.S. I do agree that MixSets is great, but I want this to work without MixSets aswell
I want everything related to the script to be a part of the same script - telling people to download multiple mods just to fix a bug isn't it
I think you don't know MixSets. The goal of MixSets is literally what you said right now, is almost 300 tweak options (including dozens of fixes) in the same mod so people don't need to download multiple mods to fix the game.
So, just like you said, use MixSets instead of adding multiple mods to fix the game.I think you didn't understand the problem. It comes from KeepNoAmmo and Reload Mod cross-compatibility - we don't have MixSets installed here (let's assume we don't, anyway). When the ammo stays at 0 it doesn't auto-reload and KeepNoAmmo expects that - but it breaks when the ammo refills by scrolling the wheel.
What you suggest is for that person to install MixSets (again, in the scenario let's assume it isn't already) just to fix the issue that comes from two existing mods, whereas I can simply integrate it into this script and keep it at two. Which I did.
P.S. I do agree that MixSets is great, but I want this to work without MixSets aswell
Ah, is another additional issue, because refilling by scroll wheel is a native issue, so we now also have a new issue besides of that.
But is fixed if use MixSets, right?
@The-Haxor Hey, try the updated version, I've found some code I could put
I was only able to test it briefly but it looks like the new functionality and the bug fix both work! The mod is like 200% better now! For me, at least.
I didn't know MixSets let you disable switch reloading. I have MixSets on the backlog of mods that I wanted to check out, it just had such a long list of changes that I had been putting it off because just thinking about fully configuring it gave me a headache.
Now there's only one small thing left that's bugging me. Although I think this is technically a problem with the vanilla game, it becomes more apparent when using the mod. If you reload and, while the animation is going, you see something you wanna shoot at and you aim at it, the reload gets cancelled and then plays a second time, which wastes times and throws me off. I did a quick search and I believe MixSets doesn't fix this.
Edit: actually, it looks like more things can cancel the reload animation. If you're crouched and not moving when you start reloading then moving or standing up can cancel it too. This game is kinda annoying.
I also noticed a thing that could be a bit more relevant. In vanilla, when you walk over a weapon on the ground, doing so still puts bullets in your mag so it removes the need for reloading in some cases.
Now there's only one small thing left that's bugging me. Although I think this is technically a problem with the vanilla game, it becomes more apparent when using the mod. If you reload and, while the animation is going, you see something you wanna shoot at and you aim at it, the reload gets cancelled and then plays a second time, which wastes times and throws me off. I did a quick search and I believe MixSets doesn't fix this.
Edit: actually, it looks like more things can cancel the reload animation. If you're crouched and not moving when you start reloading then moving or standing up can cancel it too. This game is kinda annoying.
I also noticed a thing that could be a bit more relevant. In vanilla, when you walk over a weapon on the ground, doing so still puts bullets in your mag so it removes the need for reloading in some cases.
I'm afraid I can't fix either of these, sadly
I think I found an actual bug now. When using the country rifle only the first shot works. This is the config I'm using:
DisabledOnSAMP = 1
DontReloadIfFull = 1
RealisticReload = 0
DisableScrollReload = 1
KeepNoAmmo = 1
Doesn't seem to happen without KeepNoAmmo.
I think I found an actual bug now. When using the country rifle only the first shot works. This is the config I'm using: DisabledOnSAMP = 1 DontReloadIfFull = 1 RealisticReload = 0 DisableScrollReload = 1 KeepNoAmmo = 1
Doesn't seem to happen without KeepNoAmmo.
This seems to be a bug with KeepNoAmmo itself - in particular, the asi file, which has no source code, so I can't tackle on it.
At least I think that's the case.
Unlucky. I guess I can just uninstall KeepNoAmmo then. Only wanted it for being able to empty the mag and switch quickly but I guess I'll live without it. Vanilla game animation cancels are more annoying
I updated the official download
@JuniorDjjr In the MixMods upload, you accidentally removed the [Controls] category, which breaks the mod

Update
- Added a new option, DisableVehicleAutoReload (per request on LibertyCity)
- Readjusted forced options
- KeepNoAmmo forces scroll reloading to be disabled
- RealisticReload forces scroll reloading and vehicle autoreloading to be disabled
@JuniorDjjr Update the MixMods upload when you're free, thanks
Take note of the new option
Update
- Added a new option, DisablePickupClipRefill
- Cleaned up code and made use of new gta3sc features (could improve perf)
- Reimplemented vehicle driveby logic
- Infinite ammo fixes
- Universal single-ammo weapon implementation
- Two-player mode fix: both players can reload at the same time now
most of this was done by Gemini
Changes:
Additions:
Download: https://www.mediafire.com/file/6f5fkxi2b9ma4yo/Reload_Mod_Fixed.zip/file