I tried various tools to extract data from heavymetal
DLC.
DisUnity
First I tried DisUnity - but that's an abandoned project, and it doesn't work with current version.
Unity Asset Bundle Extractor
Next I tried Unity Asset Bundle Extractor which is very nonintuitive but it extracted what I want. "Select All" doesn't work, I needed to select first item, then shift click on the last item. Then I pressed "Export Raw".
It unfortunately created files like: weapon_autocannon_lb10x_0_stock.json-CAB_81519cd4dc355e215c567f814d1dd677--9084477644472635856.dat
instead of weapon/autocannon_lb10x_0_stock.json
.
They also some weird crap at start and end of each file. It wouldn't be too difficult to strip, but I hoped for just the proper data.
"Dump as text file" and "Dump as json file" options were even worse. Finally "Plugins > Export to .txt" worked.
Unity Asset Bundle Extractor has all information necessary to get it right, it just choses not to.
Organizing the files
The files still had stupid names like weapon_autocannon_lb10x_0_stock.json-CAB_81519cd4dc355e215c567f814d1dd677--9084477644472635856.txt
.
So I did a quick:
$ rename 's/-CAB_.*//' *.txt
After that I moved weapon files to heavymetal/weapon/*.json
. I might need to organize other files like ammo etc. later.
Fortunately that's the only DLC with extra weapons. If I wanted to analyze all mechs, I'd need to repeat the same steps with other DLCs.
Script
#!/usr/bin/env ruby
require "json"
require "memoist"
require "pathname"
require "pry"
class Weapon
extend Memoist
attr_reader :data
def initialize(path)
@data = JSON.parse(path.read)
end
memoize def name
bonuses = [bonus_a, bonus_b].compact
if bonuses.empty?
base_name
else
"#{base_name} (#{bonuses.join(", ")})"
end
end
memoize def base_name
[
data["Description"]["Name"],
data["Description"]["UIName"],
].compact.last.gsub(" +", "+")
end
memoize def bonus_a
data["BonusValueA"] == "" ? nil : data["BonusValueA"].gsub(/[a-z]\K\./, "")
end
memoize def bonus_b
data["BonusValueB"] == "" ? nil : data["BonusValueB"].gsub(/[a-z]\K\./, "")
end
def category
@data["Category"]
end
def tonnage
@data["Tonnage"]
end
def damage
shots * base_damage
end
def base_damage
@data["Damage"]
end
def shots
@data["ShotsWhenFired"]
end
def heat
@data["HeatGenerated"]
end
def heat_tonnage
heat / 3.0
end
def ammo_tonnage
# TODO
0
end
def total_tonnage
tonnage + heat_tonnage + ammo_tonnage
end
def ammo_category
@data["ammoCategoryID"]
end
def purchasable?
@data["Description"]["Purchasable"]
end
end
class BattleTechGame
extend Memoist
def initialize(game_root, *dlc_roots)
@game_root = Pathname(game_root)
@dlc_roots = dlc_roots.map{|path| Pathname(path)}
end
memoize def data_root
@game_root + "BattleTech_Data/StreamingAssets/data"
end
memoize def weapon_files
[data_root, *@dlc_roots]
.flat_map{|root| root.glob("weapon/*.json")}
.select{|n| n.basename.to_s != "WeaponTemplate.json"}
end
memoize def weapons
weapon_files.map{|path| Weapon.new(path)}
end
def print_weapons_report
weapons
.select{|w| w.category != "Melee" and w.name != "AI Laser"}
.sort_by{|w|
[w.damage.to_f / w.total_tonnage, w.damage, w.name]
}
.reverse
.each{|w|
puts "* #{w.name}: #{w.damage} / #{w.total_tonnage.round(2)}"
}
end
end
game = BattleTechGame.new(*ARGV)
game.print_weapons_report
To run the scirpt I use ./weapons /path/to/battletech /path/to/heavymetal
Result
Here's the result. As the script still doesn't count ammo, it overvalues ammo using weapons. It's also quite confused by any weapon that has special effects like all those TAGs and NARCs and COILs on the end of the list. It might be best to just exclude them the analysis.
- MG++ (+ 5 Shots, - 0.5 Ton): 30 / 0.0
- MG++ (+ 50% Crit, - 0.5 Ton): 15 / 0.0
- MG+ (+ 5 Shots): 30 / 0.5
- MG+ (+ 25% Crit): 15 / 0.5
- MG: 15 / 0.5
- LB 2-X++ (+ 2 Dmg, + 50% Crit): 72 / 5.67
- S Laser+++ (+ 10 Dmg, + 50% Crit): 30 / 2.5
- S Laser++ (+ 10 Dmg): 30 / 2.5
- LB 2-X+ (+ 1 Dmg, + 25% Crit): 60 / 5.67
- ER S Laser++ (+ 10 Dmg): 40 / 3.83
- S Pulse++ (+ 10 Dmg, - 2 Heat): 45 / 4.33
- SRM6+++ (+ 4 Dmg, + 2 StbDmg): 72 / 7.0
- SRM6++ (+ 4 Dmg): 72 / 7.0
- SRM4+++ (+ 4 Dmg, + 2 StbDmg): 48 / 4.67
- SRM4++ (+ 4 Dmg): 48 / 4.67
- SRM2+++ (+ 4 Dmg, + 2 StbDmg): 24 / 2.33
- SRM2++ (+ 4 Dmg): 24 / 2.33
- S Laser++ (+ 5 Dmg, + 25% Crit): 25 / 2.5
- S Laser+ (+ 5 Dmg): 25 / 2.5
- Flamer+ (* 4 Ammo, + 5 Dmg): 10 / 1.0
- UAC/2++ (+ 10 Dmg, - 2 Tons): 70 / 7.67
- ER S Laser+ (+ 5 Dmg): 35 / 3.83
- SRM4++ (+ 2 Dmg, + 1 StbDmg): 40 / 4.67
- SRM4+ (+ 2 Dmg): 40 / 4.67
- S Pulse+ (+ 5 Dmg, - 1 Heat): 40 / 4.67
- SRM2++ (+ 2 Dmg, + 1 StbDmg): 20 / 2.33
- SRM2+ (+ 2 Dmg): 20 / 2.33
- UAC/20++ (+ 20 Dmg, - 3 Tons): 240 / 28.0
- SRM6++ (+ 2 Dmg, + 1 StbDmg): 60 / 7.0
- SRM6+ (+ 2 Dmg): 60 / 7.0
- LB 2-X: 48 / 5.67
- S Laser++ (+ 50% Crit): 20 / 2.5
- S Laser++ (+ 3 Acc): 20 / 2.5
- S Laser+ (+ 25% Crit): 20 / 2.5
- S Laser+ (+ 1 Acc): 20 / 2.5
- S Laser: 20 / 2.5
- ER S Laser: 30 / 3.83
- LRM15++ (+ 2 Dmg): 90 / 11.67
- LRM20++ (+ 2 Dmg): 120 / 16.0
- LRM5++ (+ 2 Dmg): 30 / 4.0
- UAC/20+ (+ 10 Dmg, - 1.5 Tons): 220 / 29.5
- UAC/5++ (- 2 Recoil, - 2 Tons): 90 / 12.33
- LB 10-X++ (+ 2 Dmg, - 1 Ton): 96 / 13.33
- LRM10++ (+ 2 Dmg): 60 / 8.33
- Snub PPC++ (+ 10 Dmg): 125 / 17.67
- S Pulse: 35 / 5.0
- M Laser++ (+ 10 Dmg): 35 / 5.0
- UAC/2+ (+ 5 Dmg, - 1 Ton): 60 / 8.67
- SRM4++ (+ 50% Crit): 32 / 4.67
- SRM4+ (+ 25% Crit): 32 / 4.67
- SRM4: 32 / 4.67
- SRM2++ (+ 50% Crit): 16 / 2.33
- SRM2+ (+ 25% Crit): 16 / 2.33
- SRM2: 16 / 2.33
- SRM6++ (+ 50% Crit): 48 / 7.0
- SRM6+ (+ 25% Crit): 48 / 7.0
- SRM6: 48 / 7.0
- M Pulse++ (- 4 Heat, + 1 Acc): 50 / 7.33
- UAC/5+ (- 1 Recoil, - 1 Ton): 90 / 13.33
- UAC/10++ (+ 10 StbDmg, - 3 Tons): 120 / 18.0
- LB 5-X++ (+ 4 StbDmg, - 1 Ton): 60 / 9.0
- UAC/20: 200 / 31.0
- LB 20-X++ (+ 4 StbDmg, - 2 Tons): 120 / 18.67
- LRM15+ (+ 1 Dmg): 75 / 11.67
- LB 10-X+ (+ 1 Dmg, - 0.5 Ton): 88 / 13.83
- LB 5-X+ (+ 2 StbDmg, - 0.5 Ton): 60 / 9.5
- UAC/5: 90 / 14.33
- LRM20+ (+ 1 Dmg): 100 / 16.0
- LRM5+ (+ 1 Dmg): 25 / 4.0
- UAC/10+ (+ 5 StbDmg, - 1.5 Tons): 120 / 19.5
- LB 20-X+ (+ 2 StbDmg, - 1 Ton): 120 / 19.67
- LB 5-X: 60 / 10.0
- LRM10+ (+ 1 Dmg): 50 / 8.33
- M Laser+ (+ 5 Dmg): 30 / 5.0
- ER M Laser++ (+ 10 Dmg): 45 / 7.67
- LB 20-X: 120 / 20.67
- UAC/10: 120 / 21.0
- Snub PPC+ (+ 5 Dmg): 100 / 17.67
- M Pulse+ (- 2 Heat): 45 / 8.0
- LB 10-X: 80 / 14.33
- AC/20+++ (+ 20 Dmg, + 20 StbDmg): 120 / 22.0
- AC/20++ (+ 20 Dmg): 120 / 22.0
- Snub PPC++ (- 10 Heat): 75 / 14.33
- ER M Laser+ (+ 5 Dmg): 40 / 7.67
- UAC/2: 50 / 9.67
- AC/5++ (+ 10 Dmg): 55 / 10.67
- LRM15+++ (+ 50% Crit, + 2 StbDmg): 60 / 11.67
- LRM15++ (+ 50% Crit): 60 / 11.67
- LRM15++ (+ 25% Crit, + 1 StbDmg): 60 / 11.67
- LRM15++ (+ 2 StbDmg): 60 / 11.67
- LRM15+ (+ 25% Crit): 60 / 11.67
- LRM15+ (+ 1 StbDmg): 60 / 11.67
- LRM15: 60 / 11.67
- Gauss Rifle++ (- 2 Tons, - 1 Slot): 75 / 14.67
- Gauss Rifle+ (- 2 Tons): 75 / 14.67
- AC/20++ (+ 10 Dmg, + 10 StbDmg): 110 / 22.0
- AC/20+ (+ 10 Dmg): 110 / 22.0
- LRM20+++ (+ 50% Crit, + 2 StbDmg): 80 / 16.0
- LRM20++ (+ 50% Crit): 80 / 16.0
- LRM20++ (+ 25% Crit, + 1 StbDmg): 80 / 16.0
- LRM20++ (+ 2 StbDmg): 80 / 16.0
- LRM20+ (+ 25% Crit): 80 / 16.0
- LRM20+ (+ 1 StbDmg): 80 / 16.0
- LRM20: 80 / 16.0
- M Laser+++ (+ 3 Acc, + 50% Crit): 25 / 5.0
- M Laser++ (+3 Acc): 25 / 5.0
- M Laser++ (+ 50% Crit): 25 / 5.0
- M Laser++ (+ 1 Acc, + 25% Crit): 25 / 5.0
- M Laser+ (+1 Acc): 25 / 5.0
- M Laser+ (+ 25% Crit): 25 / 5.0
- M Laser: 25 / 5.0
- LRM5+++ (+ 50% Crit, + 2 StbDmg): 20 / 4.0
- LRM5++ (+ 50% Crit): 20 / 4.0
- LRM5++ (+ 25% Crit, + 1 StbDmg): 20 / 4.0
- LRM5++ (+ 2 StbDmg): 20 / 4.0
- LRM5+ (+ 25% Crit): 20 / 4.0
- LRM5+ (+ 1 StbDmg): 20 / 4.0
- LRM5: 20 / 4.0
- Flamer+++ (* 40 Ammo): 5 / 1.0
- Flamer++ (* 4 Ammo, + 5 Dmg (H)): 5 / 1.0
- Flamer (* 4 Ammo): 5 / 1.0
- LRM10+++ (+ 50% Crit, + 2 StbDmg): 40 / 8.33
- LRM10++ (+ 50% Crit): 40 / 8.33
- LRM10++ (+ 25% Crit, + 1 StbDmg): 40 / 8.33
- LRM10++ (+ 2 StbDmg): 40 / 8.33
- LRM10+ (+ 25% Crit): 40 / 8.33
- LRM10+ (+ 1 StbDmg): 40 / 8.33
- LRM10: 40 / 8.33
- AC/2++ (+ 10 Dmg): 35 / 7.33
- Snub PPC+ (- 5 Heat): 75 / 16.0
- AC/5+ (+ 5 Dmg): 50 / 10.67
- M Pulse: 40 / 8.67
- ER M Laser: 35 / 7.67
- AC/20+++ : 100 / 22.0
- AC/20++ (+ 50% Crit): 100 / 22.0
- AC/20++ (+ 4 Acc): 100 / 22.0
- AC/20++ (+ 20 StbDmg): 100 / 22.0
- AC/20+ (+ 25% Crit): 100 / 22.0
- AC/20+ (+ 2 Acc): 100 / 22.0
- AC/20+ (+ 10 StbDmg): 100 / 22.0
- AC/20: 100 / 22.0
- L Laser+++ (+ 10 Dmg, + 3 Acc): 50 / 11.0
- L Laser++ (+ 10 Dmg): 50 / 11.0
- Gauss Rifle: 75 / 16.67
- AC/10++ (+ 10 Dmg): 70 / 16.0
- Snub PPC++ (+ 10 StbDmg): 75 / 17.67
- Snub PPC+ (+ 5 StbDmg): 75 / 17.67
- Snub PPC: 75 / 17.67
- AC/5+++ (+ 4 Acc, + 20 StbDmg): 45 / 10.67
- AC/5++ (+ 50% Crit): 45 / 10.67
- AC/5++ (+ 4 Acc): 45 / 10.67
- AC/5++ (+ 20 StbDmg): 45 / 10.67
- AC/5++ (+ 2 Acc, + 10 StbDmg): 45 / 10.67
- AC/5+ (+ 25% Crit): 45 / 10.67
- AC/5+ (+ 2 Acc): 45 / 10.67
- AC/5+ (+ 10 StbDmg): 45 / 10.67
- AC/5: 45 / 10.67
- L Laser++ (+ 5 Dmg, + 1 Acc): 45 / 11.0
- L Laser+ (+ 5 Dmg): 45 / 11.0
- AC/2+ (+ 5 Dmg): 30 / 7.33
- L Pulse++ (+ 10 Dmg, - 1 Ton): 65 / 16.0
- AC/10+ (+ 5 Dmg): 65 / 16.0
- ER L Laser++ (+ 5 Dmg, - 1 Ton): 50 / 12.33
- L Pulse+ (+ 5 Dmg, - 1 Ton): 60 / 16.0
- AC/10+++ (+ 50% Crit, + 20 StbDmg): 60 / 16.0
- AC/10++ (+ 50% Crit): 60 / 16.0
- AC/10++ (+ 4 Acc): 60 / 16.0
- AC/10++ (+ 25% Crit, + 10 StbDmg): 60 / 16.0
- AC/10++ (+ 20 StbDmg): 60 / 16.0
- AC/10+ (+ 25% Crit): 60 / 16.0
- AC/10+ (+ 2 Acc): 60 / 16.0
- AC/10+ (+ 10 StbDmg): 60 / 16.0
- AC/10: 60 / 16.0
- ER L Laser+ (+ 5 Dmg): 50 / 13.33
- L Laser++ (+ 50% Crit): 40 / 11.0
- L Laser++ (+ 3 Acc): 40 / 11.0
- L Laser+ (+ 25% Crit): 40 / 11.0
- L Laser+ (+ 1 Acc): 40 / 11.0
- L Laser: 40 / 11.0
- AC/2+++ (+ 4 Acc, + 50% Crit): 25 / 7.33
- AC/2++ (+ 50% Crit): 25 / 7.33
- AC/2++ (+ 4 Acc): 25 / 7.33
- AC/2++ (+ 20 StbDmg): 25 / 7.33
- AC/2++ (+ 2 Acc, + 25% Crit): 25 / 7.33
- AC/2+ (+ 25% Crit): 25 / 7.33
- AC/2+ (+ 2 Acc): 25 / 7.33
- AC/2+ (+ 10 StbDmg): 25 / 7.33
- AC/2: 25 / 7.33
- ER L Laser: 45 / 13.33
- ER PPC++ (+ 10 Dmg, - 1 Ton): 70 / 21.0
- L Pulse: 55 / 17.0
- PPC++ (+ 10 Dmg): 60 / 18.67
- ER PPC+ (+ 5 Dmg, - 1 Ton): 65 / 21.0
- PPC+ (+ 5 Dmg): 55 / 18.67
- ER PPC: 60 / 22.0
- PPC++ (+ 4 Acc): 50 / 18.67
- PPC++ (+ 30 StbDmg): 50 / 18.67
- PPC+ (+ 2 Acc): 50 / 18.67
- PPC+ (+ 15 StbDmg): 50 / 18.67
- PPC: 50 / 18.67
- AC/10: 30 / 21.0
- COIL-L (Dmg X Evasion): 35 / 27.33
- COIL-M (Dmg X Evasion): 25 / 19.67
- COIL-S (Dmg X Evasion): 15 / 12.0
- Infernos++ (* 8 Volleys, + 10 Dmg (H)): 4 / 4.0
- Infernos+ (* 8 Volleys, + 5 Dmg (H)): 4 / 4.0
- Infernos (* 8 Volleys): 4 / 4.0
- AC/10: 30 / 32.0
- TAG++ (+ 20% Dmg Mark, * Energy, Ballistic): 1 / 2.67
- TAG+ (+ 15% Dmg Mark, * Energy, Ballistic): 1 / 2.67
- TAG (+ 10% Dmg Mark, * Energy, Ballistic): 1 / 2.67
- Narc Beacon++ (+ 75% Dmg Mark, * Missile): 1 / 3.0
- Narc Beacon+ (+ 50% Dmg Mark, * Missile): 1 / 3.0
- Narc Beacon (+ 25% Dmg Mark, * Missile): 1 / 3.0
Story so far
Coming next
In the next few episodes, we'll finish the script by including ammo in the count.
Top comments (0)