/*
* Dire_Storm
* Gunner DPS Calculator
* 11 July 2016
*/
#include <iostream>
#include <iomanip>
#include <string>
const int weapons = 33;
struct Gun{ // Gunner's weapon
std::string name; // Name of gun
int AT_min; // Minimum ATtack damage
int AT_max; // Maximum ATtack damage
int AGI_min; // Fastest rate of fire (minimum number of frames between shots)
int AGI_max; // Slowest rate of fire (maximum number of frames between shots)
int PC; // Projectile count
};
struct Character{ // Gunner character
int STR; // STRength stat in Gunner
int DEX; // DEXterity stat in Gunner
};
// Sets values to each Gun (Gun catalogue)
void setGuns(Gun Guns[]){
Guns[0].name = "Gun";
Guns[0].AT_min = 2;
Guns[0].AT_max = 6;
Guns[0].AGI_min = 20;
Guns[0].AGI_max = 30;
Guns[0].PC = 1;
Guns[1].name = "Handgun";
Guns[1].AT_min = 8;
Guns[1].AT_max = 12;
Guns[1].AGI_min = 20;
Guns[1].AGI_max = 30;
Guns[1].PC = 1;
Guns[2].name = "Submachine-gun";
Guns[2].AT_min = 4;
Guns[2].AT_max = 8;
Guns[2].AGI_min = 5;
Guns[2].AGI_max = 10;
Guns[2].PC = 1;
Guns[3].name = "Shotgun";
Guns[3].AT_min = 1;
Guns[3].AT_max = 20;
Guns[3].AGI_min = 50;
Guns[3].AGI_max = 60;
Guns[3].PC = 5;
Guns[4].name = "Rifle";
Guns[4].AT_min = 20;
Guns[4].AT_max = 40;
Guns[4].AGI_min = 50;
Guns[4].AGI_max = 60;
Guns[4].PC = 1;
/*Guns[5].name = "Grenade";
Guns[5].AT_min = 8;
Guns[5].AT_max = 12;
Guns[5].AGI_min = 70;
Guns[5].AGI_max = 80;
Guns[5].PC = 1;*/
/*Guns[6].name = "Laser Gun";
Guns[6].AT_min = 8;
Guns[6].AT_max = 12;
Guns[6].AGI_min = 20;
Guns[6].AGI_max = 30;
Guns[6].PC = 1;*/
/*Guns[7].name = "Bazooka";
Guns[7].AT_min = 40;
Guns[7].AT_max = 60;
Guns[7].AGI_min = 80;
Guns[7].AGI_max = 90;
Guns[7].PC = 1;*/
Guns[8].name = "Homing Laser";
Guns[8].AT_min = 8;
Guns[8].AT_max = 12;
Guns[8].AGI_min = 20;
Guns[8].AGI_max = 30;
Guns[8].PC = 2;
Guns[9].name = "Beretta";
Guns[9].AT_min = 24;
Guns[9].AT_max = 36;
Guns[9].AGI_min = 20;
Guns[9].AGI_max = 30;
Guns[9].PC = 1;
Guns[10].name = "Uzi";
Guns[10].AT_min = 12;
Guns[10].AT_max = 24;
Guns[10].AGI_min = 5;
Guns[10].AGI_max = 10;
Guns[10].PC = 1;
Guns[11].name = "Remington";
Guns[11].AT_min = 1;
Guns[11].AT_max = 40;
Guns[11].AGI_min = 50;
Guns[11].AGI_max = 60;
Guns[11].PC = 7;
Guns[12].name = "Sniper Rifle";
Guns[12].AT_min = 60;
Guns[12].AT_max = 80;
Guns[12].AGI_min = 50;
Guns[12].AGI_max = 60;
Guns[12].PC = 1;
/*Guns[13].name = "Grenade Launcher";
Guns[13].AT_min = 12;
Guns[13].AT_max = 24;
Guns[13].AGI_min = 70;
Guns[13].AGI_max = 80;
Guns[13].PC = 1;*/
/*Guns[14].name = "Laser Beam Gun";
Guns[14].AT_min = 16;
Guns[14].AT_max = 24;
Guns[14].AGI_min = 20;
Guns[14].AGI_max = 30;
Guns[14].PC = 1;*/
/*Guns[15].name = "Cannon";
Guns[15].AT_min = 80;
Guns[15].AT_max = 120;
Guns[15].AGI_min = 80;
Guns[15].AGI_max = 90;
Guns[15].PC = 1;*/
Guns[16].name = "Homing Laser Beam";
Guns[16].AT_min = 8;
Guns[16].AT_max = 12;
Guns[16].AGI_min = 20;
Guns[16].AGI_max = 30;
Guns[16].PC = 5;
Guns[17].name = "3-Round Burst";
Guns[17].AT_min = 24;
Guns[17].AT_max = 36;
Guns[17].AGI_min = 20;
Guns[17].AGI_max = 30;
Guns[17].PC = 3;
Guns[18].name = "Missile";
Guns[18].AT_min = 300;
Guns[18].AT_max = 500;
Guns[18].AGI_min = 160;
Guns[18].AGI_max = 180;
Guns[18].PC = 1;
Guns[19].name = "Mini Uzi";
Guns[19].AT_min = 12;
Guns[19].AT_max = 24;
Guns[19].AGI_min = 5;
Guns[19].AGI_max = 10;
Guns[19].PC = 2;
Guns[20].name = "Scattergun";
Guns[20].AT_min = 1;
Guns[20].AT_max = 80;
Guns[20].AGI_min = 50;
Guns[20].AGI_max = 60;
Guns[20].PC = 9;
Guns[21].name = "Hunting Gun";
Guns[21].AT_min = 140;
Guns[21].AT_max = 160;
Guns[21].AGI_min = 50;
Guns[21].AGI_max = 60;
Guns[21].PC = 1;
/*Guns[22].name = "M9 Grenade";
Guns[22].AT_min = 18;
Guns[22].AT_max = 48;
Guns[22].AGI_min = 20;
Guns[22].AGI_max = 30;
Guns[22].PC = 1;*/
/*Guns[23].name = "Power Laser Gun";
Guns[23].AT_min = 24;
Guns[23].AT_max = 36;
Guns[23].AGI_min = 20;
Guns[23].AGI_max = 30;
Guns[23].PC = 1;*/
/*Guns[24].name = "Napalm Bomb";
Guns[24].AT_min = 0;
Guns[24].AT_max = 0;
Guns[24].AGI_min = 160;
Guns[24].AGI_max = 180;
Guns[24].PC = 1;*/
/*Guns[25].name = "Wave Cannon";
Guns[25].AT_min = 120;
Guns[25].AT_max = 180;
Guns[25].AGI_min = 80;
Guns[25].AGI_max = 90;
Guns[25].PC = 1;*/
Guns[26].name = "Pierce Homing";
Guns[26].AT_min = 12;
Guns[26].AT_max = 16;
Guns[26].AGI_min = 20;
Guns[26].AGI_max = 30;
Guns[26].PC = 7;
Guns[27].name = "Magnum";
Guns[27].AT_min = 80;
Guns[27].AT_max = 120;
Guns[27].AGI_min = 20;
Guns[27].AGI_max = 30;
Guns[27].PC = 1;
Guns[28].name = "Micro Uzi";
Guns[28].AT_min = 16;
Guns[28].AT_max = 32;
Guns[28].AGI_min = 5;
Guns[28].AGI_max = 10;
Guns[28].PC = 3;
Guns[29].name = "Triple Shotgun";
Guns[29].AT_min = 1;
Guns[29].AT_max = 120;
Guns[29].AGI_min = 50;
Guns[29].AGI_max = 60;
Guns[29].PC = 15;
Guns[30].name = "Rail Gun";
Guns[30].AT_min = 300;
Guns[30].AT_max = 320;
Guns[30].AGI_min = 50;
Guns[30].AGI_max = 60;
Guns[30].PC = 1;
/*Guns[31].name = "Napalm Gun";
Guns[31].AT_min = 26;
Guns[31].AT_max = 96;
Guns[31].AGI_min = 70;
Guns[31].AGI_max = 80;
Guns[31].PC = 1;*/
/*Guns[32].name = "Slow Laser Gun";
Guns[32].AT_min = 32;
Guns[32].AT_max = 48;
Guns[32].AGI_min = 20;
Guns[32].AGI_max = 30;
Guns[32].PC = 1;*/
}
// Sets values to the Gunner character
void getStats(Character &Gunner1, int &LVL){
std::cout << "Enter characters' level: ";
std::cin >> LVL;
std::cout << LVL << std::endl;
Gunner1.STR = LVL - 1; // Evenly distribute STR and DEX
Gunner1.DEX = LVL - 1;
}
// Calculates DPS for each gun equipped on the gunner character
// How to get DPS: (AT + STR*2%) * (AGI / 2%*DEX)
void calcDPS(Character Gunner1, Gun Guns[], int LVL){
float DPS; // Damage per 60 frames
float DPS_max = 0; // Maximum DPS
int DPS_max_STR, DPS_max_DEX; // STR and DEX allocation for maximum DPS
int AGImin, AGImax; // Minimum and maximum ATtack damage
float AGI; // Average AGIlity (number of frames between shots)
int ATmin, ATmax; // Minimum and maximum ATtack damage
float AT; // Average ATtack damage
int range = (LVL - 1) * 2; // Range of stats to calculate (currently set to go from 0 to max)
for (int i = 0; i < weapons; i++){ // Runs for the number of weapons
if (Guns[i].name == "") continue; // Skip over commented out Guns
for (int k = 0; k <= range; k++){ // Loop for going through full range of STR/DEX
// Calculates average AT
ATmin = Guns[i].AT_min * (1 + 0.02 * (Gunner1.STR - (range/2 - k))); // Minimum AT calculation
ATmax = Guns[i].AT_max * (1 + 0.02 * (Gunner1.STR - (range/2 - k))); // Maximum AT calculation
AT = (ATmin + ATmax) / 2.; // Average AT calculation
// Calculates average AGI
AGImin = Guns[i].AGI_min / (1 + 0.02 * (Gunner1.DEX + range/2 - k)); // Minimum AGI calculation
if (AGImin < 5) AGImin = 5; // AGImin caps at 5
AGImax = Guns[i].AGI_max / (1 + 0.02 * (Gunner1.DEX + range/2 - k)); // Maximum AGI calculation
if (AGImax < 10) AGImax = 10; // AGImin caps at 10
AGI = (AGImin + AGImax) / 2.; // Average AGI calculation
// Calculates average DPS
DPS = AT * (60 / AGI);
// Calculates maximum DPS
if (DPS > DPS_max){
DPS_max = DPS; // Store maximum DPS
DPS_max_STR = Gunner1.STR - (range/2 - k); // Store STR parameter of maximum DPS
DPS_max_DEX = Gunner1.DEX + (range/2 - k); // Store DEX parameter of maximum DPS
}
}
// Outputs table of optimum STR/DEX allocation for maximum DPS of each Gun
std::cout << "DPS max for " << std::setw(17) << Guns[i].name << ": ";
std::cout << "STR " << std::setw(3) << DPS_max_STR; // STR
std::cout << " DEX " << std::setw(3) << DPS_max_DEX; // DEX
std::cout << " DPS = " << DPS_max * Guns[i].PC << std::endl; // DPS
DPS_max = DPS_max_STR = DPS_max_DEX = 0; // Reset maximums
}
std::cout << std::endl;
}
int main(){
Character Gunner1; // Gunner character
Gun Guns[weapons]; // Array of guns to calculate
int LVL; // Level of your team
setGuns(Guns);
getStats(Gunner1, LVL);
while (LVL){
calcDPS(Gunner1, Guns, LVL);
getStats(Gunner1, LVL);
}
return 0;
}