Created
March 10, 2021 18:52
-
-
Save s0md3v/90637ef45d0ff23b9bfb86ec9b47fdd7 to your computer and use it in GitHub Desktop.
poc for cod mobile gunsmith helper
This file contains 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
# Author: Somdev Sangwan (@s0md3v) | |
# | |
# GPL v3 License | |
# Copyright 2021 Somdev Sangwan | |
import itertools | |
attachments = { | |
'tactical suppressor': { | |
'type': 'muzzle', | |
'changes': ['+5 ads_time', '-5 ads_move_speed'] | |
}, | |
'owc light suppressor': { | |
'type': 'muzzle', | |
'changes': ['-20 range'] | |
}, | |
'owc light compensator': { | |
'type': 'muzzle', | |
'changes': ['-11.1 v_recoil', '-7 h_recoil', '+6 ads_time', '+8 ads_spread'] | |
}, | |
'mip light flash guard': { | |
'type': 'muzzle', | |
'changes': ['-9.2 ads_spread', '-7.7 hip_spread', '+5 ads_time'] | |
}, | |
'rtc light muzzle brake': { | |
'type': 'muzzle', | |
'changes': ['-10.5 h_recoil', '-7.8 v_recoil', '+5 ads_time', '+8 ads_spread'] | |
}, | |
'monolithic suppressor': { | |
'type': 'muzzle', | |
'changes': ['+25 range', '+7 ads_spread', '+7 ads_time', '-5 ads_move_speed'] | |
}, | |
'mip light': { | |
'type': 'barrel', | |
'changes': ['-10 ads_time', '+8 ads_spread'], | |
}, | |
'mip light barrel (short)': { | |
'type': 'barrel', | |
'changes': ['-12 ads_time', '+3 move_speed', '+3 ads_spread', '+11.2 v_recoil'], | |
}, | |
'owc marksman': { | |
'type': 'barrel', | |
'changes': ['-8 ads_spread', '+30 range', '-16.5 h_recoil', '5.9 v_recoil'] | |
}, | |
'ykm light stock': { | |
'type': 'stock', | |
'changes': ['+25 ads_move_speed', '+6.7 ads_spread'], | |
}, | |
'ykm combat stock': { | |
'type': 'stock', | |
'changes': ['-8 ads_time', '+6.5 ads_spread', '+6 flinch', '+3.9 v_recoil'], | |
}, | |
'mip strike stock': { | |
'type': 'stock', | |
'changes': ['-7.5 ads_spread', '-10 flinch', '-8 h_recoil', '+12 ads_time', '-15 ads_move_speed'], | |
}, | |
'no stock': { | |
'type': 'stock', | |
'changes': ['-13 ads_time', '+3 move_speed', '+9.6 ads_spread', '+8 flinch', '+12.9 v_recoil'] | |
}, | |
'enchanced bolt': { | |
'type': 'perk', | |
'changes': ['-13 fire_interval'], | |
}, | |
'sleight of hand': { | |
'type': 'perk', | |
'changes': ['-15 reload_time'] | |
}, | |
'owc laser - tactical': { | |
'type': 'laser', | |
'changes': ['-9 ads_time', '-9.4 ads_spread'], | |
}, | |
'rtc laser 1mw': { | |
'type': 'laser', | |
'changes': ['-14.5 hip_spread'], | |
}, | |
'mip laser 5mw': { | |
'type': 'laser', | |
'changes': ['-13.5 hip_spread', '-25 fire_delay'] | |
}, | |
'strike foregrip': { | |
'type': 'underbarrel', | |
'changes': ['-8.3 v_recoil', '-3.8 ads_spread', '-1 move_speed'], | |
}, | |
'merc foregrip': { | |
'type': 'underbarrel', | |
'changes': ['-6.9 v_recoil', '-3 hip_spread', '-10 ads_move_speed', '+10 ads_time'], | |
}, | |
'operator foregrip': { | |
'type': 'underbarrel', | |
'changes': ['-13.9 v_recoil', '+8 ads_time'], | |
}, | |
'ranger foregrip': { | |
'type': 'underbarrel', | |
'changes': ['-13.8 v_recoil', '-12.9 ads_spread', '-10 ads_move_speed', '+15 ads_time'], | |
}, | |
'tactical foregrip a': { | |
'type': 'underbarrel', | |
'changes': ['-10 ads_spread', '-1 move_speed'] | |
}, | |
'fast reload': { | |
'type': 'magazine', | |
'changes': ['-15 reload_time'], | |
}, | |
'extended mag a': { | |
'type': 'magazine', | |
'changes': ['-10 move_speed', '+5 reload_time'] | |
}, | |
'strippled grip tape': { | |
'type': 'rear grip', | |
'changes': ['-5 ads_time', '-15 fire_delay', '+12 ads_spread'], | |
}, | |
'granulated grip tape': { | |
'type': 'rear grip', | |
'changes': ['-11.9 ads_spread', '-4 ads_move_speed'] | |
} | |
} | |
attachment_types = ['muzzle', 'barrel', 'stock', 'perk', 'laser', 'underbarrel', 'magazine', 'rear grip'] | |
stats = { | |
'move_speed': 'more', | |
'ads_spread': 'less', | |
'hip_spread': 'less', | |
'ads_time': 'less', | |
'reload_time': 'less', | |
'v_recoil': 'less', | |
'h_recoil': 'less', | |
'range': 'more', | |
'fire_interval': 'less', | |
'ads_move_speed': 'more', | |
'fire_delay': 'less', | |
'flinch': 'less' | |
} | |
def reset_stats(): | |
return { | |
'move_speed': 0, | |
'ads_spread': 0, | |
'hip_spread': 0, | |
'ads_time': 0, | |
'reload_time': 0, | |
'v_recoil': 0, | |
'h_recoil': 0, | |
'range': 0, | |
'fire_interval': 0, | |
'ads_move_speed': 0, | |
'fire_delay': 0, | |
'flinch': 0 | |
} | |
valid_combos = [] | |
priority1 = 'ads_time' | |
priority2 = 'ads_spread' | |
ignore_list = ['hip_spread', 'move_speed', 'range', 'flinch', 'v_recoil', 'ads_move_speed', 'reload_time'] | |
def make_changes(init_stats, these_attachments): | |
for attachment in these_attachments: | |
changes = attachments[attachment]['changes'] | |
for change in changes: | |
splitted = change.split(' ') | |
direction, value, stat = splitted[0][0], splitted[0][1:], splitted[1] | |
if stats[stat] == 'less': | |
if direction == '+': | |
if stat not in ignore_list: | |
init_stats[stat] -= float(value) | |
else: | |
init_stats[stat] += float(value) | |
else: | |
if direction == '-': | |
if stat not in ignore_list: | |
init_stats[stat] -= float(value) | |
else: | |
init_stats[stat] += float(value) | |
best100scores = [] | |
best100priorities = [] | |
best100combos = [] | |
skip = False | |
for combo in itertools.combinations(attachments.keys(), 5): | |
done = [] | |
for attachment in combo: | |
attachment_type = attachments[attachment]['type'] | |
if attachment_type in done: | |
skip = True | |
break | |
done.append(attachment_type) | |
if skip: | |
skip = False | |
continue | |
init_stats = reset_stats() | |
make_changes(init_stats, combo) | |
worst = min(best100priorities) if best100priorities else -10 | |
score = sum(list(init_stats.values())) | |
this = init_stats[priority1] * 2 + init_stats[priority2] | |
if len(best100priorities) < 100 and this not in best100priorities: | |
best100priorities.append(this) | |
best100combos.append(combo) | |
best100scores.append(score) | |
elif this in best100priorities: | |
this_index = best100priorities.index(worst) | |
if score > best100scores[this_index]: | |
best100combos[this_index] = combo | |
best100priorities[this_index] = this | |
best100scores[this_index] = score | |
elif this > worst: | |
worst_index = best100priorities.index(worst) | |
best100priorities.pop(worst_index) | |
best100combos.pop(worst_index) | |
best100scores.pop(worst_index) | |
best100priorities.append(this) | |
best100combos.append(combo) | |
best100scores.append(score) | |
done = [] | |
mapped = {} | |
for combo, priority, score in zip(best100combos, best100priorities, best100scores): | |
mapped[priority+score/10] = combo | |
for score in sorted(mapped.items(), reverse=True): | |
print(score) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment