All pastes #2051644 Raw Edit

Someone

public text v1 · immutable
#2051644 ·published 2011-04-28 17:58 UTC
rendered paste body
/*

Adam Obenauf, ml22

4/17/11

project2.cpp

Text based rpg game based on the combat system of eve online

*/



//Preprocessor directives

#include<iostream>

#include<iomanip>

#include<cmath>

#include<string>

#include<fstream>

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

#include "prompts.h"

#include "attributecalc.h"

#include "display.h"

using namespace std;



//Structures

struct ship

{

	int size;

	int velocity;

	

	int damageBonusShield;

	int damageBonusArmor;

	int damage;

	

	int shieldHitPoints;	

	int armorHitPoints;	

	int hullHitPoints;

	

	int accuracyFalloff;

	int optimalRange;

	float trackingSpeed;

};



//Function prototypes



//CalculateShipAttributes

//Return type:  ship

//Parameters:  int specialization, int size, int primaryWeaponChoice, int ammoChoice

//This function calculates the attributes of a ship based on specialization/size/weapon choice/ammo choice and returns that ship

ship CalculateShipAttributes (int specialization, int size, int primaryWeaponChoice, int ammoChoice);



//WriteShipFile

//Return type:  void

//Parameters:  ship myShip, string shipName

//This function is passed a ship and the name of the file and writes the data to that file 

void WriteShipFile (ship myShip, string shipName);



//LoadShip

//Return type:  ship

//Parameters:  string shipName

//This function is passed the name of a file, it reads the data from that file and returns it as a ship

ship LoadShip(string shipName);



//DoesFileExist

//Return type:  bool

//Parameters:  string shipName

//This function is passed the name of a file and checks if the file exists, it returns true/false based on whether it exists or not

bool DoesFileExist(string shipName);



//RandomNum

//Return type:  int

//Parameters:  int lo, int hi

//This function is passed two numbers and returns a random number between them (inclusive)

int RandomNum(int lo, int hi);



//DisplayShipAttributes

//Return type:  void

//Parameters:  ship playerShip

//This function is passed a ship and displays the attributes of that ship

void DisplayShipAttributes(ship playerShip);



//IsHit

//Return type:  bool

//Parameters:  float accuracyFalloff, float optimalRange, float currentRange, float velocity, float trackingSpeed

//This function is passed a bunch of attributes and returns whether or not the person attacking hit the target

bool IsHit(float accuracyFalloff, float optimalRange, float currentRange, float velocity, float trackingSpeed);



//UpdateShipWeapon

//Return type:  void

//Parameters:  int size, int weaponChoice, int ammoChoice, ship myShip passed by reference

//This function updates some of a ships's attributes when a weapon change occurs

void UpdateShipWeapon(int size, int weaponChoice, int ammoChoice, ship& myShip);



//PercHealth

//Return type:  float

//Parameters:  int current, string shipName, int healthType

//This function calculates the percentage of health remaining by using current health, originalHealth (reads this from a file), and health type

float PercHealth (int current, string shipName, int healthType);



//PlayerAttacksEnemy

//Return type:  void

//Parameters:  ship playerShip passed by reference, ship enemyShip passed by reference, int currentRange

//This function updates the enemyShips shield/armor/hull hitpoints based on damage inflicted by the player from a hit (if the hit is successful), it displays a message about whether you hit the enemy or not and how much damage you inflicted to shields/armor/hull 

void PlayerAttacksEnemy(ship playerShip, ship& enemyShip, int currentRange);



//EnemyAttacksPlayer

//Return type:  void

//Parameters:  ship playerShip passed by reference, ship enemyShip passed by reference, int currentRange

//This function updates the playerShips shield/armor/hull hitpoints based on damage inflicted by the enemy from a hit (if the hit is successful), it displays a message about whether the enemy hit you or not and how much damage it inflicted to your shields/armor/hull 

void EnemyAttacksPlayer(ship& playerShip, ship enemyShip, int currentRange);





//Main function

int main()

{

	srand((unsigned)time(0));



	//Declare variables

	int menuChoice = 0;

	ship playerShip;

	ship enemyShip;

	string shipName = "";

	bool fileExists;

	int shipMenu = 0;

	int specialization = 0;

	int size = 0;

	int weaponChoice = 0;

	int ammoChoice = 0;

	int currentRange = 0;

	float percHealth = 0;

	int combatChoice = 0;

	

	cout<<endl<<"Welcome to blah blah blah";



	do

	{

		cout<<endl;

		menuChoice = MainMenu();



		//Instructions

		if(menuChoice==1)

		{

			cout<<endl<<"Instructions go here";

		}

		//Actual game

		else if(menuChoice==2)

		{

			shipName="PlayerShip.txt";

			fileExists=DoesFileExist(shipName);



			if(fileExists==true)

			{

				playerShip=LoadShip(shipName);



				//actual game begins here

				//Generate enemy vessel

				//Make it the same size as the player vessel, everything else is random

				shipName="EnemyShip.txt";

				size=RandomNum(1,3);	

				specialization=RandomNum(1,3);	

				weaponChoice=RandomNum(1,4);	

				ammoChoice=RandomNum(1,4);

				enemyShip=CalculateShipAttributes (specialization, size, weaponChoice, ammoChoice);

				WriteShipFile (enemyShip, shipName);

	

				cout<<endl<<"The enemy has the following attributes:"<<endl;	

				DisplayShipAttributes (enemyShip);	



				//Nested for loops go here



				//Combat do while loop

				do

				{

					//If the player is faster than the enemy they set the range

					if(playerShip.velocity>=enemyShip.velocity)

					{

						currentRange=playerShip.optimalRange;

					}

					else

					{

						currentRange=enemyShip.optimalRange;

					}



					//Display current range and everyone's health

					cout<<endl<<endl<<"Current Range:  "<<currentRange<<"km";

					cout<<fixed<<setprecision(0);

					cout<<endl<<"Your shields:  ";

					percHealth = PercHealth (playerShip.shieldHitPoints, "PlayerShip.txt", 1);

					cout<<percHealth<<"%";

					/*

					DisplayHealthBar(percHealth);

					*/



					cout<<endl<<"Your armor:  ";

					percHealth = PercHealth (playerShip.armorHitPoints, "PlayerShip.txt", 2);

					cout<<percHealth<<"%";



					cout<<endl<<"Your hull:  ";

					percHealth = PercHealth (playerShip.hullHitPoints, "PlayerShip.txt", 3);

					cout<<percHealth<<"%";



					cout<<endl;



					cout<<endl<<"Enemy shields:  ";

					percHealth = PercHealth (enemyShip.shieldHitPoints, "EnemyShip.txt", 1);

					cout<<percHealth<<"%";



					cout<<endl<<"Enemy armor:  ";

					percHealth = PercHealth (enemyShip.armorHitPoints, "EnemyShip.txt", 2);

					cout<<percHealth<<"%";



					cout<<endl<<"Enemy hull:  ";

					percHealth = PercHealth (enemyShip.hullHitPoints, "EnemyShip.txt", 3);

					cout<<percHealth<<"%";





					combatChoice = PromptCombatChoice();



					//Player attacks enemy

					if(combatChoice==1)

					{

						PlayerAttacksEnemy(playerShip, enemyShip, currentRange);

					}

					else if(combatChoice==2)

					{

						//Player switches weapon/ammo

						weaponChoice = PromptWeaponChoice();

						ammoChoice = PromptAmmoChoice();	

						UpdateShipWeapon(playerShip.size, weaponChoice, ammoChoice, playerShip);

					}

					else if(combatChoice==3)

					{

						//Player attempts escape, only succesfull if they are faster than the enemy

						if(playerShip.velocity>enemyShip.velocity)

						{

							cout<<endl<<endl<<"You escaped!";

						}

						else

						{

							cout<<endl<<endl<<"You are not fast enough to escape.";

						}

					}



					EnemyAttacksPlayer(playerShip, enemyShip, currentRange);



					//Set anything that is negative to 0

					if(playerShip.shieldHitPoints<0)

					{

						playerShip.shieldHitPoints=0;

					}

					if(playerShip.armorHitPoints<0)

					{

						playerShip.armorHitPoints=0;

					}

					if(playerShip.hullHitPoints<0)

					{

						playerShip.hullHitPoints=0;

					}

					if(enemyShip.shieldHitPoints<0)

					{

						enemyShip.shieldHitPoints=0;

					}

					if(enemyShip.armorHitPoints<0)

					{

						enemyShip.armorHitPoints=0;

					}

					if(enemyShip.hullHitPoints<0)

					{

						enemyShip.hullHitPoints=0;

					}



				}

				while(enemyShip.hullHitPoints>0 & playerShip.hullHitPoints>0);



				//Either the enemy or player has died

		

				if(enemyShip.hullHitPoints=0)

				{

					cout<<endl<<endl<<"Congradulations!  You have defeated the enemy!";

				}

				else if(playerShip.hullHitPoints=0)

				{

					cout<<endl<<endl<<"Your enemy has destroyed you.  Please try again.";

				}

			}

			else

			{

				cout<<endl<<"Error.  File does not exist.  Please create a ship first.";

			}		

		}

		//Create

		else if(menuChoice==3)

		{

			shipName="PlayerShip.txt";



			specialization = PromptSpecialization();

			size = PromptSize();

			weaponChoice = PromptWeaponChoice();

			ammoChoice = PromptAmmoChoice();

			playerShip=CalculateShipAttributes (specialization, size, weaponChoice, ammoChoice);

			playerShip.size=size;

			WriteShipFile (playerShip, shipName);



			//Go ahead and automatically load the ship they just created in case they forget



			cout<<endl<<"Your ship has the following attributes:"<<endl;

			DisplayShipAttributes (playerShip);

		}

		//Display

		else if(menuChoice==4)

		{

			shipName="PlayerShip.txt";



			fileExists=DoesFileExist(shipName);



			if(fileExists==true)

			{

				playerShip=LoadShip(shipName);



				cout<<endl<<"Your ship has the following attributes:"<<endl;

				DisplayShipAttributes (playerShip);

			}

			else

			{

				cout<<endl<<"Error.  File does not exist.  Please create a ship first.";

			}

		}

		//View high scores

		else if(menuChoice==5)

		{

			cout<<"Unavailible at the moment."<<endl;

		}

		//Quit

		else if(menuChoice==6)

		{

			cout<<endl<<"Have a nice day!";

		}

	}

	while(menuChoice!=6);

	

	cout<<endl;



	return 0;

}



ship CalculateShipAttributes (int specialization, int size, int primaryWeaponChoice, int ammoChoice)

{

	ship myShip;



	//Calculate the attributes

	myShip.velocity = CalcVelocity(size);

	myShip.damage = CalcDamage (size, primaryWeaponChoice);

	myShip.shieldHitPoints = CalcShields (size);

	myShip.armorHitPoints = CalcArmor (size);

	myShip.hullHitPoints = CalcHull (size);

	myShip.accuracyFalloff = CalcAccuracyFalloff (size, primaryWeaponChoice);

	myShip.optimalRange = CalcOptimalRange (size, primaryWeaponChoice);

	myShip.trackingSpeed = CalcTrackingSpeed (size, primaryWeaponChoice);

	CalcDamageBonuses (myShip.damageBonusShield, myShip.damageBonusArmor, ammoChoice, myShip.damage);

	

	//Specializations

	if(specialization==1)

	{

		myShip.velocity = myShip.velocity * 2;

	}

	else if(specialization==2)

	{

		myShip.shieldHitPoints=myShip.shieldHitPoints * 2;

	}

	else if(specialization==3)

	{

		myShip.armorHitPoints=myShip.armorHitPoints * 2;

	}



	return myShip;

}



void UpdateShipWeapon(int size, int weaponChoice, int ammoChoice, ship& myShip)

{

	myShip.damage = CalcDamage (size, weaponChoice);

	myShip.accuracyFalloff = CalcAccuracyFalloff (size, weaponChoice);

	myShip.optimalRange = CalcOptimalRange (size, weaponChoice);

	myShip.trackingSpeed = CalcTrackingSpeed (size, weaponChoice);

	CalcDamageBonuses (myShip.damageBonusShield, myShip.damageBonusArmor, ammoChoice, myShip.damage);

}



void WriteShipFile (ship myShip, string shipName)

{

	//Write it to a file

	ofstream outputFile;

	outputFile.open(shipName.c_str());

	

	outputFile<<myShip.size<<endl;

	outputFile<<myShip.velocity<<endl;

	

	outputFile<<myShip.damageBonusShield<<endl;

	outputFile<<myShip.damageBonusArmor<<endl;

	outputFile<<myShip.damage<<endl;

	

	outputFile<<myShip.shieldHitPoints<<endl;

	outputFile<<myShip.armorHitPoints<<endl;	

	outputFile<<myShip.hullHitPoints<<endl;

	

	outputFile<<myShip.accuracyFalloff<<endl;

	outputFile<<myShip.optimalRange<<endl;

	outputFile<<myShip.trackingSpeed<<endl;

	

	outputFile.close();

}



bool IsHit(float accuracyFalloff, float optimalRange, float currentRange, float velocity, float trackingSpeed)

{

	float hitChance = 0.0;

	int randomNum = 0;

	

	//in radians/s

	float angularVelocity = velocity/currentRange;

	

	//angular speed of the enemy is greater than tracking speed of the turret

	if(angularVelocity>trackingSpeed)

	{

		return false;

	}

	//Extremely close range

	else if (currentRange < accuracyFalloff)

	{

		return true;

	}

	else if (currentRange >= accuracyFalloff)

	{

		//calculate hitChance

		hitChance = 1.f - abs(optimalRange - currentRange) / accuracyFalloff * 0.5f;

	

		//If we have 1/6 chance for example that's 0.15.  0.15 times 1000 is 150, we pick a random number between 0 and 1000 and we'll have a 1/6th chance of it being less than or equal to 150	

		randomNum=RandomNum(0,1000);



		if (hitChance*1000 <= randomNum)

		{

			return true;

		}

		else if(hitChance*1000 > randomNum)

		{

			return false;

		}

	}

}



int RandomNum(int lo, int hi) 

{

  	// note: floor() really only needed if hi < 0



	int range = (hi - lo+1);

	return rand()%range+lo;

}



ship LoadShip(string shipName)

{

	ship Ship1;

	ifstream inputFile;



	inputFile.open(shipName.c_str());



	inputFile>>Ship1.size;

	inputFile>>Ship1.velocity;

	inputFile>>Ship1.damageBonusShield;

	inputFile>>Ship1.damageBonusArmor;

	inputFile>>Ship1.damage;

	inputFile>>Ship1.shieldHitPoints;

	inputFile>>Ship1.armorHitPoints;	

	inputFile>>Ship1.hullHitPoints;

	inputFile>>Ship1.accuracyFalloff;

	inputFile>>Ship1.optimalRange;

	inputFile>>Ship1.trackingSpeed;



	inputFile.close();



	return Ship1;

}



bool DoesFileExist(string shipName)

{

	ifstream inputFile;



	inputFile.open(shipName.c_str());



	if(inputFile.fail())

	{ 

		return false;

	}

	else

	{

		return true;

	}

}



void DisplayShipAttributes (ship playerShip)

{	

	//Display everything

	cout<<"Velocity:  \t\t\t"<<playerShip.velocity<<" meters per second"<<endl;

	

	cout<<"Base damage:  \t\t\t"<<playerShip.damage<<" hitpoints"<<endl;

	cout<<"Bonus damage against shields:  \t"<<playerShip.damageBonusShield<<" hitpoints"<<endl;

	cout<<"Bonus damage against armor:  \t"<<playerShip.damageBonusArmor<<" hitpoints"<<endl;

	

	cout<<"Shields:  \t\t\t"<<playerShip.shieldHitPoints<<" hitpoints"<<endl;

	cout<<"Armor:  \t\t\t"<<playerShip.armorHitPoints<<" hitpoints"<<endl;	

	cout<<"Hull:  \t\t\t\t"<<playerShip.hullHitPoints<<" hitpoints"<<endl;

	

	cout<<"Accuracy falloff:  \t\t"<<playerShip.accuracyFalloff<<" meters"<<endl;

	cout<<"Optimal range:  \t\t"<<playerShip.optimalRange<<" meters"<<endl;

	cout<<"Tracking speed:  \t\t"<<playerShip.trackingSpeed<<" radians per second"<<endl;

}



//Make a function to get the percentage remaining health, but use 50 instead of 100

float PercHealth (int current, string shipName, int healthType)

{

	ship myShip=LoadShip(shipName);



	if(healthType==1)

	{

		return (current/myShip.shieldHitPoints) * 100;

	}

	else if(healthType==2)

	{

		return (current/myShip.armorHitPoints) * 100;

	}

	else if(healthType==3)

	{

		return (current/myShip.hullHitPoints) * 100;

	}

}



void PlayerAttacksEnemy(ship playerShip, ship& enemyShip, int currentRange)

{

	if (IsHit(playerShip.accuracyFalloff, playerShip.optimalRange, currentRange, enemyShip.velocity, playerShip.trackingSpeed)==true)

	{

		//Player deals damage

		cout<<endl<<endl<<"You hit the enemy!";

		if(enemyShip.shieldHitPoints>0)

		{

			enemyShip.shieldHitPoints=enemyShip.shieldHitPoints-(playerShip.damage + playerShip.damageBonusShield);

			cout<<endl<<"You dealt "<<playerShip.damage + playerShip.damageBonusShield<<" damage to the enemy's shields.";						

		}

		else if(enemyShip.armorHitPoints>0)

		{

			enemyShip.armorHitPoints=enemyShip.armorHitPoints-(playerShip.damage + playerShip.damageBonusArmor);

			cout<<endl<<"You dealt "<<playerShip.damage + playerShip.damageBonusArmor<<" damage to the enemy's armor.";

		}

		else if (enemyShip.armorHitPoints<0)

		{

			enemyShip.hullHitPoints=enemyShip.hullHitPoints-playerShip.damage;

		}

			cout<<endl<<"You dealt "<<playerShip.damage<<" damage to the enemy's hull";

	}

	else

	{

		//Player misses the enemy

		cout<<endl<<endl<<"You missed!";

	}

}



void EnemyAttacksPlayer(ship& playerShip, ship enemyShip, int currentRange)

{

	//Enemy attacks player

	if (IsHit(enemyShip.accuracyFalloff, enemyShip.optimalRange, currentRange, playerShip.velocity, enemyShip.trackingSpeed)==true)

	{

		//enemy hits

		cout<<endl<<endl<<"The enemy hit you!";

		if(playerShip.shieldHitPoints>0)

		{

			playerShip.shieldHitPoints=playerShip.shieldHitPoints-(enemyShip.damage + enemyShip.damageBonusShield);	

			cout<<endl<<"The enemy dealt "<<enemyShip.damage + enemyShip.damageBonusShield<<" damage to your shields.";				

		}

		else if(playerShip.armorHitPoints>0)

		{

			playerShip.armorHitPoints=playerShip.armorHitPoints-(enemyShip.damage + enemyShip.damageBonusArmor);

			cout<<endl<<"The enemy dealt "<<enemyShip.damage + enemyShip.damageBonusArmor<<" damage to your armor.";

		}

		else if(playerShip.armorHitPoints<0)

		{

			enemyShip.hullHitPoints=enemyShip.hullHitPoints-playerShip.damage;

			cout<<endl<<"The enemy dealt "<<enemyShip.damage<<" damage to your hull.";

		}

	}

	else

	{

		//Enemy misses

		cout<<endl<<endl<<"The enemy missed you!";

	}

}