////////////////////////////////////////////////////////////////////////////////
// MWBase.cpp
// Copyright Bjoern Ganster
// Developed since 2007
////////////////////////////////////////////////////////////////////////////////

#include "BGCPString.h"
#include "MWBase.h"

#include <iostream>

#define FILE_NUMBER FILE_NO_MWBASE_CPP

MWEquipment* weapons;

////////////////////////////////////////////////////////////////////////////////
// Get file type ID from name

FileType getFileTypeFromExtension (const char* FN)
{
	SET_SCOPE;
	size_t len = bgstrlen (FN);
	if (len > 3) {
		auto a = latinLowerCase (FN[len-3]);
		auto b = latinLowerCase (FN[len-2]);
		auto c = latinLowerCase (FN[len-1]);

		if (a == 'x'
		&&  b == 'e'
		&&  c == 'l')
		{
			RETURN FileType::XEL;
		} else
		if (a == 'w'
		&&  b == 't'
		&&  c == 'b')
		{
			RETURN FileType::WTB;
		} else
		if (a == 'm'
		&&  b == 'e'
		&&  c == 'k')
		{
			RETURN FileType::Mech;
		} else
		if (a == 'p'
		&&  b == 'r'
		&&  c == 'j')
		{
			RETURN FileType::PRJ;
		} else
		if (a == 's'
		&&  b == 'h'
		&&  c == 'p')
		{
			RETURN FileType::SHP;
		} else
		if (a == 's'
		&&  b == 'f'
		&&  c == 'l')
		{
			RETURN FileType::SFL;
		} else
		if (a == 'w'
		&&  b == 'a'
		&&  c == 'v')
		{
			RETURN FileType::WAV;
		} else
		if (a == 'c'
		&&  b == 'o'
		&&  c == 'l')
		{
			RETURN FileType::COL;
		} else
		if (a == 'e'
		&&  b == 'f'
		&&  c == 'a')
		{
			RETURN FileType::EFA;
		} else
		if (a == 'b'
		&&  b == 'w'
		&&  c == 'd')
		{
			RETURN FileType::BWD;
		} else
		if (a == '1'
		&&  b == '0'
		&&  c == '0')
		{
			RETURN FileType::FNT;
		}
		if (a == 'f'
		&&  b == 'l'
		&&  c == 't')
		{
			RETURN FileType::FLT;
		} else
		if (a == 'z'
		&&  b == 'b'
		&&  c == 'd')
		{
			RETURN FileType::ZBD;
		} else
		if (a == 'm'
		&&  b == 'w'
		&&  c == '2')
		{
			RETURN FileType::MW2_DB;
		} else
		if (a == 't'
		&&  b == 'e'
		&&  c == 'x')
		{
			RETURN FileType::TEX;
		} else
		if (a == 'p'
		&&  b == 'c'
		&&  c == 'x')
		{
			RETURN FileType::PCX;
		} else
		if (a == '5'
		&&  b == '5'
		&&  c == '5')
		{
			// Warning! Both MW2 and MW3 use format named .555, but they
			// have a different header ...
			RETURN FileType::MW2_555;
		} else 
		if (a == 'i'
		&&  b == 'm'
		&&  c == 'g')
		{
			RETURN FileType::ISO_9660;
		} else 
		if (a == 'i'
		&&  b == 's'
		&&  c == 'o')
		{
			RETURN FileType::ISO_9660;
		} else 
		if (a == 'b'
		&&  b == 'i'
		&&  c == 'n')
		{
			RETURN FileType::ISO_9660;
		} else 
		if (a == 's'
		&&  b == 'm'
		&&  c == 'k')
		{
			RETURN FileType::SMK;
		} else
		if (a == 'b'
		&&  b == 'm'
		&&  c == 'p')
		{
			RETURN FileType::BMP;
		} else 
		if (a == 'c'
		&&  b == 'd'
		&&  c == 'a')
		{
			RETURN FileType::ISO_9660_AUDIO;
		} else 
		if (a == 'z'
		&&  b == 'f'
		&&  c == 's')
		{
			RETURN FileType::ZFS;
		} else 
		if (a == 'f'
		&&  b == 'n'
		&&  c == 't')
		{
			RETURN FileType::FNT;
		} else 
		if (a == 'o'
		&&  b == 'b'
		&&  c == 'j')
		{
			RETURN FileType::OBJ;
		}
	}

	RETURN FileType::unsupported;
}

FileType getFileTypeFromExtension (const wchar_t* FN)
{
	SET_SCOPE;
	size_t len = bgstrlen (FN);
	if (len > 3) {
		auto a = latinLowerCase (FN[len-3]);
		auto b = latinLowerCase (FN[len-2]);
		auto c = latinLowerCase (FN[len-1]);

		if (a == 'w'
		&&  b == 'a'
		&&  c == 'v')
		{
			RETURN FileType::WAV;
		} else
		if (a == 'b'
		&&  b == 'm'
		&&  c == 'p')
		{
			RETURN FileType::BMP;
		}
		else if (a == 'x'
		&&  b == 'e'
		&&  c == 'l')
		{
			RETURN FileType::XEL;
		} else
		if (a == 'w'
		&&  b == 't'
		&&  c == 'b')
		{
			RETURN FileType::WTB;
		} else
		if (a == 'm'
		&&  b == 'e'
		&&  c == 'k')
		{
			RETURN FileType::Mech;
		} else
		if (a == 'p'
		&&  b == 'r'
		&&  c == 'j')
		{
			RETURN FileType::PRJ;
		} else
		if (a == 's'
		&&  b == 'h'
		&&  c == 'p')
		{
			RETURN FileType::SHP;
		} else
		if (a == 's'
		&&  b == 'f'
		&&  c == 'l')
		{
			RETURN FileType::SFL;
		} else
		if (a == 'c'
		&&  b == 'o'
		&&  c == 'l')
		{
			RETURN FileType::COL;
		} else
		if (a == 'e'
		&&  b == 'f'
		&&  c == 'a')
		{
			RETURN FileType::EFA;
		} else
		if (a == 'b'
		&&  b == 'w'
		&&  c == 'd')
		{
			RETURN FileType::BWD;
		} else
		if (a == '1'
		&&  b == '0'
		&&  c == '0')
		{
			RETURN FileType::FNT;
		}
		if (a == 'f'
		&&  b == 'l'
		&&  c == 't')
		{
			RETURN FileType::FLT;
		} else
		if (a == 'z'
		&&  b == 'b'
		&&  c == 'd')
		{
			RETURN FileType::ZBD;
		} else
		if (a == 'm'
		&&  b == 'w'
		&&  c == '2')
		{
			RETURN FileType::MW2_DB;
		} else
		if (a == 't'
		&&  b == 'e'
		&&  c == 'x')
		{
			RETURN FileType::TEX;
		} else
		if (a == 'p'
		&&  b == 'c'
		&&  c == 'x')
		{
			RETURN FileType::PCX;
		} else
		if (a == '5'
		&&  b == '5'
		&&  c == '5')
		{
			// Warning! Both MW2 and MW3 use format named .555, but they
			// have a different header ...
			RETURN FileType::MW2_555;
		} else 
		if (a == 'i'
		&&  b == 'm'
		&&  c == 'g')
		{
			RETURN FileType::ISO_9660;
		} else 
		if (a == 'i'
		&&  b == 's'
		&&  c == 'o')
		{
			RETURN FileType::ISO_9660;
		} else 
		if (a == 'b'
		&&  b == 'i'
		&&  c == 'n')
		{
			RETURN FileType::ISO_9660;
		} else 
		if (a == 's'
		&&  b == 'm'
		&&  c == 'k')
		{
			RETURN FileType::SMK;
		} else 
		if (a == 'c'
		&&  b == 'd'
		&&  c == 'a')
		{
			RETURN FileType::ISO_9660_AUDIO;
		} else 
		if (a == 'z'
		&&  b == 'f'
		&&  c == 's')
		{
			RETURN FileType::ZFS;
		} else 
		if (a == 'f'
		&&  b == 'n'
		&&  c == 't')
		{
			RETURN FileType::FNT;
		} else 
		if (a == 'o'
		&&  b == 'b'
		&&  c == 'j')
		{
			RETURN FileType::OBJ;
		} else 
		if (a == 'm'
		&&  b == 'w'
		&&  c == '4')
		{
			RETURN FileType::MW4ResourceFile;
		}
	}

	RETURN FileType::unsupported;
}

////////////////////////////////////////////////////////////////////////////////
// Get file extension from file type ID

#ifdef MECHVM
const char* getMWFileExt (FileType FileTypeID)
{
	SET_SCOPE;
	switch (FileTypeID) {
	case FileType::XEL:
		RETURN ".XEL";
	case FileType::WTB:
		RETURN ".WTB";
	case FileType::Mech:
		RETURN ".MEK";
	case FileType::PRJ:
		RETURN ".PRJ";
	case FileType::SHP:
		RETURN "SHP";
	case FileType::SFL:
		RETURN "SFL";
	case FileType::WAV:
		RETURN "WAV";
	case FileType::COL:
		RETURN "COL";
	case FileType::DLL:
		RETURN "DLL";
	case FileType::EFA:
		RETURN "EFA";
	case FileType::FORM:
		RETURN "FORM";
	case FileType::FNT:
		RETURN "FNT";
	case FileType::BWD:
		RETURN "BWD";
	case FileType::ZBD:
		RETURN "ZBD";
	case FileType::FLT:
		RETURN "FLT";
	case FileType::TEX:
		RETURN "TEX";
	case FileType::PCX:
		RETURN "PCX";
	case FileType::MW2_555:
	case FileType::MW3_555:
		RETURN "555";
	default:
		RETURN "";
	}
}
#endif

////////////////////////////////////////////////////////////////////////////////
// Get file type ID from file contents

FileType getFileTypeFromContent (const MemoryBlock* block)
{
	SET_SCOPE;
	if (block->getSize() > 4) {
		if (block->get<char> (0) == 'R'
		&&  block->get<char> (1) == 'I'
		&&  block->get<char> (2) == 'F'
		&&  block->get<char> (3) == 'F')
		{
			RETURN FileType::WAV;
		}
		#ifdef MECHVM
		else if (block->get<char> (0) == '1'
		&&  block->get<char> (1) == '.'
		&&  block->get<char> (2) == '1'
		&&  block->get<char> (3) == '0')
		{
			RETURN FileType::SHP;
		} else
		if (block->get<char> (0) == 'M'
		&&  block->get<char> (1) == 'Z')
		{
			RETURN FileType::DLL;
		} else
		if (block->get<unsigned char> (4) == 0xEF
		&&  block->get<char> (5) == 0x0A
		&&  block->get<char> (6) == 0x05
		&&  block->get<char> (7) == 0x01)
		{
			RETURN FileType::EFA;
		} else
		if (block->get<char> (5) == 'F'
		&&  block->get<char> (6) == 'O'
		&&  block->get<char> (7) == 'R'
		&&  block->get<char> (8) == 'M')
		{
			RETURN FileType::FORM;
		} else
		if (block->get<char> (0) == '1'
		&&  block->get<char> (1) == '.'
		&&  block->get<char> (2) == 0
		&&  block->get<char> (3) == 0)
		{
			RETURN FileType::FNT;
		} else
		if (block->get<char> (0) == 'B'
		&&  block->get<char> (1) == 'W'
		&&  block->get<char> (2) == 'D')
		{
			RETURN FileType::BWD;
		} else
		if (block->get<char> (0) == '1'
		&&  block->get<char> (1) == '.'
		&&  block->get<char> (2) == '2'
		&&  block->get<char> (3) == '2')
		{
			RETURN FileType::TEX;
		} else
		if (block->get<char> (0) == 0x0A
		&&  block->get<char> (1) == 0x05
		&&  block->get<char> (2) == 0x01
		&&  block->get<char> (3) == 0x08)
		{
			RETURN FileType::PCX;
		} else
		if (block->get<char> (0) == 0x05
		&&  block->get<char> (1) == 0x00
		&&  block->get<char> (2) == 0x00
		&&  block->get<char> (3) == 0x00)
		{
			RETURN FileType::MW3_555;
		} else
		if (block->get<char> (0) == 0x0b
		&&  block->get<char> (1) == 0x00
		&&  block->get<char> (2) == 0x00
		&&  block->get<char> (3) == 0x00)
		{
			RETURN FileType::MW3_555;
		} else
		if (block->get<char> (0) == 0x03
		&&  block->get<char> (1) == 0x00
		&&  block->get<char> (2) == 0x00
		&&  block->get<char> (3) == 0x00)
		{
			RETURN FileType::MW3_555;
		}
	#endif
	}

	// Check for ZBD
	#ifdef MECHVM
	size_t i = 0;
	char c;
	do {
		c = block->get<uint8_t>(i);
		++i;
	} while (i < 29 && c != '.');
	if (c != '.') {
		if (block->get<uint8_t>(i) == 'f'
			&&  block->get<uint8_t>(i+1) == 'l'
			&&  block->get<uint8_t>(i+2) == 't')
		{
			RETURN FileType::FLT;
		}
	}
	#endif

	RETURN FileType::unsupported;
}

////////////////////////////////////////////////////////////////////////////////

void copyWeapon (int oldID, int ID)
{
	SET_SCOPE;
	weapons[ID].Heat = weapons[oldID].Heat;
	weapons[ID].MaxDamage = weapons[oldID].MaxDamage;
	//weapons[ID].MinDamage = weapons[oldID].MinDamage;
	weapons[ID].MinimumRangeInMeters = weapons[oldID].MinimumRangeInMeters;
	weapons[ID].MaxDamageRange = weapons[oldID].MaxDamageRange;
	weapons[ID].MaxRangeInMeters = weapons[oldID].MaxRangeInMeters;
	weapons[ID].TonnageTimes100 = weapons[oldID].TonnageTimes100;
	weapons[ID].Criticals = weapons[oldID].Criticals;
	weapons[ID].ShotsPerTon = weapons[oldID].ShotsPerTon;
	weapons[ID].AvailableInYear = weapons[oldID].AvailableInYear;
	weapons[ID].CBills = weapons[oldID].CBills;
	memcpy(&weapons[ID].longName[0], weapons[oldID].getLongName(), LongWeaponNameLen);
	memcpy(&weapons[ID].shortName[0], weapons[oldID].getShortName(), ShortWeaponNameLen);
	weapons[ID].MW2_31st_ID = weapons[oldID].MW2_31st_ID;
	weapons[ID].MW2_ID = weapons[oldID].MW2_ID;
	weapons[ID].MaxCount = weapons[oldID].MaxCount;
	weapons[ID].inInventory = weapons[oldID].inInventory;
	weapons[ID].flags = weapons[oldID].flags;

	for (size_t i = 0; i < MaxAmmoTypes; i++) {
		weapons[ID].AmmoTypes[i] = weapons[oldID].AmmoTypes[i];
	}

	RETURN;
}

void setWeaponNames(int ID, const BGCPString& shortName, const BGCPString& longName)
{
	auto slen = shortName.getCharCount();
	auto llen = longName.getCharCount();

	if (slen == 0) {
		weapons[ID].shortName[0] = 0;
	} else  if (slen+1 < ShortWeaponNameLen) {
		memcpy(weapons[ID].shortName, shortName.getPtr<const char>(0), slen+1);
	} else {
		shortName.print();
		COUT << ": too long as a short weapon name (" << slen << ">=" << ShortWeaponNameLen-1 
		     << ")" << std::endl;
	}
	if (llen == 0) {
		weapons[ID].longName[0] = 0;
	} else if (llen+1 < LongWeaponNameLen) {
		memcpy(weapons[ID].longName, longName.getPtr<const char>(0), llen+1);
	} else {
		weapons[ID].longName[0] = 0;
		longName.print();
		COUT << ": too long as a long weapon name (" << llen << ">" << LongWeaponNameLen << std::endl;
	}
}

inline void setWeaponNames(int ID, const char* name)
{
	setWeaponNames(ID, name, name);
}

void setWeaponAmmoPair(int wID, int aID)
{
	size_t i = 0;
	MWEquipment& w = weapons[wID];
	while (w.AmmoTypes[i] != 0 && i < MaxAmmoTypes) {
		++i;
	}
	if (i < MaxAmmoTypes) {
		w.AmmoTypes[i] = aID;
	} else {
		printf ("%s has too many ammo types\n", w.longName);
	}

	size_t j = 0;
	MWEquipment& a = weapons[aID];
	while (a.AmmoTypes[j] != 0 && j < MaxAmmoTypes) {
		++j;
	}
	if (j < MaxAmmoTypes) {
		a.AmmoTypes[j] = wID;
	} else {
		printf ("%s has too few weapon types\n", a.longName);
	}
}

////////////////////////////////////////////////////////////////////////////////

// Initialize MW weapons list
// While doing this in a function requires a lot of code, it is nicely
// self-commenting 
void fillWeaponsList()
{
	weapons = new MWEquipment[WeaponsCount];
	BGCPString shortName, longName;
	//printf("%i bytes for weapon table\n", sizeof(MWWeapon) * WeaponsCount);
	Color red(1.0, 0, 0);
	Color green(0, 1.0, 0);
	Color blue(0, 0, 1.0);
	Color white(1.0, 1.0, 1.0);
	Color grey(0.5, 0.5, 0.5);

	size_t ID;
	for (ID = 0; ID < WeaponsCount; ID++) {
		weapons[ID].Heat = 0;
		weapons[ID].MaxDamage = 0; // Maximum weapon damage
		//weapons[ID].MinDamage = 0; // Minimum weapon damage at maximum range
		weapons[ID].MaxDamageRange = 0; // Maximum range where the weapon does its full damage
		weapons[ID].MaxRangeInMeters = 0; // The maximum range for the weapon does minimum damage
		weapons[ID].MinimumRangeInMeters = 0;
		weapons[ID].TonnageTimes100 = 0;
		weapons[ID].Criticals = 1;
		weapons[ID].ShotsPerTon = 0; // If positive, this record describes ammo
		weapons[ID].AvailableInYear = 2820; // Year of field/open market availability
		weapons[ID].CBills = 0;
		for (size_t j = 0; j < MaxAmmoTypes; j++)
			weapons[ID].AmmoTypes[j] = 0; // Ammo that this weapon can use
		setWeaponNames(ID, "", "");
		weapons[ID].MW2_ID = 65400;
		weapons[ID].MW2_31st_ID = 65400;
		weapons[ID].MaxCount = 100;
		weapons[ID].inInventory = 100;
		weapons[ID].flags = MWWeaponFlagsStdWeapon;
		weapons[ID].fireDuration = 1.0; // How long the weapon fires after being triggered
		weapons[ID].coolDown = 5.0; // How long the weapon needs to cool down after being fired
		weapons[ID].ammoUsedPerShot = 0;

		weapons[ID].geometry = nullptr;
		weapons[ID].xreps = 1; 
		weapons[ID].yreps = 1;
		weapons[ID].weaponScale = 0.125;
		weapons[ID].shotColor = white;
		weapons[ID].soundWhenFired = "";
		weapons[ID].category = WeaponCategory::energy;
		weapons[ID].metersPerSecond = 1000;
		weapons[ID].defyGravityDuration = 0.0;
		weapons[ID].shotColor = Color (1.0, 1.0, 1.0);
	}

	// Weapon geometry is loaded once and used for entire game
	BGCPString geometryPath(getDataDir());
	geometryPath.addPathSep("weapons");
	geometryPath.addPathSep();

	Texture* weaponTexture = new Texture();
	BGCPString weaponTextureFN = geometryPath;
	weaponTextureFN += "weapons.png";
	weaponTexture->loadFromFile(weaponTextureFN.getAsPath());

	Mesh* autocannonGeometry = new Mesh();
	BGCPString autocannonFN = geometryPath;
	autocannonFN += "Autocannon.obj";
	autocannonGeometry->loadFromObj(autocannonFN.getAsPath());
	autocannonGeometry->setTexture(weaponTexture);

	Mesh* gaussCannonGeometry = new Mesh();
	BGCPString gaussCannonFN = geometryPath;
	gaussCannonFN += "Gauss Cannon.obj";
	gaussCannonGeometry->loadFromObj(gaussCannonFN.getAsPath());
	gaussCannonGeometry->setTexture(weaponTexture);

	Mesh* laserGeometry = new Mesh();
	BGCPString laserFN = geometryPath;
	laserFN += "Laser.obj";
	laserGeometry->loadFromObj(laserFN.getAsPath());
	laserGeometry->setTexture(weaponTexture);

	Mesh* missileTubeGeometry = new Mesh();
	BGCPString missileTubeFN = geometryPath;
	missileTubeFN += "Missile Tube.obj";
	missileTubeGeometry->loadFromObj(missileTubeFN.getAsPath());
	missileTubeGeometry->setTexture(weaponTexture);

	ID = WeaponType::IS1_Flamer;
	weapons[ID].Heat = 3;
	weapons[ID].MaxDamage = 2; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 90; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 100;
	weapons[ID].AvailableInYear = 2025; // Year of field/open market availability
	weapons[ID].CBills = 7500;
	setWeaponNames (ID, "Flamer");
	weapons[ID].MW2_ID = 5100;
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = red;
 
	ID = WeaponType::IS1_Small_Laser;
	weapons[ID].Heat = 1;
	weapons[ID].MaxDamage = 3; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 90; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 50;
	weapons[ID].AvailableInYear = 2025; // Year of field/open market availability
	weapons[ID].CBills = 11250;
	setWeaponNames (ID, "SLaser", "Small Laser");
	weapons[ID].MW2_ID = 5700;
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = red;
	weapons[ID].soundWhenFired = "MECSLASR.SFL";
	weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

	ID = WeaponType::IS1_Medium_Laser;
	weapons[ID].Heat = 3;
	weapons[ID].MaxDamage = 5; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 270; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 100;
	weapons[ID].AvailableInYear = 2025; // Year of field/open market availability
	weapons[ID].CBills = 40000;
	setWeaponNames (ID, "MLaser", "Medium Laser");
	weapons[ID].MW2_ID = 5600;
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = green;
	weapons[ID].soundWhenFired = "MECMLASR.SFL";
	weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

	ID = WeaponType::IS1_Large_Laser;
	weapons[ID].Heat = 8;
	weapons[ID].MaxDamage = 8; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 450; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 500;
	weapons[ID].Criticals = 2;
	weapons[ID].AvailableInYear = 2025; // Year of field/open market availability
	weapons[ID].CBills = 100000;
	setWeaponNames (ID, "LLaser", "Large Laser");
	weapons[ID].MW2_ID = 5500;
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = blue;
	weapons[ID].soundWhenFired = "MECBLASR.SFL";
	weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

	ID = WeaponType::IS1_PPC;
	weapons[ID].Heat = 10;
	weapons[ID].MaxDamage = 10; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 540; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 700;
	weapons[ID].Criticals = 3;
	weapons[ID].AvailableInYear = 2460; // Year of field/open market availability
	weapons[ID].CBills = 200000;
	setWeaponNames (ID, "PPC");
	weapons[ID].MW2_ID = 5300;
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = white;
	weapons[ID].soundWhenFired = "MECMISNR.SFL";
	weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

	ID = WeaponType::IS2_Small_Pulse_Laser;
	weapons[ID].Heat = 2;
	weapons[ID].MaxDamage = 3; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 90; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 100;
	weapons[ID].AvailableInYear = 2609; // Year of field/open market availability
	weapons[ID].CBills = 16000;
	setWeaponNames (ID, "SPLaser", "Small Pulse Laser");
	weapons[ID].MW2_ID = 6000;
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = red;
	weapons[ID].soundWhenFired = "MECPLASR.SFL";
	weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

	ID = WeaponType::IS2_Medium_Pulse_Laser;
	weapons[ID].Heat = 4;
	weapons[ID].MaxDamage = 6; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 180; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 200;
	weapons[ID].AvailableInYear = 2609; // Year of field/open market availability
	weapons[ID].CBills = 60000;
	setWeaponNames (ID, "MPLaser", "Medium Pulse Laser");
	weapons[ID].MW2_ID = 5900;
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = green;
	weapons[ID].soundWhenFired = "MECPLASR.SFL";
	weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

	ID = WeaponType::IS1_Large_Pulse_Laser;
	weapons[ID].Heat = 10;
	weapons[ID].MaxDamage = 9; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 300; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 700;
	weapons[ID].Criticals = 2;
	weapons[ID].AvailableInYear = 2609; // Year of field/open market availability
	weapons[ID].CBills = 175000;
	setWeaponNames (ID, "LPLaser", "Large Pulse Laser");
	weapons[ID].MW2_ID = 5800;
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = blue;
	weapons[ID].soundWhenFired = "MECPLASR.SFL";
	weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

	ID = WeaponType::IS2_ER_Small_Laser;
	weapons[ID].Heat = 2;
	weapons[ID].MaxDamage = 3; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 150; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 50;
	weapons[ID].AvailableInYear = 2620; // Year of field/open market availability
	weapons[ID].CBills = 11250;
	weapons[ID].AmmoTypes[0] = 0; // Ammo that this weapon can use
	setWeaponNames (ID, "ER SLas", "ER Small Laser");
	weapons[ID].MW2_ID = 21900; // Weapon does not exist in MW2
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = red;
	weapons[ID].soundWhenFired = "MECSLASR.SFL";
	weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

	ID = WeaponType::IS2_ER_Medium_Laser;
	weapons[ID].Heat = 5;
	weapons[ID].MaxDamage = 5; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 360; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 100;
	weapons[ID].AvailableInYear = 2620; // Year of field/open market availability
	weapons[ID].CBills = 80000;
	weapons[ID].AmmoTypes[0] = 0; // Ammo that this weapon can use
	setWeaponNames (ID, "ER MLas", "ER Medium Laser");
	weapons[ID].MW2_ID = 22000; // Weapon does not exist in MW2
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = green;
	weapons[ID].soundWhenFired = "MECMLASR.SFL";
	weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

	ID = WeaponType::IS2_ER_Large_Laser;
	weapons[ID].Heat = 12;
	weapons[ID].MaxDamage = 8; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 570; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 500;
	weapons[ID].Criticals = 2;
	weapons[ID].AvailableInYear = 2620; // Year of field/open market availability
	weapons[ID].CBills = 200000;
	weapons[ID].AmmoTypes[0] = 0; // Ammo that this weapon can use
	setWeaponNames (ID, "ER LLaser", "ER Large Laser");
	weapons[ID].MW2_ID = 5400;
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = blue;
	weapons[ID].soundWhenFired = "MECBLASR.SFL";
	weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

	// In 3060, this is still an experimental weapon, but it's actually used and salvageable in MW3:PM
	// X-Pulse Lasers are described in Maximum Tech, p.84
	ID = WeaponType::IS3_X_Pulse_Laser_Large;
	weapons[ID].MinimumRangeInMeters = 0;
	weapons[ID].MaxRangeInMeters = 15*30;
	weapons[ID].soundWhenFired = "MECPLASR.SFL";
	weapons[ID].geometry = laserGeometry;
	weapons[ID].category = WeaponCategory::energy;
	weapons[ID].MaxDamage = 9;
	weapons[ID].TonnageTimes100 = 700;
	weapons[ID].AvailableInYear = 3078; // Year of field/open market availability - 3078: limited production, mass produced in 3145
	setWeaponNames (ID, "XPLL", "X-Pulse Laser Large");
	weapons[ID].MW2_ID = 23600; // Not in MW2 ...
	weapons[ID].MW2_31st_ID = 23600; // Not in MW2 ...
	//weapons[ID].MaxCount = 100; // ID's used by MW2
	weapons[ID].Criticals = 2;
	weapons[ID].flags = MWWeaponFlagsStdWeapon | MWweaponFlag_WorksUnderwater;
	weapons[ID].CBills = 275000;
	//weapons[ID].ammoUsedPerShot = 1;
	//weapons[ID].defyGravityDuration = 50;
	weapons[ID].shotColor = blue;

	// In 3060, this is still an experimental weapon, but it's actually used and salvageable in MW3:PM
	ID = WeaponType::IS3_X_Pulse_Laser_Medium;
	weapons[ID].MinimumRangeInMeters = 0;
	weapons[ID].MaxRangeInMeters = 9*30;
	weapons[ID].soundWhenFired = "MECPLASR.SFL";
	weapons[ID].geometry = laserGeometry;
	weapons[ID].category = WeaponCategory::energy;
	weapons[ID].MaxDamage = 6;
	weapons[ID].TonnageTimes100 = 200;
	weapons[ID].AvailableInYear = 3078; // Year of field/open market availability - 3078: limited production, mass produced in 3145
	setWeaponNames (ID, "XPLM", "X-Pulse Laser Medium");
	weapons[ID].MW2_ID = 23700; // Not in MW2 ...
	weapons[ID].MW2_31st_ID = 23700; // Not in MW2 ...
	//weapons[ID].MaxCount = 400; // ID's used by MW2
	weapons[ID].Criticals = 1;
	weapons[ID].flags = MWWeaponFlagsStdWeapon | MWweaponFlag_WorksUnderwater;
	weapons[ID].CBills = 110000;
	//weapons[ID].ammoUsedPerShot = 1;
	//weapons[ID].defyGravityDuration = 50;
	weapons[ID].shotColor = green;

	// In 3060, this is still an experimental weapon, but it's actually used and salvageable in MW3:PM
	ID = WeaponType::IS3_X_Pulse_Laser_Small;
	weapons[ID].MinimumRangeInMeters = 0;
	weapons[ID].MaxRangeInMeters = 5*30;
	weapons[ID].soundWhenFired = "MECPLASR.SFL";
	weapons[ID].geometry = laserGeometry;
	weapons[ID].category = WeaponCategory::energy;
	weapons[ID].MaxDamage = 3;
	weapons[ID].TonnageTimes100 = 200;
	weapons[ID].AvailableInYear = 3078; // Year of field/open market availability - 3078: limited production, mass produced in 3145
	setWeaponNames (ID, "XPLS", "X-Pulse Laser Small");
	weapons[ID].MW2_ID = 23800; // Not in MW2 ...
	weapons[ID].MW2_31st_ID = 23800; // Not in MW2 ...
	//weapons[ID].MaxCount = 400; // ID's used by MW2
	weapons[ID].Criticals = 1;
	weapons[ID].flags = MWWeaponFlagsStdWeapon | MWweaponFlag_WorksUnderwater;
	weapons[ID].CBills = 31000;
	//weapons[ID].ammoUsedPerShot = 1;
	//weapons[ID].defyGravityDuration = 50;
	weapons[ID].shotColor = red;

	ID = WeaponType::IS2_ER_PPC;
	weapons[ID].Heat = 15;
	weapons[ID].MaxDamage = 10; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 690; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 700;
	weapons[ID].Criticals = 3;
	weapons[ID].AvailableInYear = 2760; // Year of field/open market availability
	weapons[ID].CBills = 300000;
	setWeaponNames (ID, "ER PPC", "ER PPC");
	weapons[ID].MW2_ID = 5200;
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = white;
	weapons[ID].soundWhenFired = "MECMISNR.SFL";
	weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

	ID = WeaponType::IS2_Light_Machine_Gun;
	weapons[ID].MaxDamage = 1; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 180; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 50;
	weapons[ID].Criticals = 1;
	weapons[ID].AvailableInYear = 1900; // Year of field/open market availability
	weapons[ID].CBills = 5000;
	setWeaponNames (ID, "LMG", "Light Machine Gun");
	weapons[ID].MW2_ID = 20000; // Not in MW2
	weapons[ID].MW2_31st_ID = weapons[ID].MW2_ID;
	weapons[ID].ammoUsedPerShot = 10;
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = grey;
	weapons[ID].category = WeaponCategory::bullet;
	weapons[ID].soundWhenFired = "MECMGUN1.SFL";
	setWeaponAmmoPair (WeaponType::IS2_Light_Machine_Gun, WeaponType::IS1_Machine_Gun_Ammo);

	ID = WeaponType::IS1_Machine_Gun;
	weapons[ID].MaxDamage = 2; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 90; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 50;
	weapons[ID].Criticals = 1;
	weapons[ID].AvailableInYear = 1900; // Year of field/open market availability
	weapons[ID].CBills = 5000;
	setWeaponNames (ID, "MG", "Machine Gun");
	weapons[ID].MW2_ID = 4300; //???
	weapons[ID].ammoUsedPerShot = 10;
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = grey;
	weapons[ID].category = WeaponCategory::bullet;
	weapons[ID].soundWhenFired = "MECMGUN1.SFL";

	ID = WeaponType::IS1_Machine_Gun_Ammo;
	weapons[ID].MaxDamage = 2; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 90; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 100;
	weapons[ID].ShotsPerTon = 2000; // If positive, this record describes ammo
	weapons[ID].AvailableInYear = 1900; // Year of field/open market availability
	weapons[ID].CBills = 1000;
	weapons[ID].flags = MWWeaponFlagsStdAmmo;
	setWeaponNames (ID, "A(MG)", "Ammo (Machine Gun)");
	weapons[ID].MW2_ID = 15400; // ???
	setWeaponAmmoPair (WeaponType::IS1_Machine_Gun, WeaponType::IS1_Machine_Gun_Ammo);
	weapons[ID].shotColor = grey;
	weapons[ID].category = WeaponCategory::bullet;

	ID = WeaponType::IS2_Heavy_Machine_Gun;
	weapons[ID].MaxDamage = 3; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 60; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 50;
	weapons[ID].Criticals = 1;
	weapons[ID].AvailableInYear = 1900; // Year of field/open market availability
	weapons[ID].CBills = 7500;
	setWeaponNames (ID, "HMG", "Heavy Machine Gun");
	weapons[ID].MW2_ID = 22300; // Not in MW2
	weapons[ID].MW2_31st_ID = weapons[ID].MW2_ID;
	weapons[ID].ammoUsedPerShot = 10;
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = grey;
	weapons[ID].category = WeaponCategory::bullet;
	weapons[ID].soundWhenFired = "MECMGUN1.SFL";

	ID = WeaponType::IS2_Heavy_Machine_Gun_Ammo;
	weapons[ID].MaxDamage = 3; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 60; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 100;
	weapons[ID].ShotsPerTon = 1000; // If positive, this record describes ammo
	weapons[ID].AvailableInYear = 1900; // Year of field/open market availability
	weapons[ID].CBills = 1000;
	weapons[ID].flags = MWWeaponFlagsStdAmmo;
	setWeaponNames (ID, "A(HMG)", "Ammo (Heavy Machine Gun)");
	weapons[ID].MW2_ID = 22400; // Not in MW2
	weapons[ID].MW2_31st_ID = weapons[ID].MW2_ID;
	setWeaponAmmoPair (WeaponType::IS2_Heavy_Machine_Gun, WeaponType::IS2_Heavy_Machine_Gun_Ammo);
	weapons[ID].shotColor = grey;
	weapons[ID].category = WeaponCategory::bullet;

	int ACnums[] = {20, 10, 5, 2};
	const char* ACnumStr[] = {"20", "10", "5", "2"};
	for (int i = 0; i < 4; i++) {
		int ID = ((int)WeaponType::IS1_Autocannon_20) + i;
		BGCPString shortName = "AC";
		shortName += ACnumStr[i];
		BGCPString longName = "Autocannon/";
		longName += ACnumStr[i];
		setWeaponNames(ID, shortName, longName);
		weapons[ID].Heat = 1;
		weapons[ID].AvailableInYear = 3035; // Year of field/open market availability
		weapons[ID].MW2_ID = 4800-i*100;
		weapons[ID].AvailableInYear = 2250; // Year of field/open market availability
		setWeaponAmmoPair (ID, WeaponType::IS1_Autocannon_Ammo);
		weapons[ID].ammoUsedPerShot = ACnums[i];
		weapons[ID].fireDuration = 4;
		weapons[ID].coolDown = 6;
		weapons[ID].geometry = autocannonGeometry;
		weapons[ID].shotColor = grey;
		weapons[ID].soundWhenFired = "MECACAN1.SFL";
		weapons[ID].category = WeaponCategory::bullet;
		weapons[ID].MaxDamage = ACnums[i]; // Maximum weapon damage
	}

	ID = WeaponType::IS1_Autocannon_2;
	weapons[ID].MaxRangeInMeters = 720;
	weapons[ID].TonnageTimes100 = 600;
	weapons[ID].weaponScale = 0.1 *  weapons[ID].Criticals;

	ID = WeaponType::IS1_Autocannon_5;
	weapons[ID].MaxRangeInMeters = 540; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 800;
	weapons[ID].Criticals = 4;
	weapons[ID].CBills = 125000;
	weapons[ID].weaponScale = 0.1 * weapons[ID].Criticals;

	ID = WeaponType::IS1_Autocannon_10;
	weapons[ID].Heat = 3;
	weapons[ID].MaxRangeInMeters = 450; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 1200;
	weapons[ID].Criticals = 7;
	weapons[ID].CBills = 200000;
	weapons[ID].weaponScale = 0.1 * weapons[ID].Criticals;

	ID = WeaponType::IS1_Autocannon_20;
	weapons[ID].Heat = 7;
	weapons[ID].MaxRangeInMeters = 270; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 1400;
	weapons[ID].Criticals = 10;
	weapons[ID].CBills = 300000;
	weapons[ID].weaponScale = 0.1 * weapons[ID].Criticals;

	ID = WeaponType::IS1_Autocannon_Ammo;
	weapons[ID].MaxRangeInMeters = 800; // The range where the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 100;
	weapons[ID].ShotsPerTon = 100;
	weapons[ID].AvailableInYear = 2250; // Year of field/open market availability
	weapons[ID].CBills = 10000;
	setWeaponNames (ID, "Ammo (AC)", "Ammo (Autocannon)");
	weapons[ID].MW2_ID = 14500;
	weapons[ID].MaxCount = 400; // ID's used by MW2
	weapons[ID].flags = MWWeaponFlagsStdAmmo;

	for (int i = 0; i < 4; i++) {
		int wID = WeaponType::IS1_Autocannon_20+i;
		setWeaponAmmoPair (wID, WeaponType::IS1_Autocannon_Ammo); 
	}

	ID = WeaponType::IS2_Anti_Missile_System;
	weapons[ID].Heat = 1;
	weapons[ID].MaxRangeInMeters = 90; // The range where the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 50;
	weapons[ID].AvailableInYear = 3040; // Year of field/open market availability
	weapons[ID].CBills = 100000;
	weapons[ID].AmmoTypes[0] = WeaponType::IS1_Machine_Gun_Ammo; // Ammo that this weapon can use
	//weapons[ID].flags = MWWeaponFlag_MWCannotFire | MWWeaponFlag_CountedInMEK; // use standard flags to allow firing
	setWeaponNames (ID, "AMS", "Anti-Missile System");
	weapons[ID].MW2_ID = 6200;
	setWeaponAmmoPair (WeaponType::IS2_Anti_Missile_System, WeaponType::IS1_Machine_Gun_Ammo);
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = grey;
	weapons[ID].ammoUsedPerShot = 1;
	weapons[ID].category = WeaponCategory::bullet;
	weapons[ID].soundWhenFired = "MECMGUN1.SFL";
	weapons[ID].MaxDamage = 2;

	ID = WeaponType::IS2_Rotary_AC_2;
	weapons[ID].Heat = 1;
	weapons[ID].MaxDamage = 2; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 540; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 800;
	weapons[ID].Criticals = 3;
	weapons[ID].AvailableInYear = 3062; // Year of field/open market availability
	weapons[ID].CBills = 175000;
	setWeaponNames (ID, "RAC/2", "Rotary Autocannon/2");
	setWeaponAmmoPair (ID, WeaponType::IS1_Autocannon_Ammo);
	weapons[ID].shotColor = grey;
	weapons[ID].category = WeaponCategory::bullet;
	weapons[ID].weaponScale = 0.1 *  weapons[ID].Criticals;

	ID = WeaponType::IS2_Rotary_AC_5;
	weapons[ID].Heat = 1;
	weapons[ID].MaxDamage = 5; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 450; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 1000;
	weapons[ID].Criticals = 6;
	weapons[ID].AvailableInYear = 3062; // Year of field/open market availability
	weapons[ID].CBills = 275000;
	//weapons[ID].AmmoTypes[0] = IS1_Autocannon_Ammo; // Ammo that this weapon can use
	setWeaponNames (ID, "RAC/5", "Rotary Autocannon/5");
	setWeaponAmmoPair (ID, WeaponType::IS1_Autocannon_Ammo);
	weapons[ID].shotColor = grey;
	weapons[ID].category = WeaponCategory::bullet;
	weapons[ID].weaponScale = 0.1 *  weapons[ID].Criticals;

	int ISUACCriticals[] = {10, 7, 5, 3};
	for (int i = 0; i < 4; i++) {
		int ID = ((int)WeaponType::IS2_Ultra_Autocannon_20)+i;
		weapons[ID].AmmoTypes[0] = WeaponType::IS1_Autocannon_Ammo;
		shortName = "UAC";
		shortName += ACnumStr[i];
		longName = "Ultra Autocannon/";
		longName += ACnumStr[i];
		setWeaponNames(ID, shortName, longName);
		weapons[ID].Heat = 1;
		weapons[ID].AvailableInYear = 3035; // Year of field/open market availability
		weapons[ID].AmmoTypes[0] = WeaponType::IS1_Autocannon_Ammo; // Ammo that this weapon can use
		setWeaponAmmoPair (ID, WeaponType::IS1_Autocannon_Ammo);
		weapons[ID].fireDuration = 2;
		weapons[ID].coolDown = 3;
		weapons[ID].ammoUsedPerShot = ACnums[i];
		weapons[ID].geometry = autocannonGeometry;
		weapons[ID].shotColor = grey;
		weapons[ID].soundWhenFired = "MECACAN1.SFL";
		weapons[ID].category = WeaponCategory::bullet;
		weapons[ID].MaxDamage = ACnums[i]; // Maximum weapon damage
		weapons[ID].Criticals = ISUACCriticals[i];
		weapons[ID].weaponScale = 0.1 *  weapons[ID].Criticals;
	}

	ID = WeaponType::IS2_Ultra_Autocannon_2;
	weapons[ID].MaxRangeInMeters = 540; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 700;
	weapons[ID].CBills = 120000;
	weapons[ID].MW2_31st_ID = 21300; // Not in MW2
	weapons[ID].MW2_ID = weapons[ID].MW2_31st_ID;

	ID = WeaponType::IS2_Ultra_Autocannon_5;
	weapons[ID].MaxRangeInMeters = 600; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 900;
	weapons[ID].CBills = 200000;
	weapons[ID].MW2_31st_ID = 21400; // Not in MW2
	weapons[ID].MW2_ID = weapons[ID].MW2_31st_ID;

	ID = WeaponType::IS2_Ultra_Autocannon_10;
	weapons[ID].Heat = 4;
	weapons[ID].MaxRangeInMeters = 540; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 1300;
	weapons[ID].CBills = 320000;
	weapons[ID].MW2_31st_ID = 21500; // Not in MW2
	weapons[ID].MW2_ID = weapons[ID].MW2_31st_ID;

	ID = WeaponType::IS2_Ultra_Autocannon_20;
	weapons[ID].Heat = 8;
	weapons[ID].MaxRangeInMeters = 750; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 1500;
	weapons[ID].CBills = 480000;
	weapons[ID].MW2_31st_ID = 21600; // Not in MW2
	weapons[ID].MW2_ID = weapons[ID].MW2_31st_ID;

	int isLBXCriticals[4] = {11, 6, 5, 4};
	for (int i = 0; i < 4; i++) {
		int ID = ((int) WeaponType::IS2_LB_X_Autocannon_20)+i;
		weapons[ID].AmmoTypes[0] = WeaponType::IS1_Autocannon_Ammo;
		shortName = "LB";
		shortName += ACnumStr[i];
		shortName += "X AC";
		longName = "LB ";
		longName += ACnumStr[i];
		longName += "-X Autocannon/";
		setWeaponNames(ID, shortName, longName);
		weapons[ID].Heat = 1;
		weapons[ID].AvailableInYear = 3035; // Year of field/open market availability
		setWeaponAmmoPair (ID, WeaponType::IS1_Autocannon_Ammo);
		setWeaponAmmoPair(ID, WeaponType::IS2_LB_X_Autocannon_Cluster_Ammo);
		weapons[ID].geometry = autocannonGeometry;
		weapons[ID].shotColor = grey;
		weapons[ID].soundWhenFired = "MECACAN1.SFL";
		weapons[ID].category = WeaponCategory::bullet;
		weapons[ID].Criticals = isLBXCriticals[i];
		weapons[ID].weaponScale = 0.1 *  weapons[ID].Criticals;
	}

	ID = WeaponType::IS2_LB_X_Autocannon_2;
	weapons[ID].MaxDamage = 2; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 810; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 600;
	weapons[ID].CBills = 150000;
	weapons[ID].MW2_31st_ID = 20100; // Not in MW2
	weapons[ID].MW2_ID = weapons[ID].MW2_31st_ID;
	weapons[ID].ammoUsedPerShot = 2;

	ID = WeaponType::IS2_LB_X_Autocannon_5;
	weapons[ID].MaxDamage = 5; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 630; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 900;
	weapons[ID].CBills = 250000;
	weapons[ID].MW2_31st_ID = 20200; // Not in MW2
	weapons[ID].MW2_ID = weapons[ID].MW2_31st_ID;
	weapons[ID].ammoUsedPerShot = 5;
	weapons[ID].weaponScale = 0.1 *  weapons[ID].Criticals;

	ID = WeaponType::IS2_LB_X_Autocannon_10;
	weapons[ID].Heat = 2;
	weapons[ID].MaxDamage = 10; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 540; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 1100;
	weapons[ID].CBills = 400000;
	weapons[ID].MW2_ID = 5000;
	weapons[ID].ammoUsedPerShot = 10;

	ID = WeaponType::IS2_LB_X_Autocannon_20;
	weapons[ID].Heat = 6;
	weapons[ID].MaxDamage = 20; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 360; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 1400;
	weapons[ID].CBills = 600000;
	weapons[ID].MW2_31st_ID = 20300; // Not in MW2
	weapons[ID].MW2_ID = weapons[ID].MW2_31st_ID;
	weapons[ID].ammoUsedPerShot = 20;

	ID = WeaponType::IS2_LB_X_Autocannon_Cluster_Ammo;
	weapons[ID].TonnageTimes100 = 1400;
	setWeaponNames (ID, "A(LBX Cl)", "Ammo (LB-X Cluster)");
	weapons[ID].Criticals = 11;
	weapons[ID].CBills = 34000;
	weapons[ID].MW2_ID = 20400; // Weapon does not exist in MW2
	weapons[ID].MW2_31st_ID = 20400;
	weapons[ID].ShotsPerTon = 100;
	setWeaponAmmoPair (ID, WeaponType::IS2_LB_X_Autocannon_20);
	setWeaponAmmoPair (ID, WeaponType::IS2_LB_X_Autocannon_10);
	setWeaponAmmoPair (ID, WeaponType::IS2_LB_X_Autocannon_5);
	setWeaponAmmoPair (ID, WeaponType::IS2_LB_X_Autocannon_2);

	// Described in Tech Manual, p. 219 and 341
	ID = WeaponType::IS2_Light_Gauss;
	weapons[ID].Heat = 1;
	weapons[ID].MaxDamage = 8; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 750; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 1200;
	weapons[ID].Criticals = 5;
	weapons[ID].AvailableInYear = 3056; // Year of field/open market availability
	weapons[ID].CBills = 275000;
	//weapons[ID].AmmoTypes[0] = IS2_Gauss_Ammo; // Ammo that this weapon can use
	setWeaponNames (ID, "Lt Gauss", "Light Gauss");
	weapons[ID].MW2_ID = 22500; // Not in MW2
	weapons[ID].MW2_31st_ID = weapons[ID].MW2_ID;
	weapons[ID].ammoUsedPerShot = 1;
	setWeaponAmmoPair (WeaponType::IS2_Light_Gauss, WeaponType::IS2_Light_Gauss_Ammo);
	weapons[ID].geometry = gaussCannonGeometry;
	weapons[ID].shotColor = grey;
	weapons[ID].soundWhenFired = "MECGAUNR.SFL";
	weapons[ID].category = WeaponCategory::bullet;
	weapons[ID].metersPerSecond = 3000;
	weapons[ID].weaponScale = 0.1 *  weapons[ID].Criticals;

	ID = WeaponType::IS2_Light_Gauss_Ammo;
	//weapons[ID].Heat = 0;
	weapons[ID].MaxDamage = 8; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 750; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 100;
	weapons[ID].AvailableInYear = 3056; // Year of field/open market availability
	weapons[ID].CBills = 20000;
	//weapons[ID].AmmoTypes[0] = 0; // Ammo that this weapon can use
	setWeaponNames (ID, "A(LtGaus)", "Ammo (Light Gauss)");
	weapons[ID].ShotsPerTon = 16;
	weapons[ID].MW2_ID = 22600; // Not in MW2
	weapons[ID].MW2_31st_ID = weapons[ID].MW2_ID;
	weapons[ID].flags = MWWeaponFlagsStdAmmo;

	ID = WeaponType::IS2_Gauss;
	weapons[ID].Heat = 1;
	weapons[ID].MaxDamage = 15; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 660; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 1500;
	weapons[ID].Criticals = 7;
	weapons[ID].AvailableInYear = 3040; // Year of field/open market availability
	weapons[ID].CBills = 300000;
	//weapons[ID].AmmoTypes[0] = IS2_Gauss_Ammo; // Ammo that this weapon can use
	setWeaponNames (ID, "Gauss");
	weapons[ID].MW2_ID = 4400;
	weapons[ID].ammoUsedPerShot = 1;
	setWeaponAmmoPair (WeaponType::IS2_Gauss, WeaponType::IS2_Gauss_Ammo);
	weapons[ID].geometry = gaussCannonGeometry;
	weapons[ID].shotColor = grey;
	weapons[ID].soundWhenFired = "MECGAUNR.SFL";
	weapons[ID].category = WeaponCategory::bullet;
	weapons[ID].metersPerSecond = 3000;
	weapons[ID].weaponScale = 0.1 *  weapons[ID].Criticals;

	ID = WeaponType::IS2_Gauss_Ammo;
	//weapons[ID].Heat = 0;
	weapons[ID].MaxDamage = 15; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 660; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 100;
	weapons[ID].AvailableInYear = 3040; // Year of field/open market availability
	weapons[ID].CBills = 20000;
	//weapons[ID].AmmoTypes[0] = 0; // Ammo that this weapon can use
	setWeaponNames (ID, "A(Gauss)", "Ammo (Gauss)");
	weapons[ID].ShotsPerTon = 8;
	weapons[ID].MW2_ID = 14400;
	weapons[ID].flags = MWWeaponFlagsStdAmmo;

	// Described in Tech Manual, p. 218 and 341
	ID = WeaponType::IS2_Heavy_Gauss;
	weapons[ID].Heat = 2;
	weapons[ID].MaxDamage = 25; // Maximum weapon damage. todo: actually depends on range, see Tech Manual.
	weapons[ID].MaxRangeInMeters = 600; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 1800;
	weapons[ID].Criticals = 11;
	weapons[ID].AvailableInYear = 3061; // Year of field/open market availability
	weapons[ID].CBills = 500000;
	//weapons[ID].AmmoTypes[0] = IS2_Gauss_Ammo; // Ammo that this weapon can use
	setWeaponNames (ID, "H Gauss", "Heavy Gauss");
	weapons[ID].MW2_ID = 22700; // Not in MW2
	weapons[ID].MW2_31st_ID = weapons[ID].MW2_ID;
	weapons[ID].ammoUsedPerShot = 1;
	setWeaponAmmoPair (WeaponType::IS2_Heavy_Gauss, WeaponType::IS2_Heavy_Gauss_Ammo);
	weapons[ID].geometry = gaussCannonGeometry;
	weapons[ID].shotColor = grey;
	weapons[ID].soundWhenFired = "MECGAUNR.SFL";
	weapons[ID].category = WeaponCategory::bullet;
	weapons[ID].metersPerSecond = 3000;
	weapons[ID].weaponScale = 0.1 *  weapons[ID].Criticals;

	ID = WeaponType::IS2_Heavy_Gauss_Ammo;
	//weapons[ID].Heat = 0;
	weapons[ID].MaxDamage = 25; // Maximum weapon damage. todo: actually depends on range, see Tech Manual.
	weapons[ID].MaxRangeInMeters = 600; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 100;
	weapons[ID].AvailableInYear = 3061; // Year of field/open market availability
	weapons[ID].CBills = 20000;
	//weapons[ID].AmmoTypes[0] = 0; // Ammo that this weapon can use
	setWeaponNames (ID, "A(HGauss)", "Ammo (Heavy Gauss)");
	weapons[ID].ShotsPerTon = 4;
	weapons[ID].MW2_ID = 22800; // Not in MW2
	weapons[ID].MW2_31st_ID = weapons[ID].MW2_ID;
	weapons[ID].flags = MWWeaponFlagsStdAmmo;

	const char* SRMnames[] = {"SRM 2", "SRM 4", "SRM 6"};
	for (int i = 0; i < 3; i++) {
		int ID = ((int)WeaponType::IS1_SRM_2)+i;
		weapons[ID].MW2_ID = 4100-100*i;
		//weapons[ID].AmmoTypes[0] = IS1_SRM_Ammo; // Ammo that this weapon can use
		weapons[ID].AvailableInYear = 2370; // Year of field/open market availability
		setWeaponNames(ID, SRMnames[i]);
		weapons[ID].TonnageTimes100 = 100*(i+1);
		weapons[ID].Heat = 2+i;
		weapons[ID].ammoUsedPerShot = 2*(i+1);
		setWeaponAmmoPair (ID, WeaponType::IS1_SRM_Ammo);
		weapons[ID].geometry = missileTubeGeometry;
		weapons[ID].MaxDamage = 4 * (i+1);
		weapons[ID].MaxRangeInMeters = 270; // At that range, missiles run out of fuel and start falling
		if (i == 2) {
			// SRM-6
			weapons[ID].xreps = 3;
			weapons[ID].yreps = 2;
		} else {
			// SRM-2 and SRM-4
			weapons[ID].xreps = 2*(i+1);
			weapons[ID].yreps = 1;
		}
		weapons[ID].defyGravityDuration = 0.45;
		weapons[ID].soundWhenFired = "MECBBAAT.SFL";
		weapons[ID].category = WeaponCategory::missile;
		weapons[ID].metersPerSecond = 200;
	}
	weapons[WeaponType::IS1_SRM_2].CBills = 10000;
	weapons[WeaponType::IS1_SRM_4].CBills = 60000;

	ID = WeaponType::IS1_SRM_6;
	weapons[ID].Criticals = 2;
	weapons[ID].CBills = 80000;

	for (int ID = WeaponType::IS1_SRM_Ammo; ID <= WeaponType::IS1_SRM_6_Ammo; ++ID) {
		weapons[ID].MaxDamage = 2; // Maximum weapon damage
		//weapons[ID].MinDamage = 2; // Minimum weapon damage at maximum range
		weapons[ID].MaxRangeInMeters = 270; // At that range, missiles run out of fuel and start falling
		weapons[ID].TonnageTimes100 = 100;
		weapons[ID].ShotsPerTon = 50; // If positive, this record describes ammo
		weapons[ID].AvailableInYear = 2370; // Year of field/open market availability
		weapons[ID].CBills = 27000;
		setWeaponNames (ID, "A(SRM)", "Ammo (SRM)");
		weapons[ID].MW2_ID = 13900;
		weapons[ID].flags = MWWeaponFlagsStdAmmo;
	}

	setWeaponNames(WeaponType::IS1_SRM_2_Ammo, "A(SRM 2)", "Ammo (SRM 2)");
	setWeaponAmmoPair(WeaponType::IS1_SRM_2, WeaponType::IS1_SRM_2_Ammo);
	weapons[IS1_SRM_2].MW2_ID = 14100;

	setWeaponNames(WeaponType::IS1_SRM_4_Ammo, "A(SRM 4)", "Ammo (SRM 4)");
	setWeaponAmmoPair(WeaponType::IS1_SRM_4, WeaponType::IS1_SRM_4_Ammo);
	weapons[IS1_SRM_4_Ammo].MW2_ID = 14000;

	setWeaponNames(WeaponType::IS1_SRM_6_Ammo, "A(SRM 6)", "Ammo (SRM 6)");
	setWeaponAmmoPair(WeaponType::IS1_SRM_6, WeaponType::IS1_SRM_6_Ammo);
	weapons[IS1_SRM_6_Ammo].MW2_ID = 13900;

	const char* LRMnames[] = {"LRM 5", "LRM 10", "LRM 15", "LRM 20"};
	for (int i = 0; i < 4; i++) {
		int ID = ((int)WeaponType::IS1_LRM_5)+i;
		weapons[ID].AvailableInYear = 2300;
		weapons[ID].MW2_ID = 3800-i*100;
		setWeaponNames(ID, LRMnames[i]);
		setWeaponAmmoPair (ID, WeaponType::IS1_LRM_Ammo);
		weapons[ID].ammoUsedPerShot = 5*(i+1);
		weapons[ID].geometry = missileTubeGeometry;
		weapons[ID].yreps = i+1;
		weapons[ID].xreps = 5;
		weapons[ID].soundWhenFired = "MECBBAAT.SFL";
		weapons[ID].category = WeaponCategory::missile;
		weapons[ID].metersPerSecond = 200;
		weapons[ID].MaxDamage = 5 * (i+i);
		weapons[ID].MaxRangeInMeters = 630; // At that range, missiles run out of fuel and start falling
		weapons[ID].defyGravityDuration = 3.15;
	}

	ID = WeaponType::IS1_LRM_5;
	weapons[ID].Heat = 6;
	weapons[ID].TonnageTimes100 = 200;
	weapons[ID].CBills = 30000;

	ID = WeaponType::IS1_LRM_10;
	weapons[ID].Heat = 4;
	weapons[ID].TonnageTimes100 = 500;
	weapons[ID].Criticals = 2;
	weapons[ID].CBills = 100000;

	ID = WeaponType::IS1_LRM_15;
	weapons[ID].Heat = 5;
	weapons[ID].TonnageTimes100 = 700;
	weapons[ID].Criticals = 3;
	weapons[ID].CBills = 175000;

	ID = WeaponType::IS1_LRM_20;
	weapons[ID].Heat = 6;
	weapons[ID].TonnageTimes100 = 1000;
	weapons[ID].Criticals = 5;
	weapons[ID].CBills = 250000;

	for (int ID = WeaponType::IS1_LRM_Ammo; ID <= WeaponType::IS1_LRM_20_Ammo; ++ID) {
		weapons[ID].MinimumRangeInMeters = 180;
		weapons[ID].MaxRangeInMeters = 630; // At that range, missiles run out of fuel and start falling
		weapons[ID].TonnageTimes100 = 100;
		weapons[ID].ShotsPerTon = 120; // If positive, this record describes ammo
		weapons[ID].AvailableInYear = 2300; // Year of field/open market availability
		weapons[ID].CBills = 30000;
		setWeaponNames (ID, "A(LRM)", "Ammo (LRM)");
		weapons[ID].MW2_ID = 13500;
		weapons[ID].MaxCount = 400; // ID's used by MW2
		weapons[ID].flags = MWWeaponFlagsStdAmmo;
	}

	setWeaponNames (WeaponType::IS1_LRM_5_Ammo, "A(LRM5)", "Ammo (LRM 5)");
	setWeaponAmmoPair(WeaponType::IS1_LRM_5, WeaponType::IS1_LRM_5_Ammo);

	setWeaponNames (WeaponType::IS1_LRM_10_Ammo, "A(LRM10)", "Ammo (LRM 10)");
	setWeaponAmmoPair(WeaponType::IS1_LRM_10, WeaponType::IS1_LRM_10_Ammo);

	setWeaponNames (WeaponType::IS1_LRM_15_Ammo, "A(LRM15)", "Ammo (LRM 15)");
	setWeaponAmmoPair(WeaponType::IS1_LRM_15, WeaponType::IS1_LRM_15_Ammo);

	setWeaponNames (WeaponType::IS1_LRM_20_Ammo, "A(LRM20)", "Ammo (LRM 20)");
	setWeaponAmmoPair(WeaponType::IS1_LRM_20, WeaponType::IS1_LRM_20_Ammo);

	for (int i = 0; i < 4; i++) {
		int ID = ((int)WeaponType::IS3_Thunderbolt_5)+i;
		weapons[ID].AvailableInYear = 3072; // But available in MW3:PM ...
		weapons[ID].MW2_ID = 22900+i*100; // Not in MW2
		weapons[ID].MW2_31st_ID = weapons[ID].MW2_ID;
		setWeaponAmmoPair (ID, WeaponType::IS3_Thunderbolt_Ammo);
		weapons[ID].ammoUsedPerShot = i+1;
		weapons[ID].geometry = missileTubeGeometry;
		weapons[ID].yreps = i+1;
		weapons[ID].xreps = 5;
		weapons[ID].soundWhenFired = "MECBBAAT.SFL";
		weapons[ID].category = WeaponCategory::missile;
		weapons[ID].metersPerSecond = 200;
		weapons[ID].MaxDamage = 5 * (i+i);
		weapons[ID].MaxRangeInMeters = 540; // At that range, missiles run out of fuel and start falling
		weapons[ID].defyGravityDuration = 3;
	}

	ID = WeaponType::IS3_Thunderbolt_5;
	setWeaponNames (ID, "TBolt 5", "Thunderbolt 5");
	weapons[ID].Heat = 3;
	weapons[ID].TonnageTimes100 = 300;
	weapons[ID].CBills = 50000;

	ID = WeaponType::IS3_Thunderbolt_10;
	setWeaponNames (ID, "TBolt 10", "Thunderbolt 10");
	weapons[ID].Heat = 5;
	weapons[ID].TonnageTimes100 = 700;
	weapons[ID].Criticals = 2;
	weapons[ID].CBills = 175000;

	ID = WeaponType::IS3_Thunderbolt_15;
	setWeaponNames (ID, "TBolt 15", "Thunderbolt 15");
	weapons[ID].Heat = 7;
	weapons[ID].TonnageTimes100 = 1100;
	weapons[ID].Criticals = 3;
	weapons[ID].CBills = 325000;

	ID = WeaponType::IS3_Thunderbolt_20;
	setWeaponNames (ID, "TBolt 20", "Thunderbolt 20");
	weapons[ID].Heat = 8;
	weapons[ID].TonnageTimes100 = 1500;
	weapons[ID].Criticals = 5;
	weapons[ID].CBills = 450000;

	ID = IS3_Thunderbolt_Ammo;
	setWeaponNames (ID, "A(TBolt)", "Ammo (Thunderbolt)");
	weapons[ID].TonnageTimes100 = 100;
	weapons[ID].Criticals = 1;
	weapons[ID].CBills = 50000;
	weapons[ID].ShotsPerTon = 12; // If positive, this record describes ammo

	// Depicted in MW2:Mercs mission mcc3 as a missile weapon, but actually more a ballistic weapon?
	// todo: the weapon stats have been changed for Mercs mission mcc3
	ID = WeaponType::IS1_Long_Tom;
	weapons[ID].MinimumRangeInMeters = 300;
	weapons[ID].MaxRangeInMeters = 10000;
	weapons[ID].soundWhenFired = "MECBBAAT.SFL";
	weapons[ID].geometry = missileTubeGeometry;
	weapons[ID].category = WeaponCategory::missile;
	weapons[ID].metersPerSecond = 400;
	weapons[ID].MaxDamage = 100;
	weapons[ID].TonnageTimes100 = 3000;
	weapons[ID].AvailableInYear = 2300; // Year of field/open market availability
	setWeaponNames (ID, "Long Tom", "Long Tom");
	weapons[ID].MaxCount = 400; // ID's used by MW2
	weapons[ID].Criticals = 30;
	weapons[ID].flags = MWWeaponFlagsStdWeapon;
	weapons[ID].CBills = 450000;
	weapons[ID].ammoUsedPerShot = 1;
	weapons[ID].defyGravityDuration = 50;

	// todo: the weapon stats have been changed for Mercs mission mcc3
	ID = WeaponType::IS1_Long_Tom_Ammo;
	weapons[ID].Heat = 6;
	weapons[ID].TonnageTimes100 = 1000;
	weapons[ID].ShotsPerTon = 50; // If positive, this record describes ammo
	weapons[ID].flags = MWWeaponFlagsStdAmmo;
	weapons[ID].CBills = 10000;
	setWeaponNames (ID, "A(LT)", "Ammo (Long Tom)");
	setWeaponAmmoPair(WeaponType::IS1_Long_Tom, WeaponType::IS1_Long_Tom_Ammo);

	ID = WeaponType::IS2_MRM_10;
	weapons[ID].Heat = 4;
	weapons[ID].TonnageTimes100 = 300;
	weapons[ID].Criticals = 2;
	weapons[ID].CBills = 50000;
	setWeaponNames (ID, "MRM 10", "Medium-Range Missiles 10");

	ID = WeaponType::IS2_MRM_20;
	weapons[ID].Heat = 6;
	weapons[ID].TonnageTimes100 = 700;
	weapons[ID].Criticals = 3;
	weapons[ID].CBills = 125000;
	setWeaponNames (ID, "MRM 20", "Medium-Range Missiles 20");

	ID = WeaponType::IS2_MRM_30;
	weapons[ID].Heat = 10;
	weapons[ID].TonnageTimes100 = 1000;
	weapons[ID].Criticals = 5;
	weapons[ID].CBills = 225000;
	setWeaponNames (ID, "MRM 30", "Medium-Range Missiles 30");

	ID = WeaponType::IS2_MRM_40;
	weapons[ID].Heat = 12;
	weapons[ID].TonnageTimes100 = 1200;
	weapons[ID].Criticals = 7;
	weapons[ID].CBills = 350000;
	setWeaponNames (ID, "MRM 40", "Medium-Range Missiles 40");

	for (size_t i = 0; i < 4; ++i) {
		int ID = ((int)WeaponType::IS2_MRM_10)+i;
		weapons[ID].MaxRangeInMeters = 450; // The maximum range for the weapon does minimum damage
		weapons[ID].AvailableInYear = 3058; // Year of field/open market availability
		weapons[ID].AmmoTypes[0] = WeaponType::IS2_MRM_Ammo; // Ammo that this weapon can use
		weapons[ID].soundWhenFired = "MECBBAAT.SFL";
		setWeaponAmmoPair(ID, WeaponType::IS2_MRM_Ammo);
		weapons[ID].category = WeaponCategory::missile;
		weapons[ID].metersPerSecond = 200;
		weapons[ID].MaxDamage = 10 * (i+i);
		weapons[ID].defyGravityDuration = 2.25;
	}

	ID = WeaponType::IS2_MRM_Ammo;
	weapons[ID].MaxDamage = 1; // Maximum weapon damage
	//weapons[ID].MinDamage = 1; // Minimum weapon damage at maximum range
	weapons[ID].MaxRangeInMeters = 450; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 100;
	weapons[ID].ShotsPerTon = 24; // If positive, this record describes ammo
	weapons[ID].AvailableInYear = 3058; // Year of field/open market availability
	weapons[ID].CBills = 27000;
	weapons[ID].AmmoTypes[0] = 0; // Ammo that this weapon can use
	setWeaponNames (ID, "Ammo(MRM)");
	weapons[ID].flags = MWWeaponFlagsStdAmmo;

	for (int i = 0; i < 9; i++) {
		int ID    = i + ((int)WeaponType::IS2_SRT_2);
		int oldID = i + ((int)WeaponType::IS1_SRM_2);
		copyWeapon (oldID, ID);
		if (ID < WeaponType::IS2_SRT_Ammo) {
			weapons[ID].shortName[2] = 'T';
		}
		bgstrcpy(weapons[ID].longName, weapons[ID].shortName, ShortWeaponNameLen);
		//weapons[ID].MW2_31st_ID = ID_UNUSED_MW2;
		//weapons[ID].MW2_ID = ID_UNUSED_MW2;
	}

	// todo: copy other ammo attributes
	setWeaponNames (IS2_SRT_Ammo, "Ammo(SRT)");
	setWeaponNames (IS2_LRT_Ammo, "Ammo(LRT)");

	for (int i = 0; i < 3; ++i) 
		setWeaponAmmoPair(WeaponType::IS2_SRT_2+i, WeaponType::IS2_SRT_Ammo);
	for (int i = 0; i < 4; ++i) 
		setWeaponAmmoPair(WeaponType::IS2_LRT_5+i, WeaponType::IS2_LRT_Ammo);

	for (int i = 0; i < 3; i++) {
		int ID = ((int)WeaponType::IS2_Streak_SRM_2) + i;
		weapons[ID].Heat = 2+i;
		weapons[ID].TonnageTimes100 = 150*(i+1);
		weapons[ID].AvailableInYear = 3058; // Year of field/open market availability
		longName = "Streak ";
		longName += SRMnames[i];
		shortName = 'S';
		shortName += SRMnames[i];
		weapons[ID].ammoUsedPerShot = 2*(i+1);
		setWeaponNames(ID, shortName, longName);
		setWeaponAmmoPair(ID, WeaponType::IS2_Streak_SRM_Ammo);
		weapons[ID].geometry = missileTubeGeometry;
		weapons[ID].soundWhenFired = "MECBBAAT.SFL";
		weapons[ID].category = WeaponCategory::missile;
		weapons[ID].MaxDamage = 4 * i;
		weapons[ID].MaxRangeInMeters = 270; // At that range, missiles run out of fuel and start falling
		if (i == 2) {
			weapons[ID].yreps = 2;
			weapons[ID].xreps = 3;
		} else {
			weapons[ID].xreps = 2*(i+1);
		}
		weapons[ID].metersPerSecond = 200;
		weapons[ID].defyGravityDuration = 0.45;
	}

	ID = WeaponType::IS2_Streak_SRM_2;
	weapons[ID].AvailableInYear = 3035; // Year of field/open market availability
	weapons[ID].CBills = 15000;
	weapons[ID].MW2_ID = 4200;

   ID = WeaponType::IS2_Streak_SRM_4;
   weapons[ID].CBills = 90000;
   weapons[ID].MW2_ID = 21700; // Weapon does not exist in MW2

   ID = WeaponType::IS2_Streak_SRM_6;
   weapons[ID].Criticals = 2;
   weapons[ID].CBills = 120000;
   weapons[ID].MW2_ID = 21800; // Weapon does not exist in MW2

   ID = WeaponType::IS2_Streak_SRM_Ammo;
   weapons[ID].MaxDamage = 2; // Maximum weapon damage
   //weapons[ID].MinDamage = 2; // Minimum weapon damage at maximum range
   weapons[ID].MaxRangeInMeters = 270; // At that range, missiles run out of fuel and start falling
   weapons[ID].TonnageTimes100 = 100;
   weapons[ID].ShotsPerTon = 50; // If positive, this record describes ammo
   weapons[ID].AvailableInYear = 2370; // Year of field/open market availability
   weapons[ID].CBills = 27000;
   setWeaponNames (ID, "A(SSRM)", "Ammo (Streak SRM)");
   weapons[ID].MW2_ID = 14200;
   weapons[ID].flags = MWWeaponFlagsStdAmmo;
   weapons[ID].geometry = missileTubeGeometry;
   weapons[ID].xreps = 2;

   ID = WeaponType::IS2_NARC;
   weapons[ID].MaxRangeInMeters = 270; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 300;
   weapons[ID].Criticals = 2;
   weapons[ID].AvailableInYear = 3035; // Year of field/open market availability
   weapons[ID].CBills = 100000;
   setWeaponNames (ID, "NARC");
   weapons[ID].MW2_ID = 6100;
   weapons[ID].soundWhenFired = "MECBBAAT.SFL";
   weapons[ID].flags = MWWeaponFlagsStdWeapon;
   weapons[ID].geometry = missileTubeGeometry;
   weapons[ID].category = WeaponCategory::missile;
   weapons[ID].metersPerSecond = 200;
   weapons[ID].ammoUsedPerShot = 1;

   ID = WeaponType::IS2_NARC_AMMO;
   weapons[ID].MaxDamage = 0; // Maximum weapon damage
   //weapons[ID].MinDamage = 0; // Minimum weapon damage at maximum range
   weapons[ID].MaxRangeInMeters = 270; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 100;
   weapons[ID].ShotsPerTon = 6; // If positive, this record describes ammo
   weapons[ID].AvailableInYear = 3035; // Year of field/open market availability
   weapons[ID].CBills = 6000;
   setWeaponNames (ID, "A(NARC)", "Ammo (NARC)");
   weapons[ID].MW2_ID = 16100;
   weapons[ID].flags = MWWeaponFlagsStdAmmo;
   setWeaponAmmoPair(IS2_NARC, IS2_NARC_AMMO);

   ID = WeaponType::IS2_Arrow_IV;
   setWeaponNames (ID, "Arrow IV");
   weapons[ID].MW2_ID = 6500;
   weapons[ID].soundWhenFired = "MECBBAAT.SFL";
   weapons[ID].category = WeaponCategory::missile;
   weapons[ID].metersPerSecond = 200;

   ID = WeaponType::IS2_Arrow_IV_Ammo;
   setWeaponNames (ID, "A(Arr.IV)", "Ammo (Arrow IV)");
   weapons[ID].MW2_ID = 16500;
   weapons[ID].flags = MWWeaponFlagsStdAmmo;
   setWeaponAmmoPair(IS2_Arrow_IV, IS2_Arrow_IV_Ammo);

   ID = WeaponType::IS2_SRM_Ammo_Inferno;
   setWeaponNames (ID, "A(SRM I)", "Ammo (Inferno SRM)");
   weapons[ID].flags = MWWeaponFlagsStdAmmo;
   for (size_t i = 0; i < 3; ++i) {
      setWeaponAmmoPair(IS1_SRM_2+i, IS2_SRM_Ammo_Inferno);
      weapons[ID].ammoUsedPerShot = 2*i;
   }
   weapons[ID].metersPerSecond = 200;

   ID = WeaponType::CE_Engine;
   setWeaponNames (ID, "Engine");
   weapons[ID].MW2_ID = 7850;
   weapons[ID].MW2_31st_ID = 5850;
   weapons[ID].MaxCount = 50;
   weapons[ID].flags = 0;

   ID = WeaponType::CE_Gyro;
   setWeaponNames (ID, "Gyro", "Gyroscope");
   weapons[ID].MW2_ID = 7800;
   weapons[ID].MW2_31st_ID = 5800;
   weapons[ID].MaxCount = 50;
   weapons[ID].Criticals = 4;
   weapons[ID].flags = 0;

   ID = WeaponType::CE_Life_Support;
   setWeaponNames (ID, "Life S.", "Life Support");
   weapons[ID].MW2_ID = 7900;
   weapons[ID].MW2_31st_ID = 5900;
   weapons[ID].MaxCount = 50;
   weapons[ID].Criticals = 2;
   weapons[ID].flags = 0;
   weapons[ID].CBills = 50000;

   ID = WeaponType::CE_Cockpit;
   setWeaponNames (ID, "Cockpit");
   weapons[ID].MW2_ID = 7750;
   weapons[ID].MW2_31st_ID = 5750;
   weapons[ID].MaxCount = 50;
   weapons[ID].flags = 0;
   weapons[ID].CBills = 200000;

   ID = WeaponType::CE_Sensors;
   setWeaponNames (ID, "Sensors");
   weapons[ID].MW2_ID = 7700;
   weapons[ID].MW2_31st_ID = 5700;
   weapons[ID].MaxCount = 50;
   weapons[ID].Criticals = 2;
   weapons[ID].flags = 0;

   ID = WeaponType::CE_Shoulder;
   setWeaponNames (ID, "Shoulder");
   weapons[ID].MW2_ID = 7300;
   weapons[ID].MW2_31st_ID = 5300;
   weapons[ID].MaxCount = 50;
   weapons[ID].flags = MWWeaponFlag_CountedInMEK;

   ID = WeaponType::CE_Upper_Arm_Actuator;
   setWeaponNames (ID, "UAA", "Upper Arm Actuator");
   weapons[ID].MW2_ID = 7350;
   weapons[ID].MW2_31st_ID = 5350;
   weapons[ID].MaxCount = 50;
   weapons[ID].flags = MWWeaponFlag_CountedInMEK;

   ID = WeaponType::CE_Lower_Arm_Actuator;
   setWeaponNames (ID, "LAA", "Lower Arm Actuator");
   weapons[ID].MW2_ID = 7400;
   weapons[ID].MW2_31st_ID = 5400;
   weapons[ID].MaxCount = 50;
   weapons[ID].flags = 0;

   ID = WeaponType::CE_Hand;
   setWeaponNames (ID, "Hand");
   weapons[ID].MW2_ID = 7450;
   weapons[ID].MW2_31st_ID = 5450;
   weapons[ID].MaxCount = 50;
   weapons[ID].flags = 0;

   ID = WeaponType::CE_Hip;
   setWeaponNames (ID, "Hip");
   weapons[ID].MW2_ID = 7500;
   weapons[ID].MW2_31st_ID = 5500;
   weapons[ID].MaxCount = 50;
   weapons[ID].flags = 0;

   ID = WeaponType::CE_Upper_Leg_Actuator;
   setWeaponNames (ID, "ULA", "Upper Leg Actuator");
   weapons[ID].MW2_ID = 7550;
   weapons[ID].MW2_31st_ID = 5550;
   weapons[ID].MaxCount = 50;
   weapons[ID].flags = 0;

   ID = WeaponType::CE_Lower_Leg_Actuator;
   setWeaponNames (ID, "LLA", "Lower Leg Actuator");
   weapons[ID].MW2_ID = 7600;
   weapons[ID].MW2_31st_ID = 5600;
   weapons[ID].MaxCount = 50;
   weapons[ID].flags = 0;

   ID = WeaponType::CE_Foot;
   setWeaponNames (ID, "Foot");
   weapons[ID].MW2_ID = 7650;
   weapons[ID].MW2_31st_ID = 5650;
   weapons[ID].MaxCount = 50;
   weapons[ID].flags = 0;

   ID = WeaponType::CE_Jump_Jet;
   setWeaponNames (ID, "Jump Jet");
   weapons[ID].MW2_ID = 8500;
   weapons[ID].MW2_31st_ID = 7000;
   weapons[ID].MaxCount = 50;
   weapons[ID].flags = 0;

   ID = WeaponType::IS_Heat_Sink;
   weapons[ID].Heat = -1;
   setWeaponNames (ID, "HS", "Heat Sink");
   weapons[ID].MW2_ID = 8000;
   weapons[ID].MW2_31st_ID = 5450;
   weapons[ID].MaxCount = 50;
   weapons[ID].flags = MWWeaponFlag_CountedInMEK;

   ID = WeaponType::IS_Double_Heat_Sink;
   weapons[ID].Heat = -2;
   weapons[ID].Criticals = 3;
   weapons[ID].MW2_ID = 8000;
   setWeaponNames (ID, "DHS", "Double Heat Sink");
   weapons[ID].flags = MWWeaponFlag_CountedInMEK;

   ID = WeaponType::IS_CASE;
   setWeaponNames (ID, "CASE");
   weapons[ID].MW2_ID = 9550;
   weapons[ID].MaxCount = 50;
   weapons[ID].TonnageTimes100 = 50;
   weapons[ID].flags = 0;

   ID = WeaponType::IS_Ferro_Fibrous;
   setWeaponNames (ID, "FF", "Ferro-Fibrous Armor");
   weapons[ID].MW2_ID = 9500;
   weapons[ID].MaxCount = 50;
   weapons[ID].flags = MWWeaponFlag_CountedInMEK;

   ID = WeaponType::IS_Endo_Steel;
   setWeaponNames (ID, "Endo", "Endo Steel Internals");
   weapons[ID].MW2_ID = 9000;
   weapons[ID].MaxCount = 50;
   weapons[ID].flags = MWWeaponFlag_CountedInMEK;

   ID = WeaponType::IS_Beagle;
   setWeaponNames (ID, "Beagle", "Beagle Active Probe");
   weapons[ID].TonnageTimes100 = 150;
   weapons[ID].AvailableInYear = 3045;
   weapons[ID].CBills = 20000;
   weapons[ID].MW2_31st_ID = 22222; // Not in MW2
   weapons[ID].MW2_ID = 22222; // Not in MW2
   weapons[ID].Criticals = 2;

   ID = WeaponType::IS_MASC;
   setWeaponNames (ID, "MASC");
   weapons[ID].flags = 0;

   // If there are not enough criticals/tonnage for all weapons on a mech,
   // the user should decide at mission start which weapons use the TC
   ID = WeaponType::IS_Targeting_Computer;
   setWeaponNames (ID, "TaCo", "Targeting Computer");
   weapons[ID].flags = 0;
   weapons[ID].TonnageTimes100 = 100;
   weapons[ID].AvailableInYear = 3062; // Year of field/open market availability
   weapons[ID].CBills = (int) (clanFactor * 10000);
   weapons[ID].MW2_31st_ID = 21200; // Not in MW2
   weapons[ID].MW2_ID = weapons[ID].MW2_31st_ID; // Not in MW2
   weapons[ID].Criticals = 1;

   ID = WeaponType::IS_TAG;
   setWeaponNames (ID, "TAG");

   ID = WeaponType::IS_Hatchet;
   setWeaponNames (ID, "Hatchet");

   ID = WeaponType::IS_Sword;
   setWeaponNames (ID, "Sword");

   ID = WeaponType::CE_Artemis_IV;
   setWeaponNames (ID, "Art IV", "Artemis IV");
   weapons[ID].flags = 0;
   weapons[ID].TonnageTimes100 = 100;
   weapons[ID].CBills = 100000;
   weapons[ID].Criticals = 1;
   weapons[ID].MW2_31st_ID = 20000;
   weapons[ID].MW2_ID = weapons[ID].MW2_31st_ID;

   ID = WeaponType::Clan_ER_Large_Laser;
   weapons[ID].Heat = 12;
   weapons[ID].MaxDamage = 10; // Maximum weapon damage
   weapons[ID].MaxRangeInMeters = 750; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 400;
   weapons[ID].AvailableInYear = 2620; // Year of field/open market availability
   weapons[ID].CBills = (int) (clanFactor * 200000);
   setWeaponNames (ID, "ER LLaser", "ER Large Laser");
   weapons[ID].MW2_31st_ID = 2200;
   weapons[ID].MW2_ID = 2200;
   weapons[ID].Criticals = 1;
   weapons[ID].geometry = laserGeometry;
   weapons[ID].shotColor = blue;
   weapons[ID].soundWhenFired = "MECBLASR.SFL";
   weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

   ID = WeaponType::Clan_ER_Medium_Laser;
   weapons[ID].Heat = 5;
   weapons[ID].MaxDamage = 7; // Maximum weapon damage
   weapons[ID].MaxRangeInMeters = 450; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 100;
   weapons[ID].CBills = (int) (clanFactor * 80000);
   setWeaponNames (ID, "ER MLaser", "ER Medium Laser");
   weapons[ID].MW2_31st_ID = 2300;
   weapons[ID].MW2_ID = 2300;
   weapons[ID].geometry = laserGeometry;
   weapons[ID].shotColor = green;
   weapons[ID].soundWhenFired = "MECMLASR.SFL";
   weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

   ID = WeaponType::Clan_ER_Small_Laser;
   weapons[ID].Heat = 2;
   weapons[ID].MaxDamage = 5; // Maximum weapon damage
   weapons[ID].MaxRangeInMeters = 180; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 50;
   weapons[ID].CBills = (int) (clanFactor * 11250);
   setWeaponNames (ID, "ER SLaser", "ER Small Laser");
   weapons[ID].MW2_31st_ID = 2400;
   weapons[ID].MW2_ID = 2400;
   weapons[ID].geometry = laserGeometry;
   weapons[ID].shotColor = red;
   weapons[ID].soundWhenFired = "MECSLASR.SFL";
   weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

   ID = WeaponType::Clan_ER_Micro_Laser;
   weapons[ID].Heat = 1;
   weapons[ID].MaxDamage = 2; // Maximum weapon damage
   weapons[ID].MaxRangeInMeters = 120; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 25;
   weapons[ID].AvailableInYear = 3060; // Year of field/open market availability
   weapons[ID].CBills = (int) (clanFactor * 10000);
   setWeaponNames (ID, "ER MicLas", "ER Micro Laser");
   weapons[ID].geometry = laserGeometry;
   weapons[ID].shotColor = red;
   weapons[ID].soundWhenFired = "MECSLASR.SFL";
   weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

   ID = WeaponType::Clan_Large_Heavy_Laser;
   weapons[ID].Heat = 18;
   weapons[ID].MaxDamage = 16; // Maximum weapon damage
   weapons[ID].MaxRangeInMeters = 450; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 400;
   weapons[ID].Criticals = 3;
   weapons[ID].AvailableInYear = 3059; // Year of field/open market availability
   weapons[ID].CBills = (int) (clanFactor * 250000);
   setWeaponNames (ID, "LHLaser", "Large Heavy Laser");
   weapons[ID].geometry = laserGeometry;
   weapons[ID].shotColor = blue;
   weapons[ID].soundWhenFired = "MECBLASR.SFL";
   weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

   ID = WeaponType::Clan_Medium_Heavy_Laser;
   weapons[ID].Heat = 7;
   weapons[ID].MaxDamage = 10; // Maximum weapon damage
   weapons[ID].MaxRangeInMeters = 570; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 100;
   weapons[ID].Criticals = 2;
   weapons[ID].AvailableInYear = 3059; // Year of field/open market availability
   weapons[ID].CBills = (int) (clanFactor * 100000);
   setWeaponNames (ID, "MHLaser", "Medium Heavy Laser");
   weapons[ID].geometry = laserGeometry;
   weapons[ID].shotColor = green;
   weapons[ID].soundWhenFired = "MECMLASR.SFL";
   weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

   ID = WeaponType::Clan_Small_Heavy_Laser;
   weapons[ID].Heat = 3;
   weapons[ID].MaxDamage = 6; // Maximum weapon damage
   weapons[ID].MaxRangeInMeters = 90; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 50;
   weapons[ID].AvailableInYear = 3059; // Year of field/open market availability
   weapons[ID].CBills = (int) (clanFactor * 20000);
   setWeaponNames (ID, "SHLaser", "Small Heavy Laser");
   weapons[ID].geometry = laserGeometry;
   weapons[ID].shotColor = red;
   weapons[ID].soundWhenFired = "MECSLASR.SFL";
   weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

   ID = WeaponType::Clan_Flamer;
   weapons[ID].Heat = 3;
   weapons[ID].MaxDamage = 2; // Maximum weapon damage
   weapons[ID].MaxRangeInMeters = 90; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 50;
   weapons[ID].AvailableInYear = 2025; // Year of field/open market availability
   weapons[ID].CBills = (int) (clanFactor * 7500);
   setWeaponNames (ID, "Flamer");
   weapons[ID].MW2_ID = 2000; // See Linebacker C, LBK03STD.MEK
   weapons[ID].MW2_31st_ID = 2000;
   weapons[ID].geometry = laserGeometry;
   weapons[ID].shotColor = red;

   ID = WeaponType::Clan_ER_PPC;
   weapons[ID].Heat = 15;
   weapons[ID].MaxDamage = 15; // Maximum weapon damage
   weapons[ID].MaxRangeInMeters = 690; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 600;
   weapons[ID].Criticals = 2;
   weapons[ID].AvailableInYear = 2760; // Year of field/open market availability
   weapons[ID].CBills = (int) (clanFactor * 300000);
   setWeaponNames (ID, "ER PPC");
   weapons[ID].MW2_31st_ID = 2100;
   weapons[ID].MW2_ID = 2100;
   weapons[ID].fireDuration = 0.5;
   weapons[ID].coolDown = 7.0;
   weapons[ID].geometry = laserGeometry;
   weapons[ID].weaponScale = 0.25;
   weapons[ID].shotColor = white;
   weapons[ID].soundWhenFired = "MECMISNR.SFL";
   weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

   ID = WeaponType::Clan_Large_Pulse_Laser;
   weapons[ID].Heat = 10;
   weapons[ID].MaxDamage = 10; // Maximum weapon damage
   weapons[ID].MaxRangeInMeters = 600; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 600;
   weapons[ID].Criticals = 2;
   weapons[ID].AvailableInYear = 2609; // Year of field/open market availability
   weapons[ID].CBills = (int) (clanFactor * 175000);
   setWeaponNames (ID, "LPLaser", "Large Pulse Laser");
   weapons[ID].MW2_31st_ID = 2500;
   weapons[ID].MW2_ID = 2500;
   weapons[ID].fireDuration = 3.0;
   weapons[ID].coolDown = 3.0;
   weapons[ID].geometry = laserGeometry;
   weapons[ID].shotColor = blue;
   weapons[ID].soundWhenFired = "MECPLASR.SFL";
   weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

   ID = WeaponType::Clan_Medium_Pulse_Laser;
   weapons[ID].Heat = 4;
   weapons[ID].MaxDamage = 7; // Maximum weapon damage
   weapons[ID].MaxRangeInMeters = 360; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 200;
   weapons[ID].AvailableInYear = 2609; // Year of field/open market availability
   weapons[ID].CBills = (int) (clanFactor * 60000);
   setWeaponNames (ID, "MPLaser", "Medium Pulse Laser");
   weapons[ID].MW2_31st_ID = 2600;
   weapons[ID].MW2_ID = 2600;
   weapons[ID].fireDuration = 3.0;
   weapons[ID].coolDown = 3.0;
   weapons[ID].geometry = laserGeometry;
   weapons[ID].shotColor = green;
   weapons[ID].soundWhenFired = "MECPLASR.SFL";
   weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

   ID = WeaponType::Clan_Small_Pulse_Laser;
   weapons[ID].Heat = 2;
   weapons[ID].MaxDamage = 3; // Maximum weapon damage
   weapons[ID].MaxRangeInMeters = 180; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 100;
   weapons[ID].AvailableInYear = 2609; // Year of field/open market availability
   weapons[ID].CBills = (int) (clanFactor * 16000);
   setWeaponNames (ID, "SPLaser", "Small Pulse Laser");
   weapons[ID].MW2_31st_ID = 2700;
   weapons[ID].MW2_ID = 2700;
   weapons[ID].fireDuration = 3.0;
   weapons[ID].coolDown = 3.0;
   weapons[ID].geometry = laserGeometry;
   weapons[ID].shotColor = red;
   weapons[ID].soundWhenFired = "MECPLASR.SFL";
   weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

   ID = WeaponType::Clan_Micro_Pulse_Laser;
   weapons[ID].Heat = 1;
   weapons[ID].MaxDamage = 3; // Maximum weapon damage
   weapons[ID].MaxRangeInMeters = 90; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 50;
   weapons[ID].AvailableInYear = 2609; // Year of field/open market availability
   weapons[ID].CBills = (int) (clanFactor * 12500);
   setWeaponNames (ID, "miPLaser", "Micro Pulse Laser");
   weapons[ID].fireDuration = 3.0;
   weapons[ID].coolDown = 3.0;
   weapons[ID].geometry = laserGeometry;
   weapons[ID].shotColor = red;
   weapons[ID].soundWhenFired = "MECPLASR.SFL";
   weapons[ID].flags |= MWweaponFlag_WorksUnderwater;

   for (int ID = Clan_Ballistic_Weapons; ID < Clan_Missile_Weapons; ID++) {
         weapons[ID].MaxRangeInMeters = 270; // The maximum range for the weapon does minimum damage
   }

   ID = WeaponType::Clan_Anti_Missile_System;
   weapons[ID].Heat = 1;
   weapons[ID].MaxRangeInMeters = 90; // The maximum range where the weapon does damage
   weapons[ID].TonnageTimes100 = 50;
   weapons[ID].AvailableInYear = 2617; // Year of field/open market availability
   weapons[ID].CBills = 100000;
   //weapons[ID].AmmoTypes[0] = Clan_Machine_Gun_Ammo; // Ammo that this weapon can use
   //weapons[ID].flags = MWWeaponFlagsStdWeapon;
   setWeaponNames (ID, "AMS", "Anti-Missile System");
   weapons[ID].MW2_ID = 2900;
   weapons[ID].MW2_31st_ID = 2900;
   weapons[ID].flags = MWWeaponFlag_MWCannotFire | MWWeaponFlag_IncludeInWeaponList;
   weapons[ID].geometry = laserGeometry;
   weapons[ID].shotColor = grey;
   weapons[ID].ammoUsedPerShot = 1;
   weapons[ID].category = WeaponCategory::bullet;
   weapons[ID].soundWhenFired = "MECMGUN1.SFL";

   ID = WeaponType::Clan_Anti_Missile_System_Ammo;
   setWeaponNames(ID, "A(AMS)", "Ammo (Anti-Missile System)");
   weapons[ID].TonnageTimes100 = 100;
   weapons[ID].MW2_ID = 12900;
   weapons[ID].MW2_31st_ID = 12900;
   setWeaponAmmoPair(Clan_Anti_Missile_System, Clan_Anti_Missile_System_Ammo);
   weapons[ID].ShotsPerTon = 24;
   weapons[ID].flags = MWWeaponFlagsStdAmmo;

   ID = WeaponType::Clan_Gauss;
   weapons[ID].Heat = 1;
   weapons[ID].MaxRangeInMeters = 660; // At maximum range, the weapon should do less damage
   weapons[ID].TonnageTimes100 = 1200;
   weapons[ID].Criticals = 6;
   weapons[ID].AvailableInYear = 2590; // Year of field/open market availability
   weapons[ID].CBills = 300000;
   //weapons[ID].AmmoTypes[0] = Clan_Gauss_Ammo; // Ammo that this weapon can use
   setWeaponNames (ID, "Gauss", "Gauss Rifle");
   weapons[ID].ammoUsedPerShot = 1;
   weapons[ID].MW2_31st_ID = 1100;
   weapons[ID].MW2_ID = 1100;
   weapons[ID].geometry = gaussCannonGeometry;
   weapons[ID].weaponScale = weapons[ID].Criticals * 0.125;
   weapons[ID].shotColor = grey;
   weapons[ID].soundWhenFired = "MECGAUNR.SFL";
   weapons[ID].MaxDamage = 15;
   weapons[ID].category = WeaponCategory::bullet;
   weapons[ID].metersPerSecond = 3000;

   ID = WeaponType::Clan_Gauss_Ammo;
   weapons[ID].TonnageTimes100 = 100;
   weapons[ID].AvailableInYear = 2590;
   weapons[ID].CBills = 20000;
   setWeaponNames (ID, "A(Gauss)", "Ammo (Gauss)");
   weapons[ID].MW2_31st_ID = 11100;
   weapons[ID].MW2_ID = 11100;
   weapons[ID].ShotsPerTon = 8;
   weapons[ID].flags = MWWeaponFlagsStdAmmo;
   setWeaponAmmoPair(Clan_Gauss, Clan_Gauss_Ammo);

   // Clan LB-X
   for (int i = 0; i < 4; i++) {
      int ID = ((int)Clan_LB_20_X_AC)+i;
      weapons[ID].Heat = 1;
      weapons[ID].Criticals = 6-i;
      setWeaponAmmoPair(ID, WeaponType::Clan_LB_X_Ammo);
      setWeaponAmmoPair(ID, WeaponType::Clan_Autocannon_Ammo);
      shortName = "LB";
      shortName += ACnumStr[i];
      shortName += "X AC";
      longName = "LB ";
      longName += ACnumStr[i];
      longName += "-X Autocannon";
      setWeaponNames(ID, shortName, longName);
      int MW2_ID = 1500-100*i;
      weapons[ID].MW2_31st_ID = MW2_ID;
      weapons[ID].MW2_ID = MW2_ID;
      weapons[ID].AvailableInYear = 2595; // Year of field/open market availability
      weapons[ID].Heat = 1;
      weapons[ID].Criticals = 6-i;
      weapons[ID].fireDuration = 4;
      weapons[ID].coolDown = 6;
      weapons[ID].ammoUsedPerShot = ACnums[i];
	  weapons[ID].geometry = autocannonGeometry;
	  weapons[ID].weaponScale = 0.125 * weapons[ID].Criticals;
	  weapons[ID].shotColor = grey;
	  weapons[ID].soundWhenFired = "MECACAN1.SFL";
	  weapons[ID].category = WeaponCategory::bullet;
   }

   ID = WeaponType::Clan_LB_2_X_AC;
   weapons[ID].MaxRangeInMeters = 900; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 500;
   weapons[ID].CBills = 150000;
   weapons[ID].MaxRangeInMeters = 900;
   weapons[ID].MaxDamage = 2;

   ID = WeaponType::Clan_LB_5_X_AC;
   weapons[ID].MaxRangeInMeters = 720; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 700;
   weapons[ID].CBills = 250000;
   weapons[ID].MaxDamage = 5;

   ID = WeaponType::Clan_LB_10_X_AC;
   weapons[ID].Heat = 2;
   weapons[ID].MaxRangeInMeters = 540; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 1000;
   weapons[ID].CBills = 400000;
   weapons[ID].MaxDamage = 10;

   ID = WeaponType::Clan_LB_20_X_AC;
   weapons[ID].Heat = 6;
   weapons[ID].MaxRangeInMeters = 360; // The maximum range for the weapon does minimum damage
   weapons[ID].TonnageTimes100 = 1200;
   weapons[ID].Criticals = 9;
   weapons[ID].CBills = 600000;
   weapons[ID].weaponScale = 0.125 * weapons[ID].Criticals;
   weapons[ID].MaxDamage = 20;

   for (int i = 0; i < 4; i++) {
      int ID = ((int) WeaponType::Clan_UAC_20) + i;
      weapons[ID].Heat = 1;
      weapons[ID].MaxRangeInMeters = 810; // The maximum range for the weapon does minimum damage
      weapons[ID].MW2_31st_ID = 1900-100*i;
      weapons[ID].MW2_ID = weapons[ID].MW2_31st_ID;
      shortName = "UAC/";
      shortName += ACnumStr[i];
      longName = "Ultra Autocannon/";
      longName += ACnumStr[i];
      setWeaponNames(ID, shortName, longName);
      setWeaponAmmoPair(ID, Clan_Autocannon_Ammo);
      weapons[ID].fireDuration = 2;
      weapons[ID].coolDown = 3;
      weapons[ID].ammoUsedPerShot = ACnums[i];
	  weapons[ID].geometry = autocannonGeometry;
 	  weapons[ID].weaponScale = 0.125 * weapons[ID].Criticals;
	  weapons[ID].shotColor = grey;
	  weapons[ID].soundWhenFired = "MECACAN1.SFL";
	  weapons[ID].category = WeaponCategory::bullet;
   }

   ID = WeaponType::Clan_UAC_2;
   weapons[ID].TonnageTimes100 = 500;
   weapons[ID].CBills = 120000;
   weapons[ID].Criticals = 2;
   weapons[ID].MaxRangeInMeters = 810;
   weapons[ID].ammoUsedPerShot = 2;
   weapons[ID].weaponScale = 0.125 * weapons[ID].Criticals;
   weapons[ID].MaxDamage = 2;

   ID = WeaponType::Clan_UAC_5;
   weapons[ID].TonnageTimes100 = 700;
   weapons[ID].CBills = 200000;
   weapons[ID].Criticals = 3;
   weapons[ID].MaxRangeInMeters = 630;
   weapons[ID].ammoUsedPerShot = 5;
   weapons[ID].weaponScale = 0.125 *  weapons[ID].Criticals;
   weapons[ID].MaxDamage = 5;

   ID = WeaponType::Clan_UAC_10;
   weapons[ID].Heat = 3;
   weapons[ID].TonnageTimes100 = 1000;
   weapons[ID].CBills = 320000;
   weapons[ID].Criticals = 4;
   weapons[ID].MaxRangeInMeters = 540;
   weapons[ID].ammoUsedPerShot = 10;
   weapons[ID].weaponScale = 0.125 *  weapons[ID].Criticals;
   weapons[ID].MaxDamage = 10;

   ID = WeaponType::Clan_UAC_20;
   weapons[ID].Heat = 7;
   weapons[ID].TonnageTimes100 = 1200;
   weapons[ID].CBills = 480000;
   weapons[ID].Criticals = 8;
   weapons[ID].MaxRangeInMeters = 360;
   weapons[ID].ammoUsedPerShot = 20;
   weapons[ID].weaponScale = 0.125 *  weapons[ID].Criticals;
   weapons[ID].MaxDamage = 20;

	ID = WeaponType::Clan_Light_Machine_Gun;
	weapons[ID].MaxDamage = 1; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 180; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 50;
	weapons[ID].Criticals = 1;
	weapons[ID].AvailableInYear = 1900; // Year of field/open market availability
	weapons[ID].CBills = 5000;
	setWeaponNames (ID, "LMG", "Light Machine Gun");
	weapons[ID].MW2_ID = 23300; // Not in MW2
	weapons[ID].MW2_31st_ID = weapons[ID].MW2_ID;
	weapons[ID].ammoUsedPerShot = 10;
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = grey;
	weapons[ID].category = WeaponCategory::bullet;
	weapons[ID].soundWhenFired = "MECMGUN1.SFL";
	setWeaponAmmoPair (WeaponType::IS2_Light_Machine_Gun, WeaponType::IS1_Machine_Gun_Ammo);

	ID = WeaponType::Clan_Machine_Gun;
	weapons[ID].MaxDamage = 2;
	weapons[ID].MaxRangeInMeters = 90; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 25;
	weapons[ID].CBills = 5000;
	setWeaponNames (ID, "MG", "Machine Gun");
	weapons[ID].MW2_31st_ID = 1000;
	weapons[ID].MW2_ID = 1000;
	weapons[ID].Criticals = 1;
	weapons[ID].ammoUsedPerShot = 10;
	setWeaponAmmoPair(Clan_Machine_Gun, Clan_Machine_Gun_Ammo);
	weapons[ID].geometry = laserGeometry;
	weapons[ID].category = WeaponCategory::bullet;
	weapons[ID].soundWhenFired = "MECMGUN1.SFL";

	ID = WeaponType::Clan_Heavy_Machine_Gun;
	weapons[ID].MaxDamage = 3; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 60; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 50;
	weapons[ID].Criticals = 1;
	weapons[ID].AvailableInYear = 1900; // Year of field/open market availability
	weapons[ID].CBills = 7500;
	setWeaponNames (ID, "HMG", "Heavy Machine Gun");
	weapons[ID].MW2_ID = 23400; // Not in MW2
	weapons[ID].MW2_31st_ID = weapons[ID].MW2_ID;
	weapons[ID].ammoUsedPerShot = 10;
	weapons[ID].geometry = laserGeometry;
	weapons[ID].shotColor = grey;
	weapons[ID].category = WeaponCategory::bullet;
	weapons[ID].soundWhenFired = "MECMGUN1.SFL";

	ID = WeaponType::Clan_Heavy_Machine_Gun_Ammo;
	weapons[ID].MaxDamage = 3; // Maximum weapon damage
	weapons[ID].MaxRangeInMeters = 60; // The maximum range for the weapon does minimum damage
	weapons[ID].TonnageTimes100 = 100;
	weapons[ID].ShotsPerTon = 1000; // If positive, this record describes ammo
	weapons[ID].AvailableInYear = 1900; // Year of field/open market availability
	weapons[ID].CBills = 1000;
	weapons[ID].flags = MWWeaponFlagsStdAmmo;
	setWeaponNames (ID, "A(HMG)", "Ammo (Heavy Machine Gun)");
	weapons[ID].MW2_ID = 23500; // Not In MW2
	weapons[ID].MW2_31st_ID = weapons[ID].MW2_ID;
	setWeaponAmmoPair (WeaponType::Clan_Heavy_Machine_Gun, WeaponType::Clan_Heavy_Machine_Gun_Ammo);
	weapons[ID].shotColor = grey;
	weapons[ID].category = WeaponCategory::bullet;

   for (int ID = WeaponType::Clan_Autocannon_Ammo; ID <= WeaponType::Clan_UAC_2_Ammo; ++ID) {
      weapons[ID].MaxDamage = 1;
      weapons[ID].TonnageTimes100 = 100;
      //weapons[ID].Criticals = 1;
      weapons[ID].CBills = 20000;
      weapons[ID].MW2_31st_ID = 11700;
      weapons[ID].MW2_ID = 11700;
      weapons[ID].flags = MWWeaponFlagsStdAmmo;
      weapons[ID].ShotsPerTon = 100;
   }

   // MW2 needs ammo types for each weapon type ...
   for (int i = 0; i < 4; ++i) {
      setWeaponAmmoPair(WeaponType::Clan_UAC_20+i, WeaponType::Clan_UAC_20_Ammo+i);
      weapons[Clan_UAC_20_Ammo+i].MW2_31st_ID = 11900-100*i;
      weapons[Clan_UAC_20_Ammo+i].MW2_ID = 11900-100*i;
   }

   setWeaponNames(WeaponType::Clan_Autocannon_Ammo, "Ammo(AC)", "Ammo (Autocannon)");
   setWeaponNames(WeaponType::Clan_UAC_2_Ammo, "A(UAC2)", "Ammo (Ultra Autocannon 2)");
   setWeaponNames(WeaponType::Clan_UAC_5_Ammo, "A(UAC5)", "Ammo (Ultra Autocannon 5)");
   setWeaponNames(WeaponType::Clan_UAC_10_Ammo, "A(UAC10)", "Ammo (Ultra Autocannon 10)");
   setWeaponNames(WeaponType::Clan_UAC_20_Ammo, "A(UAC20)", "Ammo (Ultra Autocannon 20)");

   for (int ID = WeaponType::Clan_LB_X_Ammo; ID <= WeaponType::Clan_LB_2_X_AC_Ammo; ++ID) {
      weapons[ID].MaxDamage = 1;
      weapons[ID].TonnageTimes100 = 100;
      weapons[ID].CBills = 20000;
      weapons[ID].MW2_ID = 11300;
      weapons[ID].flags = MWWeaponFlag_Ammo | MWWeaponFlag_CountedInMEK;
      weapons[ID].ShotsPerTon = 100;
   }

   // MW2 needs ammo types for each weapon type ...
   for (int i = 0; i < 4; ++i) {
      setWeaponAmmoPair(WeaponType::Clan_LB_20_X_AC+i, WeaponType::Clan_LB_20_X_AC_Ammo+i);
      weapons[Clan_LB_20_X_AC_Ammo+i].MW2_31st_ID = 11500-100*i;
   }

   setWeaponNames(WeaponType::Clan_LB_X_Ammo, "A(LBX AC)", "Ammo (LB-X Autocannon)");
   setWeaponNames(WeaponType::Clan_LB_20_X_AC_Ammo, "A(LB 20X)", "Ammo (LB 20-X Autocannon)");
   setWeaponNames(WeaponType::Clan_LB_10_X_AC_Ammo, "A(LB 10X)", "Ammo (LB 10-X Autocannon)");
   setWeaponNames(WeaponType::Clan_LB_5_X_AC_Ammo, "A(LB 5X)", "Ammo (LB 5-X Autocannon)");
   setWeaponNames(WeaponType::Clan_LB_2_X_AC_Ammo, "A(LB 2X)", "Ammo (LB 2-X Autocannon)");

   ID = WeaponType::Clan_Machine_Gun_Ammo;
   weapons[ID].MaxDamage = 1;
   weapons[ID].TonnageTimes100 = 100;
   //weapons[ID].Criticals = 1;
   weapons[ID].CBills = 1000;
   setWeaponNames (ID, "A(MG)", "Ammo (Machine Gun)");
   weapons[ID].MW2_31st_ID = 11000; // Not confirmed?
   weapons[ID].MW2_ID = 11000;
   weapons[ID].flags = MWWeaponFlagsStdAmmo;
   weapons[ID].ShotsPerTon = 2000;

	// Clan ATMs follow simple formulas
	for (int i = 0; i < 4; i++) {
		int ID = i+((int)WeaponType::Clan_ATM_3);
		weapons[ID].Heat = 2*(i+1);
		weapons[ID].Criticals = i+2;
		BGCPString name = BGCPString("ATM ") + BGCPString::fromInt(3*(i+1));
		setWeaponNames (ID, name, name);
		setWeaponAmmoPair(ID, WeaponType::Clan_ATM_Std_Ammo);
		setWeaponAmmoPair(ID, WeaponType::Clan_ATM_ER_Ammo);
		setWeaponAmmoPair(ID, WeaponType::Clan_ATM_HE_Ammo);
		weapons[ID].MW2_31st_ID = 20500 + 100 * i;
		weapons[ID].MW2_ID = weapons[ID].MW2_31st_ID;
		weapons[ID].ammoUsedPerShot = 3*(i+1);
		weapons[ID].geometry = missileTubeGeometry;
		weapons[ID].xreps = 3;
		weapons[ID].yreps = i+1;
		weapons[ID].category = WeaponCategory::missile;
		weapons[ID].metersPerSecond = 200;
		weapons[ID].MaxDamage = 6 * (i+i);
		weapons[ID].defyGravityDuration = 2.25;
	}
	weapons[WeaponType::Clan_ATM_3].TonnageTimes100 = 150;
	weapons[WeaponType::Clan_ATM_6].TonnageTimes100 = 350;
	weapons[WeaponType::Clan_ATM_9].TonnageTimes100 = 500;
	weapons[WeaponType::Clan_ATM_12].TonnageTimes100 = 700;

	setWeaponNames(WeaponType::Clan_ATM_Std_Ammo, "A(ATM)", "Ammo (ATM Standard)");
	weapons[Clan_ATM_Std_Ammo].TonnageTimes100 = 100;
	weapons[Clan_ATM_Std_Ammo].flags = MWWeaponFlagsStdAmmo;
	weapons[Clan_ATM_Std_Ammo].MW2_31st_ID = 20900; // Not in MW2
	weapons[ID].MW2_31st_ID = weapons[ID].MW2_ID;
	weapons[Clan_ATM_Std_Ammo].MW2_ID = weapons[Clan_ATM_Std_Ammo].MW2_31st_ID;
	weapons[Clan_ATM_Std_Ammo].ShotsPerTon = 60;

	setWeaponNames(WeaponType::Clan_ATM_ER_Ammo, "A(ATM ER)", "Ammo (ATM Extended Range)");
	weapons[Clan_ATM_ER_Ammo].TonnageTimes100 = 100;
	weapons[Clan_ATM_ER_Ammo].flags = MWWeaponFlagsStdAmmo;
	weapons[Clan_ATM_ER_Ammo].MW2_31st_ID = 21000; // Not in MW2
	weapons[ID].MW2_31st_ID = weapons[ID].MW2_ID;
	weapons[Clan_ATM_ER_Ammo].MW2_ID = weapons[Clan_ATM_ER_Ammo].MW2_31st_ID;
	weapons[Clan_ATM_ER_Ammo].ShotsPerTon = 60;

	setWeaponNames(WeaponType::Clan_ATM_HE_Ammo, "A(ATM HE)", "Ammo (ATM High-Explosive)");
	weapons[Clan_ATM_HE_Ammo].TonnageTimes100 = 100;
	weapons[Clan_ATM_HE_Ammo].flags = MWWeaponFlagsStdAmmo;
	weapons[Clan_ATM_HE_Ammo].MW2_31st_ID = 21100; // Not in MW2
	weapons[ID].MW2_31st_ID = weapons[ID].MW2_ID;
	weapons[Clan_ATM_HE_Ammo].MW2_ID = weapons[Clan_ATM_HE_Ammo].MW2_31st_ID;
	weapons[Clan_ATM_HE_Ammo].ShotsPerTon = 60;

	// Clan LRM
	for (int i = 0; i < 4; i++) {
		int ID = ((int)WeaponType::Clan_LRM_5)+i;
		//weapons[ID].AmmoTypes[0] = Clan_LRM_Ammo;
		//weapons[ID].Criticals = 1;
		weapons[ID].MW2_ID = 100*(3-i);
		weapons[ID].MW2_31st_ID = weapons[ID].MW2_ID;
		weapons[ID].CBills = weapons[WeaponType::IS1_LRM_5+i].CBills;
		setWeaponNames (ID, LRMnames[i]);
		setWeaponAmmoPair(ID, WeaponType::Clan_LRM_Ammo);
		setWeaponAmmoPair(ID, WeaponType::Clan_LRM_5_Ammo+i);
		weapons[ID].ammoUsedPerShot = 5*(i+1);
		weapons[ID].geometry = missileTubeGeometry;
		weapons[ID].xreps = 5;
		weapons[ID].yreps = i+1;
		weapons[ID].soundWhenFired = "MECBBAAT.SFL";
		weapons[ID].category = WeaponCategory::missile;
		weapons[ID].metersPerSecond = 200;
		weapons[ID].MaxDamage = 5 * (i+i);
		weapons[ID].defyGravityDuration = 3.15;
		weapons[ID].MaxRangeInMeters = 630; // At that range, missiles run out of fuel and start falling
	}

   ID = WeaponType::Clan_LRM_5;
   weapons[ID].Heat = 2;
   weapons[ID].TonnageTimes100 = 100;

   ID = WeaponType::Clan_LRM_10;
   weapons[ID].Heat = 4;
   weapons[ID].TonnageTimes100 = 250;

   ID = WeaponType::Clan_LRM_15;
   weapons[ID].Heat = 5;
   weapons[ID].TonnageTimes100 = 350;
   weapons[ID].Criticals = 2;

   ID = WeaponType::Clan_LRM_20;
   weapons[ID].Heat = 6;
   weapons[ID].TonnageTimes100 = 500;
   weapons[ID].Criticals = 4;

   ID = WeaponType::Clan_NARC_Missile_Beacon;
   //weapons[ID].Heat = 0;
   weapons[ID].TonnageTimes100 = 200;
   //weapons[ID].Criticals = 1;
   setWeaponNames (ID, "NARC");
   weapons[ID].MW2_ID = 2800;
   weapons[ID].MW2_31st_ID = 2800;
   weapons[ID].ammoUsedPerShot = 1;

   ID = WeaponType::Clan_NARC_Missile_Beacon_Ammo;
   setWeaponNames (ID, "A(NARC)", "Ammo (NARC)");
   weapons[ID].TonnageTimes100 = 100;
   weapons[ID].flags = MWWeaponFlagsStdAmmo;
   weapons[ID].MW2_31st_ID = 12800;
   weapons[ID].MW2_ID = 12800;
   setWeaponAmmoPair(Clan_NARC_Missile_Beacon, Clan_NARC_Missile_Beacon_Ammo);

   // Clan SRMs follow simple formulas
   for (int i = 0; i < 3; i++) {
      int ID = i+((int)WeaponType::Clan_SRM_2);
      weapons[ID].Heat = i+2;
      //weapons[ID].Criticals = 1;
      weapons[ID].TonnageTimes100 = (i+1)*50;
      weapons[ID].CBills = weapons[WeaponType::IS1_SRM_2+i].CBills;
      //weapons[ID].AmmoTypes[0] = Clan_SRM_Ammo;
      //weapons[ID].AmmoTypes[1] = Clan_SRM_Ammo_Inferno;
      setWeaponNames (ID, SRMnames[i]);
      weapons[ID].MW2_31st_ID = (6-i)*100; // 600: SRM-2, 500: SRM-4, 400: SRM-6
      weapons[ID].MW2_ID = (6-i)*100;
	  weapons[ID].MaxRangeInMeters = 270; // At that range, missiles run out of fuel and start falling
      weapons[ID].ammoUsedPerShot = 2*(i+1);
      setWeaponAmmoPair(ID, WeaponType::Clan_SRM_Ammo);
      setWeaponAmmoPair(ID, WeaponType::Clan_SRM_Ammo_Inferno);
      setWeaponAmmoPair(ID, WeaponType::Clan_SRM_2_Ammo+i);
	  weapons[ID].geometry = missileTubeGeometry;
      weapons[ID].soundWhenFired = "MECBBAAT.SFL";
	  weapons[ID].metersPerSecond = 200;
	  if (i == 2) {
		  // SRM-6
		  weapons[ID].xreps = 3;
		  weapons[ID].yreps = 2;
	  } else {
		  // SRM-2 and SRM-4
		  weapons[ID].xreps = 2*(i+1);
		  weapons[ID].yreps = 1;
	  }
	  weapons[ID].MaxDamage = 4 * (i+i);
	  weapons[ID].category = WeaponCategory::missile;
	  weapons[ID].defyGravityDuration = 0.45;
   }

   // SRM2 Inferno is a special weapon in GBL, MW2:Mercs
   // Outside of MW2, use an SRM launcher with Inferno ammunition
   ID = WeaponType::Clan_SRM_2_Inferno;
   weapons[ID].Heat = 2;
   weapons[ID].TonnageTimes100 = 50;
   weapons[ID].CBills = weapons[IS1_SRM_2].CBills;
   setWeaponNames (ID, "SRM2Inf", "SRM2 Inferno");
   weapons[ID].MW2_31st_ID = 3100;
   weapons[ID].MW2_ID = 3100;
   setWeaponAmmoPair(ID, WeaponType::Clan_SRM_Ammo_Inferno);
   weapons[ID].MaxRangeInMeters = 270;
   weapons[ID].geometry = missileTubeGeometry;
   weapons[ID].xreps = 2;
   weapons[ID].soundWhenFired = "MECBBAAT.SFL";
   weapons[ID].category = WeaponCategory::missile;
   weapons[ID].metersPerSecond = 200;
   weapons[ID].defyGravityDuration = 0.45;

   // Clan streak SRMs follow simple formulas
   for (int i = 0; i < 3; i++) {
      int ID = i+((int)Clan_Streak_SRM_2);
      weapons[ID].Heat = i+2;
      //weapons[ID].Criticals = 1;
      weapons[ID].TonnageTimes100 = (i+1)*100;
      weapons[ID].CBills = weapons[IS2_Streak_SRM_2+i].CBills;
      weapons[ID].AmmoTypes[0] = WeaponType::Clan_SSRM_Ammo;
      weapons[ID].AmmoTypes[1] = WeaponType::Clan_SRM_Ammo_Inferno;
      shortName = 'S';
      shortName += SRMnames[i];
      longName = "Streak ";
      longName += SRMnames[i];
      weapons[ID].MaxRangeInMeters = 360;
      setWeaponNames(ID, shortName, longName);
      weapons[ID].MW2_31st_ID = (9-i)*100;
      weapons[ID].MW2_ID = (9-i)*100;
      setWeaponAmmoPair(ID, WeaponType::Clan_SSRM_Ammo);
      //setWeaponAmmoPair(ID, Clan_SSRM_Ammo_Inferno);
      setWeaponAmmoPair(ID, WeaponType::Clan_Streak_SRM_2_Ammo+i);
      weapons[ID].ammoUsedPerShot = 2*(i+1);
	  weapons[ID].geometry = missileTubeGeometry;
	  weapons[ID].soundWhenFired = "MECBBAAT.SFL";
	  weapons[ID].category = WeaponCategory::missile;
	  if (i == 2) {
		  // SRM-6
		  weapons[ID].xreps = 3;
		  weapons[ID].yreps = 2;
	  } else {
		  // SRM-2 and SRM-4
		  weapons[ID].xreps = 2*(i+1);
		  weapons[ID].yreps = 1;
	  }
	  weapons[ID].metersPerSecond = 200;
	  weapons[ID].MaxDamage = 4 * (i+i);
	  weapons[ID].defyGravityDuration = 0.6;
   }
   weapons[WeaponType::Clan_Streak_SRM_6].Criticals = 2;

   setWeaponNames (WeaponType::Clan_SRM_Ammo,  "A(SRM)", "Ammo (SRM)");
   setWeaponNames (WeaponType::Clan_SRM_2_Ammo, "A(SRM 2)", "Ammo (SRM 2)");
   setWeaponNames (WeaponType::Clan_SRM_4_Ammo, "A(SRM 4)", "Ammo (SRM 4)");
   setWeaponNames (WeaponType::Clan_SRM_6_Ammo, "A(SRM 6)", "Ammo (SRM 6)");

   for (int ID = Clan_SRM_Ammo; ID < Clan_LRM_Ammo; ++ID) {
      weapons[ID].TonnageTimes100 = 100;
      weapons[ID].MaxDamage = 2;
      weapons[ID].MaxDamageRange = 270;
      weapons[ID].ShotsPerTon = 100;
      weapons[ID].flags = MWWeaponFlagsStdAmmo;
   }

   for (int i = 0; i < 3; ++i) {
      weapons[Clan_SRM_2_Ammo+i].MW2_31st_ID = 10600-100*i;
      weapons[Clan_SRM_2_Ammo+i].MW2_ID = 10600-100*i;
   }

   for (int ID = WeaponType::Clan_SSRM_Ammo; ID <= WeaponType::Clan_Streak_SRM_6_Ammo; ++ID) {
      weapons[ID].TonnageTimes100 = 100;
      weapons[ID].MaxDamage = 2;
      weapons[ID].MaxDamageRange = 360;
      weapons[ID].ShotsPerTon = 100;
      weapons[ID].flags = MWWeaponFlagsStdAmmo;
   }

   setWeaponNames(WeaponType::Clan_SSRM_Ammo, "A(SSRM)", "Ammo (Streak SRM)");
   setWeaponNames(WeaponType::Clan_Streak_SRM_2_Ammo, "A(SSRM2)", "Ammo (Streak SRM 2)");
   setWeaponNames(WeaponType::Clan_Streak_SRM_4_Ammo, "A(SSRM4)", "Ammo (Streak SRM 4)");
   setWeaponNames(WeaponType::Clan_Streak_SRM_6_Ammo, "A(SSRM6)", "Ammo (Streak SRM 6)");

   for (int i = 0; i < 3; ++i) {
      weapons[Clan_Streak_SRM_2_Ammo+i].MW2_31st_ID = 10900-100*i;
      weapons[Clan_Streak_SRM_2_Ammo+i].MW2_ID = 10900-100*i;
   }

   // Streak SRM2 Inferno is a special weapon in GBL, MW2:Mercs
   // Outside of MW2, use a Streak SRM2 launcher with Inferno ammunition
   ID = WeaponType::Clan_Streak_SRM_2_Inferno;
   weapons[ID].Heat = 2;
   weapons[ID].TonnageTimes100 = 100;
   weapons[ID].CBills = weapons[IS2_Streak_SRM_2].CBills;
   setWeaponNames (ID, "SSRM2Inf", "Streak SRM2 Inferno");
   weapons[ID].MW2_31st_ID = 3300;
   weapons[ID].MW2_ID = 3300;
   setWeaponAmmoPair(ID, WeaponType::Clan_SSRM_Inferno_Ammo);
   weapons[ID].geometry = missileTubeGeometry;
   weapons[ID].xreps = 2;
   weapons[ID].category = WeaponCategory::missile;
   weapons[ID].metersPerSecond = 200;

   ID = WeaponType::Clan_SSRM_Inferno_Ammo;
   setWeaponNames(ID, "A(SSRM2I)", "Ammo (Streak SRM Inferno)");
   weapons[ID].TonnageTimes100 = 100;
   weapons[ID].CBills = WeaponType::Clan_SSRM_Inferno_Ammo;
   weapons[ID].ShotsPerTon = 50;
   weapons[ID].MW2_31st_ID = 13300;
   weapons[ID].MW2_ID = 13300;
   weapons[ID].flags = MWWeaponFlagsStdAmmo;

   setWeaponNames(WeaponType::Clan_LRM_Ammo, "Ammo(LRM)", "Ammo (LRM)");
   setWeaponNames(WeaponType::Clan_LRM_5_Ammo, "A(LRM 5)");
   setWeaponNames(WeaponType::Clan_LRM_10_Ammo, "A(LRM 10)");
   setWeaponNames(WeaponType::Clan_LRM_15_Ammo, "A(LRM 15)");
   setWeaponNames(WeaponType::Clan_LRM_20_Ammo, "A(LRM 20)");

   for (int ID = Clan_LRM_Ammo; ID <= Clan_LRM_20_Ammo; ++ID) {
      weapons[ID].TonnageTimes100 = 100;
      weapons[ID].MaxDamage = 1;
      weapons[ID].MaxDamageRange = 630;
      weapons[ID].ShotsPerTon = 120;
      weapons[ID].flags = MWWeaponFlagsStdAmmo;
   }

   for (size_t i = 0; i < 4; ++i) {
      int ID = WeaponType::Clan_LRM_5_Ammo+i;
      int mw2ID = 10300-100*i;
      weapons[ID].MW2_31st_ID = mw2ID;
      weapons[ID].MW2_ID = mw2ID;
   }

   ID = WeaponType::Clan_SRM_Ammo_Inferno;
   weapons[ID].TonnageTimes100 = 100;
   //weapons[ID].Criticals = 1;
   weapons[ID].ShotsPerTon = 5;
   weapons[ID].CBills = 10000;
   weapons[ID].ShotsPerTon = 100;
   setWeaponNames (ID, "A(SRM)I", "Ammo (SRM) Inferno");
   weapons[ID].MW2_ID = 13100;
   weapons[ID].MW2_31st_ID = 13100;
   weapons[ID].flags = MWWeaponFlagsStdAmmo;
   weapons[ID].soundWhenFired = "MECBBAAT.SFL";

   ID = WeaponType::Clan_Arrow_IV;
   weapons[ID].TonnageTimes100 = 1200;
   weapons[ID].Criticals = 12;
   weapons[ID].CBills = 450000;
   weapons[ID].MaxRangeInMeters = 6000;
   weapons[ID].AmmoTypes[0] = Clan_Arrow_IV_Ammo;
   setWeaponNames (ID, "Arrow IV");
   weapons[ID].MW2_ID = 3400;
   weapons[ID].MW2_31st_ID = 3400;
   weapons[ID].Heat = 10;
   weapons[ID].soundWhenFired = "MECBBAAT.SFL";
   weapons[ID].category = WeaponCategory::missile;
   weapons[ID].metersPerSecond = 200;

   ID = WeaponType::Clan_Arrow_IV_Ammo;
   weapons[ID].TonnageTimes100 = 100;
   weapons[ID].ShotsPerTon = 5;
   weapons[ID].CBills = 10000;
   weapons[ID].MaxRangeInMeters = 6000;
   setWeaponNames (ID, "A(Arr.IV)", "Ammo (Arrow IV)");
   weapons[ID].MW2_ID = 13400;
   weapons[ID].MW2_31st_ID = 13400;
   weapons[ID].flags = MWWeaponFlagsStdAmmo;
   weapons[ID].soundWhenFired = "MECBBAAT.SFL";
   setWeaponAmmoPair(Clan_Arrow_IV, Clan_Arrow_IV_Ammo);

   ID = WeaponType::Clan_Nuke;
   weapons[ID].MaxRangeInMeters = 6000;
   setWeaponNames (ID, "Nuke");
   weapons[ID].MW2_ID = 3000;
   weapons[ID].geometry = missileTubeGeometry;
   weapons[ID].soundWhenFired = "MECBBAAT.SFL";
   weapons[ID].category = WeaponCategory::missile;
   weapons[ID].metersPerSecond = 200;

   // Copy torpedos from SRM, LRM
   for (int i = 0; i < 9; i++) {
	   int ID = i + ((int)WeaponType::Clan_SRT_2);
	   int oldID = i+WeaponType::Clan_SRM_2;
	   copyWeapon (oldID, ID);
	   if (ID < WeaponType::Clan_LRT_5) {
		   setWeaponAmmoPair(ID, WeaponType::Clan_SRT_Ammo);
		   weapons[ID].defyGravityDuration = 2.7;
	   } else if (ID < WeaponType::Clan_SRT_Ammo) {
		   setWeaponAmmoPair(ID, Clan_LRT_Ammo);
		   weapons[ID].defyGravityDuration = 6.3;
	   }
	   weapons[ID].geometry = missileTubeGeometry;
	   weapons[ID].xreps = weapons[oldID].xreps;
	   weapons[ID].yreps = weapons[oldID].yreps;
	   weapons[ID].category = WeaponCategory::missile;
	   weapons[ID].metersPerSecond = 100;
	   weapons[ID].ammoUsedPerShot = weapons[oldID].ammoUsedPerShot;
	   weapons[ID].soundWhenFired = "TORLNCH1.SFL";
	   weapons[ID].flags = MWWeaponFlag_IncludeInWeaponList | MWWeaponFlag_CountedInMEK | MWweaponFlag_WorksUnderwater;
   }

   setWeaponNames (WeaponType::Clan_SRT_2, "SRT2");
   setWeaponNames (WeaponType::Clan_SRT_4, "SRT4");
   setWeaponNames (WeaponType::Clan_SRT_6, "SRT6");
   setWeaponNames (WeaponType::Clan_LRT_5, "LRT5");
   setWeaponNames (WeaponType::Clan_LRT_10, "LRT10");
   setWeaponNames (WeaponType::Clan_LRT_15, "LRT15");
   setWeaponNames (WeaponType::Clan_LRT_20, "LRT20");
   setWeaponNames (WeaponType::Clan_LRT_Ammo, "A(LRT)", "Ammo (LRT)");

   auto& SRT4Stats = weapons[WeaponType::Clan_SRT_4];
   weapons[WeaponType::Clan_SRT_4].MW2_ID = 3200;
   weapons[WeaponType::Clan_SRT_4].MW2_31st_ID = 3200;
   weapons[ID].category = WeaponCategory::missile;
   weapons[WeaponType::Clan_LRT_Ammo].flags = MWWeaponFlagsStdAmmo;

   ID = WeaponType::Clan_SRT_Ammo;
   weapons[ID].Heat = 0;
   weapons[ID].TonnageTimes100 = 100;
   weapons[ID].Criticals = 1;
   weapons[ID].CBills = WeaponType::Clan_SSRM_Inferno_Ammo;
   weapons[ID].ShotsPerTon = 50;
   setWeaponNames (ID, "A(SRT)", "Ammo (SRT)");
   weapons[ID].category = WeaponCategory::missile;
   weapons[ID].MaxDamage = 2;
   weapons[ID].MaxDamageRange = 270;
   weapons[ID].MW2_ID = 13200;
   weapons[ID].MW2_31st_ID = 13200;
   weapons[ID].metersPerSecond = 100;
   weapons[ID].defyGravityDuration = 2.7;
   weapons[ID].flags = MWWeaponFlagsStdAmmo;

   ID = WeaponType::Clan_Double_Heat_Sink;
   weapons[ID].Heat = -2;
   weapons[ID].TonnageTimes100 = 0; // Should not be included in weight calc
   weapons[ID].Criticals = 2;
   setWeaponNames (ID, "DHS", "Double Heat Sink");
   weapons[ID].MW2_31st_ID = 6000;
   weapons[ID].MW2_ID = 8000;
   weapons[ID].flags = MWWeaponFlag_CountedInMEK;

	// If there are not enough criticals/tonnage for all weapons on a mech,
	// the user should decide at mission start which weapons use the TC
	ID = WeaponType::Clan_Targeting_Computer;
	weapons[ID].TonnageTimes100 = 100;
	weapons[ID].Criticals = 1;
	setWeaponNames (ID, "TaCo", "Targeting Computer");
	weapons[ID].flags = 0;
	weapons[ID].MW2_31st_ID = 22100; // Not in MW2
	weapons[ID].MW2_ID = 22100; // Not in MW2

	ID = WeaponType::Clan_Ferro_Fibrous;
	//weapons[ID].Criticals = 1; // Actually 7, but 1 is better to handle in mech lab
	setWeaponNames (ID, "FF", "Ferro Fibrous Armor");
	weapons[ID].MW2_31st_ID = 9000;
	weapons[ID].MW2_ID = 9500;
	weapons[ID].flags = MWWeaponFlag_CountedInMEK;

	ID = WeaponType::Clan_Endo_Steel_Internals;
	//weapons[ID].Criticals = 1; // Actually 7, but 1 is better to handle in mech lab
	setWeaponNames (ID, "Endo", "Endo Steel Internals");
	weapons[ID].MW2_31st_ID = 8000;
	weapons[ID].MW2_ID = 9000;
	weapons[ID].flags = MWWeaponFlag_CountedInMEK;

	ID = WeaponType::Clan_MASC;
	//weapons[ID].Criticals = 1; // Depends on number of connected weapons
	//weapons[ID].TonnageTimes100 = 1; // Use BipedMech::calcMASCTonsAndSlots instead
	setWeaponNames (ID, "MASC");
	weapons[ID].MW2_31st_ID = 5000;
	weapons[ID].MW2_ID = 7000;
	weapons[ID].flags = 0;

	ID = IS1_Avionics;
	setWeaponNames (ID, "Avionics");
	weapons[ID].flags = MWWeaponFlag_MWCannotFire;
	weapons[ID].Criticals = 1;
	weapons[ID].TonnageTimes100 = 100;

	ID = IS1_Gear;
	setWeaponNames (ID, "Gear", "Landing Gear");
	weapons[ID].flags = MWWeaponFlag_MWCannotFire;
	weapons[ID].Criticals = 1;
	weapons[ID].TonnageTimes100 = 100;

	ID = IS1_Fuel;
	setWeaponNames (ID, "Fuel", "Fuel");
	weapons[ID].flags = MWWeaponFlag_MWCannotFire;
	weapons[ID].Criticals = 1;
	weapons[ID].TonnageTimes100 = 100;

	ID = CE_BOMB_100;
	setWeaponNames(ID, "Bomb", "Bomb");
	weapons[ID].Criticals = 1;
	weapons[ID].TonnageTimes100 = 100;
	weapons[ID].MW2_ID = 23900; // Not in MW2 ...
	weapons[ID].soundWhenFired = "MECEXPX2.SFL";
	weapons[ID].ShotsPerTon = 50;
	weapons[ID].MaxDamage = 100;
	weapons[ID].MaxRangeInMeters = 60;
}

////////////////////////////////////////////////////////////////////////////////
// Get statistics for a specific weapon

const MWEquipment* getWeaponStats (WeaponType weaponType)
{
	SET_SCOPE;
	if (weaponType > 0 && weaponType < WeaponsCount) {
		RETURN &weapons[weaponType];
	} else {
		RETURN NULL;
	}
}


double engineWeight[] = {0.0, 0.5, 0.5, 0.5, 0.5, // 0-20
                         0.5, 1.0, 1.0, 1.0, 1.0, // 25-45 
                         1.5, 1.5, 1.5, 2.0, 2.0, // 50-70
                         2.0, 2.5, 2.5, 3.0, 3.0, // 75-95
                         3.0, 3.5, 3.5, 4.0, 4.0, // 100-120
                         4.0, 4.5, 4.5, 5.0, 5.0, // 125-145
                         5.5, 5.5, 6.0, 6.0, 6.0, // 150-170
                         7.0, 7.0, 7.5, 7.5, 8.0, // 175-195
                         8.5, 8.5, 9.0, 9.5, 10.0, // 200-220
                         10.0, 10.5, 11.0, 11.5, 12.0, // 225-245
                         12.5, 13.0, 13.5, 14.0, 14.5, // 250-270
                         15.5, 16.0, 16.5, 17.5, 18.0, // 275-295
                         19.0, 19.5, 20.5, 21.5, 22.5, // 300-320
                         23.5, 24.5, 25.5, 27.0, 28.5, // 325-345
                         29.5, 31.5, 33.0, 34.5, 36.5, // 350-370
                         38.5, 41.0, 43.5, 46.0, 49.0, // 375-395
                         52.5, 56.5, 61.0, 66.5, 72.5, // 400-420
                         79.5, 87.5, 97.0, 107.5, 119.5, // 425-445
                         133.5, 150, 168.5, 190.0, 214.5, // 450-470
                         243.0, 275.5, 313.0, 356, 405.5, // 475-495
                         462.5}; // 500

double getEngineWeight (unsigned int engineRating, int EngineType)
{
	SET_SCOPE;
	if (engineRating <= 500) {
		if (EngineType == ENGINE_TYPE_STD) {
			RETURN engineWeight[engineRating/5];
		} else {
			RETURN engineWeight[engineRating/5] / 2;
		}
	} else {
		RETURN 500;
	}
}

////////////////////////////////////////////////////////////////////////////////

BGCPString getDosBoxPath ()
{
	SET_SCOPE;
	BGCPString result (getDataDir());
	result.addPathSep("DosBox");
	RETURN result;
}

////////////////////////////////////////////////////////////////////////////////

bool ammoCompatible(WeaponType weaponType, WeaponType ammoType)
{
	SET_SCOPE;
	const MWEquipment* weaponStats = getWeaponStats(weaponType);
	for (size_t i = 0; i < MaxAmmoTypes; ++i) {
		if (weaponStats->AmmoTypes[i] == ammoType) {
			RETURN true;
		}
	}

	RETURN false;
}

bool weaponUsesAmmo (const MWEquipment* w)
{
	if (w->AmmoTypes[0] != 0) {
		return false;
	} else {
		return true;
	}
}

void exportWeaponsListAsTSV(const PathChar* fn)
{
	BGCPString tsv;
	BGCPString tab("\t", CP_ASCII);
	BGCPString endl("\n", CP_ASCII);
	size_t ID;
	for (ID = 0; ID < WeaponsCount; ID++) {
		const MWEquipment& weapon = weapons[ID];
		tsv += BGCPString::fromInt(ID) + tab + BGCPString(weapon.longName, CP_ASCII) + tab + BGCPString(weapon.soundWhenFired, CP_ASCII) +
			endl;
	}
	tsv.saveToFile(fn, CP_ASCII);
}
