Jump to content

R&D Modding Ammo


Amineri

Recommended Posts

Okies, here's the initial draft of hex changes to implement the new ammo system:

 

 

 

All hex changes for Ammo Cost mod
Change XGWeapon.ApplyAmmoCost to deal with remainders
original hex:
52 B9 00 00 50 55 00 00 00 00 00 00 3C B9 00 00 00 00 00 00 00 00 00 00 3D B9 00 00 00 00 00 00 D9 00 00 00 45 1A 00 00 31 00 00 00 21 00 00 00 A2 01 1E B9 00 00 00 3D B9 00 00 16 07 2E 00 9A 01 1E B9 00 00 26 16 0F 01 1E B9 00 00 25 04 0B 53
new hex: (virtual 0x2D)
52 B9 00 00 50 55 00 00 00 00 00 00 3C B9 00 00 00 00 00 00 00 00 00 00 3D B9 00 00 00 00 00 00 D9 00 00 00 45 1A 00 00 2D 00 00 00 21 00 00 00 07 26 00 98 A2 01 1E B9 00 00 00 3D B9 00 00 16 2C 04 16 0F 01 1E B9 00 00 25 04 0B 0B 0B 0B 0B 53
---------------------------------------------
Change XGAbilityTree.ApplyActionCost to call XGAbility_Targeted.GraduatedOdds instead of XGTacticalGameCore.GetAmmoCost
original hex for just function: (next 0x1EB)
iCost = XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.GetAmmoCost(kAbility.m_kWeapon.GameplayType(), kAbility.GetType(), kAbility.m_kUnit.GetPlayer().HasFoundryHistory(10), kAbility.m_kUnit.GetCharacter().m_kChar, kAbility.m_bReactionFire); (259 file, 379 virtual bytes -- 120 extra)
0F 00 C3 7E 00 00 19 19 2E FE 2C 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF 09 00 F0 2C 00 00 00 01 F0 2C 00 00 13 01 42 10 00 00 00 1B 16 31 00 00 00 00 00 00 38 3A 19 19 00 C4 7E 00 00 09 00 E8 BB 00 00 00 01 E8 BB 00 00 0A 00 E8 9B 00 00 00 1B 92 30 00 00 00 00 00 00 16 19 00 C4 7E 00 00 0A 00 1C 7C 00 00 00 1B 1E 35 00 00 00 00 00 00 16 19 19 19 00 C4 7E 00 00 09 00 E6 7B 00 00 00 01 E6 7B 00 00 0A 00 EB B2 00 00 00 1B 0A 34 00 00 00 00 00 00 16 0C 00 9E 94 00 00 00 1B 7A 36 00 00 00 00 00 00 24 0A 16 19 19 19 00 C4 7E 00 00 09 00 E6 7B 00 00 00 01 E6 7B 00 00 0A 00 63 B4 00 00 00 1B 7B 31 00 00 00 00 00 00 16 09 00 C3 A2 00 00 00 01 C3 A2 00 00 19 00 C4 7E 00 00 0A 00 D2 7B 00 00 00 2D 01 D2 7B 00 00 16
new function call: (next 0x1EB)
iCost = kAbility.GraduatedOdds(0, 0, kAbility.m_kUnit.GetPlayer().HasFoundryHistory(10)); (89 file, 121 virtual bytes -- 32 extra)
0F 00 C3 7E 00 00 19 00 C4 7E 00 00 5A 00 B9 7C 00 00 00 1B E1 35 00 00 00 00 00 00 2C 00 2C 00 19 19 19 00 C4 7E 00 00 09 00 E6 7B 00 00 00 01 E6 7B 00 00 0A 00 EB B2 00 00 00 1B 0A 34 00 00 00 00 00 00 16 0C 00 9E 94 00 00 00 1B 7A 36 00 00 00 00 00 00 24 0A 16 16 0B 0B 0B 0B 0B 0B 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 00 C3 7E 00 00 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B
---------------------------------------------
Alter UITacticalHUD_WeaponPanel.SetWeaponAndAmmo to call XGAbility_Targeted.GraduatedOdds instead of XGTacticalGameCore.GetAmmoCost
****TWO IDENTICAL CALLS****
call 2 hex: (identical to call 1 ) (254 file, 370 virtual bytes -- 116 additional)
myValue.N = float(XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.GetAmmoCost(kTAbility.m_kWeapon.GameplayType(), kTAbility.GetType(), kTAbility.m_kUnit.GetPlayer().HasFoundryHistory(10), kTAbility.m_kUnit.GetCharacter().m_kChar));
0F 35 C8 FC FF FF 32 F9 FF FF 00 01 00 72 27 00 00 38 3F 19 19 2E FE 2C 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF 09 00 F0 2C 00 00 00 01 F0 2C 00 00 F5 00 42 10 00 00 00 1B 16 31 00 00 00 00 00 00 38 3A 19 19 00 70 27 00 00 09 00 E8 BB 00 00 00 01 E8 BB 00 00 0A 00 E8 9B 00 00 00 1B 92 30 00 00 00 00 00 00 16 19 00 70 27 00 00 0A 00 1C 7C 00 00 00 1B 1E 35 00 00 00 00 00 00 16 19 19 19 00 70 27 00 00 09 00 E6 7B 00 00 00 01 E6 7B 00 00 0A 00 EB B2 00 00 00 1B 0A 34 00 00 00 00 00 00 16 0C 00 9E 94 00 00 00 1B 7A 36 00 00 00 00 00 00 24 0A 16 19 19 19 00 70 27 00 00 09 00 E6 7B 00 00 00 01 E6 7B 00 00 0A 00 63 B4 00 00 00 1B 7B 31 00 00 00 00 00 00 16 09 00 C3 A2 00 00 00 01 C3 A2 00 00 4A 16
new function call:
myValue.N = float(kTAbility.GraduatedOdds(0, 0, kTAbility.m_kUnit.GetPlayer().HasFoundryHistory(10))); (100 file, 140 virtual bytes -- 40 extra)
0F 35 C8 FC FF FF 32 F9 FF FF 00 01 00 72 27 00 00 19 00 70 27 00 00 5A 00 B9 7C 00 00 00 1B E1 35 00 00 00 00 00 00 2C 00 2C 00 19 19 19 00 70 27 00 00 09 00 E6 7B 00 00 00 01 E6 7B 00 00 0A 00 EB B2 00 00 00 1B 0A 34 00 00 00 00 00 00 16 0C 00 9E 94 00 00 00 1B 7A 36 00 00 00 00 00 00 24 0A 16 16 0B 0B 0B 0B 0B 0B 0B 00 70 27 00 00 00 70 27 00 00 00 70 27 00 00 00 70 27 00 00 00 70 27 00 00 00 70 27 00 00 00 70 27 00 00 00 70 27 00 00 00 70 27 00 00 00 70 27 00 00 00 70 27 00 00 00 70 27 00 00 00 70 27 00 00 00 70 27 00 00 00 70 27 00 00 00 70 27 00 00 00 70 27 00 00 00 70 27 00 00 00 70 27 00 00 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B
---------------------------------------------
Rewrite XGUnit.ReactionWeaponCheck to call XGAbility_Targeted.GraduatedOdds instead of XGTacticalGameCore.GetAmmoCost
original hex:
CA B7 00 00 50 55 00 00 00 00 00 00 B3 B7 00 00 00 00 00 00 00 00 00 00 B5 B7 00 00 00 00 00 00 F6 31 00 00 88 45 06 00 5F 01 00 00 07 01 00 00 0F 00 B4 B7 00 00 19 1B CC 32 00 00 00 00 00 00 16 0A 00 2C 0A 00 00 00 1B ED 30 00 00 00 00 00 00 16 07 3B 00 72 00 B4 B7 00 00 2A 16 04 28 07 2E 01 96 19 00 B4 B7 00 00 0A 00 3B B9 00 00 00 1B 6A 34 00 00 00 00 00 00 16 19 19 2E FE 2C 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF 09 00 F0 2C 00 00 00 01 F0 2C 00 00 6F 00 42 10 00 00 00 1B 16 31 00 00 00 00 00 00 38 3A 19 00 B4 B7 00 00 0A 00 E8 9B 00 00 00 1B 92 30 00 00 00 00 00 00 16 2C 07 19 1B 0A 34 00 00 00 00 00 00 16 0C 00 9E 94 00 00 00 1B 7A 36 00 00 00 00 00 00 24 0A 16 19 1B 7B 31 00 00 00 00 00 00 16 09 00 C3 A2 00 00 00 01 C3 A2 00 00 27 16 16 04 28 07 52 01 19 00 B4 B7 00 00 0A 00 47 B9 00 00 00 1B F8 3D 00 00 00 00 00 00 16 04 28 04 27 04 3A B5 B7 00 00 53
new hex: (virtual 0x15B)
CA B7 00 00 50 55 00 00 00 00 00 00 B3 B7 00 00 00 00 00 00 00 00 00 00 B5 B7 00 00 00 00 00 00 F6 31 00 00 88 45 06 00 5B 01 00 00 07 01 00 00 0F 00 B4 B7 00 00 19 1B CC 32 00 00 00 00 00 00 16 0A 00 2C 0A 00 00 00 1B ED 30 00 00 00 00 00 00 16 07 3B 00 72 00 B4 B7 00 00 2A 16 04 28 0F 00 54 B7 00 00 9E 35 9C 0D 00 00 AA 0D 00 00 00 00 19 00 B4 B7 00 00 09 00 14 B9 00 00 00 01 14 B9 00 00 94 1A 2C 0C 35 D1 0D 00 00 D5 0D 00 00 00 01 19 01 0A 31 00 00 09 00 C3 A2 00 00 00 01 C3 A2 00 00 2C 10 16 16 07 2E 01 96 19 00 B4 B7 00 00 0A 00 3B B9 00 00 00 1B 6A 34 00 00 00 00 00 00 16 12 20 66 7D 00 00 37 00 BC 7C 00 00 00 1B E1 35 00 00 00 00 00 00 00 54 B7 00 00 2C 00 19 1B 0A 34 00 00 00 00 00 00 16 0C 00 9E 94 00 00 00 1B 7A 36 00 00 00 00 00 00 24 0A 16 16 16 04 28 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 04 27 04 3A B5 B7 00 00 53
---------------------------------------------
Rewrite XGAbility_Targeted.GraduatedOdds into the new Ammo Costing function
original hex:
D4 7C 00 00 50 55 00 00 00 00 00 00 B8 7C 00 00 00 00 00 00 00 00 00 00 BF 7C 00 00 00 00 00 00 73 02 00 00 CF 54 00 00 3D 04 00 00 0D 03 00 00 0F 00 BA 7C 00 00 19 19 00 BE 7C 00 00 0A 00 56 94 00 00 00 1B C5 34 00 00 00 00 00 00 16 0A 00 40 AC 00 00 00 1B 95 33 00 00 00 00 00 00 16 07 F2 01 19 19 19 2E 64 2D 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF 09 00 71 2D 00 00 00 01 71 2D 00 00 09 00 A3 9C 00 00 00 01 A3 9C 00 00 0A 00 A8 9F 00 00 00 2D 01 A8 9F 00 00 07 F2 01 82 81 19 01 E6 7B 00 00 0A 00 B5 32 00 00 00 1B DB 3D 00 00 00 00 00 00 16 16 18 21 00 19 1B 38 34 00 00 00 00 00 00 16 0A 00 B5 32 00 00 00 1B DB 3D 00 00 00 00 00 00 16 16 07 F2 01 82 82 2D 00 BD 7C 00 00 18 5F 00 77 19 2E 64 2D 00 00 2E FE 2C 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF 09 00 69 2D 00 00 00 01 69 2D 00 00 2A 16 16 18 74 00 81 19 19 2E 64 2D 00 00 2E FE 2C 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF 09 00 69 2D 00 00 00 01 69 2D 00 00 0A 00 97 4C 00 00 00 2D 01 97 4C 00 00 16 16 04 25 07 08 02 99 00 BA 7C 00 00 2C 04 16 04 1D FF FF FF FF 0F 00 B9 7C 00 00 93 F9 2C 04 19 19 00 BE 7C 00 00 0A 00 56 94 00 00 00 1B C5 34 00 00 00 00 00 00 16 0A 00 87 AC 00 00 00 1B AD 33 00 00 00 00 00 00 16 16 00 BA 7C 00 00 16 07 39 03 82 82 19 01 E6 7B 00 00 0A 00 B5 32 00 00 00 1B DB 3D 00 00 00 00 00 00 16 18 23 00 81 19 1B 38 34 00 00 00 00 00 00 16 0A 00 B5 32 00 00 00 1B DB 3D 00 00 00 00 00 00 16 16 16 18 0D 00 97 00 BF 7C 00 00 25 16 16 0F 00 BB 7C 00 00 91 00 BF 7C 00 00 2C 05 16 07 1E 03 99 00 BF 7C 00 00 2C 32 16 A1 00 BB 7C 00 00 F9 2C 1E 90 19 19 01 E6 7B 00 00 0A 00 EB B2 00 00 00 1B 0A 34 00 00 00 00 00 00 16 09 00 DB 93 00 00 00 01 DB 93 00 00 2C 0F 16 16 16 A1 00 BB 7C 00 00 90 00 B9 7C 00 00 2C 0F 16 16 06 18 04 07 18 04 82 81 19 01 E6 7B 00 00 0A 00 B5 32 00 00 00 1B DB 3D 00 00 00 00 00 00 16 16 18 21 00 19 1B 38 34 00 00 00 00 00 00 16 0A 00 B5 32 00 00 00 1B DB 3D 00 00 00 00 00 00 16 16 0F 00 BB 7C 00 00 90 8F 19 19 1B 38 34 00 00 00 00 00 00 16 0A 00 EB B2 00 00 00 1B 0A 34 00 00 00 00 00 00 16 09 00 DC 93 00 00 00 01 DC 93 00 00 16 2C 0A 16 07 FD 03 82 9A 00 BA 7C 00 00 26 16 18 0B 00 2D 00 BD 7C 00 00 16 0F 00 BB 7C 00 00 8F 00 BF 7C 00 00 16 06 18 04 A1 00 BB 7C 00 00 90 00 B9 7C 00 00 1D E7 FF FF FF 16 16 04 FB 92 00 BF 7C 00 00 00 BB 7C 00 00 16 25 2C 64 16 04 3A BC 7C 00 00 53
new hex : (virtual 0x3C5)
D4 7C 00 00 50 55 00 00 00 00 00 00 B8 7C 00 00 00 00 00 00 00 00 00 00 BF 7C 00 00 00 00 00 00 73 02 00 00 CF 54 00 00 C5 03 00 00 0D 03 00 00 0F 00 BB 7C 00 00 25 07 37 00 9B 00 BF 7C 00 00 25 16 0F 00 BB 7C 00 00 9C 00 BF 7C 00 00 1D FF FF 00 00 16 06 CD 00 07 48 00 72 01 E8 BB 00 00 2A 16 04 25 07 6E 00 19 01 E8 BB 00 00 0C 00 4F B9 00 00 00 1B 9A 36 00 00 00 00 00 00 2C 0A 16 04 25 07 92 00 19 01 E8 BB 00 00 0A 00 4D B9 00 00 00 1B D6 3D 00 00 00 00 00 00 16 04 25 0F 00 BB 7C 00 00 35 9C 0D 00 00 AA 0D 00 00 00 00 19 01 E8 BB 00 00 09 00 14 B9 00 00 00 01 14 B9 00 00 07 F6 00 81 2D 00 BD 7C 00 00 16 0F 00 B9 7C 00 00 FD 00 BB 7C 00 00 2C 64 16 06 0D 01 0F 00 B9 7C 00 00 91 00 BB 7C 00 00 2C 64 16 07 3A 01 9B 00 BF 7C 00 00 25 16 0F 00 BA 7C 00 00 9C 95 00 BF 7C 00 00 2C 10 16 2C FF 16 06 8D 01 0F 00 BA 7C 00 00 1A 2C 0C 35 D1 0D 00 00 D5 0D 00 00 00 01 19 19 01 E6 7B 00 00 09 00 0A 31 00 00 00 01 0A 31 00 00 09 00 C3 A2 00 00 00 01 C3 A2 00 00 07 AC 01 97 9C 00 BA 7C 00 00 26 16 25 16 A1 00 B9 7C 00 00 2C 02 16 07 DA 01 97 9C 00 BA 7C 00 00 2C FE 16 25 16 A1 00 B9 7C 00 00 90 2C 01 95 00 BA 7C 00 00 26 16 16 16 0F 00 B9 7C 00 00 FA 00 B9 7C 00 00 2C 01 16 0F 00 BB 7C 00 00 91 2C 64 00 B9 7C 00 00 16 07 67 02 9A 00 BF 7C 00 00 25 16 07 3F 02 9A 1B 1E 35 00 00 00 00 00 00 16 2C 11 16 0F 00 BB 7C 00 00 90 2C 02 00 BB 7C 00 00 16 07 67 02 9A 1B 1E 35 00 00 00 00 00 00 16 2C 0C 16 0F 00 BB 7C 00 00 90 2C 01 00 BB 7C 00 00 16 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 0B 04 00 BB 7C 00 00 53
-----------------------------------------
Disable call to GraduatedOdds in XGAbility_Targeted.AdjustToHit
Change first conditional from:
if(kPlayer.m_bCantLose || XComTacticalGRI(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kBattle.m_kDesc.m_iDifficulty == 0)
07 C2 02 84 19 00 C1 7C 00 00 0A 00 D9 93 00 00 00 2D 01 D9 93 00 00 18 80 00 9A 19 19 19 2E 64 2D 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF 09 00 71 2D 00 00 00 01 71 2D 00 00 09 00 A3 9C 00 00 00 01 A3 9C 00 00 09 00 B2 9F 00 00 00 01 B2 9F 00 00 25 16 16
to:
if(kPlayer.m_bCantLose && XComTacticalGRI(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kBattle.m_kDesc.m_iDifficulty < 0)
07 C2 02 82 19 00 C1 7C 00 00 0A 00 D9 93 00 00 00 2D 01 D9 93 00 00 18 80 00 96 19 19 19 2E 64 2D 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF 09 00 71 2D 00 00 00 01 71 2D 00 00 09 00 A3 9C 00 00 00 01 A3 9C 00 00 09 00 B2 9F 00 00 00 01 B2 9F 00 00 25 16 16

 

 

 

  • ApplyAmmoCost is updated to discard remainders that are 4 or less.
  • Functions that call GetAmmoCost are modified to call GraduatedOdds
  • GraduatedOdds is rewritten to calculate ammo cost
  • XGAbility_Targeted.AdjustToHit is changed to disallow call to GraduatedOdds

To set ammo costs per weapon use the iSuppression field in the Weapons= array in the DGC.ini. Usage is 100*(shots with A.C.) + shots without A.C.

 

To make an LMG with 5 shots regularly and 8 after Ammo Conservation foundry project would be:

iSuppression = 805,

 

If the value is not set (defaults to 0), a default of 1 shot before reload is used.

 

Values over 12 will work inconsistently due to round-off errors (e.g. trying to set 13 shots will result in 14 shots).

 

Extra ammo used for Suppression and Flush is set directly in the hex code in GraduatedOdds. Default is 2x for Suppression and 1x for Flush.

 

Perk 12 is set up to grant extra shots (currently perk 12 = ButtonUp is unused). Current default is that each item granting perk 12 will grant +1 shot, while the perk selected from the perk tree will grant +2 shots. This is applied AFTER ammo conservation. This will grant extra ammo to both main and pistol (if available) weapons.

 

With the above LMG (5 shots or 8 shots), if the perk 12 "extra ammo" were selected the soldier would have 7 shots or 10 shots.

 

Note that configurations that allow the total number of shots to exceed 12 through Foundry projects, perks and items will cause the above glitch (although at the point of having 13 or 14 shots it is so many as to be effectively unlimited in one mission)

 

-------------------------------------

 

Testing completed:

  • Regular shots fire correctly without crashing
  • Individual weapons can have ammo usage set independently
  • Reaction Fire shots fire correctly without crashing
  • Ammo Conservation project works correctly (credit : Yzaxtol)
  • Unlimited Ammo property works correctly (credit : Yzaxtol)
  • Perk 12 on item grants +1 max shot (credit : johnnylump)

 

Testing still required:

  • Verify that Suppression uses correct ammo
  • Verify that Flush uses correct ammo
  • Verify that perk 12 in perk tree increases ammo correctly

Known glitches:

  • Sectoids appear to have unlimited ammo regardless of settings

Side Effects:

  • Hit bonuses on easy mode and tutorial (calculated in Graduated Odds) are removed
Edited by Amineri
Link to comment
Share on other sites

  • Replies 71
  • Created
  • Last Reply

Top Posters In This Topic

The ammo works with the Ammo Conservation project exactly as designed.

 

Also Unlimited Ammo Property still works.

 

Right ... I did add in conditions so that weapons with Unlimited Ammo property and Melee weapons return 0 ammo used.

 

Technically the reaction fire check to see if sufficient ammo is remaining doesn't check Unlimited Ammo, but since an Unlimited Ammo weapon will always have enough ammo to pass the check it should be fine. (the reaction check doesn't apply the result, it only checks)

 

For those interested, here is what the final function came out as:

 

 

 

function int GraduatedOdds(int iHitChance, XGPlayer kHumanPlayer, bool bCantLose)
{
    local int iAdjustment, iSoldiers, iFactor;

	iAdjustment = 0; 
	if(iHitChance != 0) // check for passed ammo/perk info
	{
		iAdjustment = iHitChance & 0xFFFF;  // use passed ammo info
	}
	else
	{
		if(m_kWeapon == none)
		{
			return 0;
		}	
		if(m_kWeapon.HasProperty(eWP_UnlimitedAmmo)) ((10))
		{
			return 0;
		}
		if(m_kWeapon.IsMelee())
		{
			return 0;
		}
		iAdjustment = m_kWeapon.m_kTWeapon.iSuppression; // retrieve weapon ammo info if none was supplied in parameter
	}
	if(!bCantLose) // doesn't have bHasAmmoConservation
	{
		iFactor = iAdjustment % 100; // get NumShots -- no Ammo Conservation
	}
	else // has ammo conservation
	{
		iFactor = iAdjustment / 100; // get NumShots -- w/ Ammo Conservation
	}
	if(iHitChance != 0) // check for passed ammo/perk info
	{
		iSoldiers = (iHitChance >> 16) & 0xFF; //use passed perk info
	}
	else
		iSoldiers = m_kUnit.m_kCharacter.m_kChar.aUpgrades[12]; // store perk 12 (vanilla ButtonUp) for later checks
	}
	if ((iSoldiers & 1) >  0) // explicitly test for perk 12 (vanilla ButtonUp) assigned through perk tree
	{
		iFactor += 2; // add 2 shots for perk -- can be customized separately from item count
	}
	if(iSoldiers & 254) >  0) // explicitly test for perk 12 (vanilla ButtonUp) assigned via items
	{
		iFactor += 1*(iSoldiers >> 1); // add shots equal to the number of equipped items
	}
	iFactor = Max(iFactor, 1); // prevent divide-by-zero errors
	iAdjustment = 100 / iFactor; // convert NumShots into Ammo Used -- valid for 12 or fewer shots
	if(iHitChance == 0)
	{
		if (GetType() == eAbility_ShotSuppress) ((17))
		{
			iAdjustment = 2 * iAdjustment;
		}
		if (GetType() == eAbility_ShotFlush) ((12))
		{
			iAdjustment = 1 * iAdjustment;
		}
	}
	return iAdjustment;
}
 

 

 

 

I had to mutate it a bit because the reaction fire check doesn't have access to a class'XGAbility_Targeted'. So, instead that function packs the iSuppression ammo info and perk information into one byte and passes that info through the iHitChance parameter.

 

The XGAbility_Targeted class isn't replicated, so I had to do a class'XGAbility_Targeted'.static.GraduatedOdds call for the reaction fire weapon test, meaning that no specific information was available from within the function -- only the parameters passed can be used.

 

The other calls all use the kAbility.GraduatedOdds(0, 0, bool) style call instead, and the function retrieves information about the weapon based on the weapon attached to the current ability.

Link to comment
Share on other sites

What happens if a soldier has both an item with perk 12 and the actual perk 12 ?

 

They add together :D

 

At least, that was the intention (hasn't been tested yet)

NumShots = BaseNum + 2 (if HasRealPerk) + 1 * NumAmmoItems

Each ammo item adds 1 additional shot, so you can see it can be a bit easy with Ammo Conservation, the perk, and a couple of items to get quite a few shots!

 

BaseNum is either with or without Ammo Conservation foundry project.

 

Each ammo item equipped adds 2 to the aUpgrades perk array, so the Ammo function divides by 2 to get the number of items. The actual perk is the only thing that can set bit 0 of aUpgrades, so that is tested explicitly to grant a special extra number of shots.

 

---------------

 

Oh, and I picked "ButtonUp" (perk 12) just because it was the first one in BuildPerkArray. I don't know if there is a good icon for this. If there is, and its icon string has more than 8 characters, it can be easily swapped to another unused perk ID with a larger string.

Link to comment
Share on other sites

The Ammo system is in the v1.4 Merciless beta, one note on the Disabling Shot bug. The aliens will use the same ammo for their weapons as the XCOM do, as it's an iValue which their weapons don't pull from their own set of stats.

 

So the choice really is between having the aliens with terrible ammo and AI, or removing Disabling Shot. :(

Link to comment
Share on other sites

There's probably a rounding error with 6 shots, as rifles have a large bit left but says they don't have enough ammo?

 

100/6 = 16.66

17*6 = 102

 

Might also be an issue with 8 shots.

 

100/8 = 12.5

13*8 = 104

 

3, 7,9 will probably be fine as they round down.

Link to comment
Share on other sites

That shouldn't be the case -- dividing two integers drops the remainder without rounding, so 100/6 should return 16, and 100/8 returns 12, not 17 and 13, so in both cases you should be at 4% left when out of shots, which is treated as zero.

 

And are we sure disabling shot doesn't work on aliens with unlimited ammo? My question was hypothetical way back when -- I was concerned about suppression preventing aliens from taking the reload action when weapon is disabled ...

Link to comment
Share on other sites

I based this on this snippet of code in XGAbility_DisablingShot.DoDisablingShotEffects:

if(kWeapon.ItemType() == 39 || (!XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.WeaponHasProperty(iWeaponType, 13) && (!XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.WeaponHasProperty(iWeaponType, 10))))
{
	kWeapon.iAmmo = 0;
	bDisabled = true;
}

Stripped down/ decode the conditions says:

  • Item is SectoidPlasmaPistol OR
  • Weapon is NOT melee AND
  • Weapon does NOT have Unlimited Ammo

I found this when I was cataloguing what the various weapon properties do.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...