Skip to content

Instantly share code, notes, and snippets.

@s0md3v
Created March 10, 2021 18:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save s0md3v/90637ef45d0ff23b9bfb86ec9b47fdd7 to your computer and use it in GitHub Desktop.
Save s0md3v/90637ef45d0ff23b9bfb86ec9b47fdd7 to your computer and use it in GitHub Desktop.
poc for cod mobile gunsmith helper
# 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