diff --git a/8382/Torosyan_lr1-7/bin/Debug/lab.exe b/8382/Torosyan_lr1-7/bin/Debug/lab.exe new file mode 100644 index 000000000..5a2557b34 Binary files /dev/null and b/8382/Torosyan_lr1-7/bin/Debug/lab.exe differ diff --git a/8382/Torosyan_lr1-7/dice.cpp b/8382/Torosyan_lr1-7/dice.cpp new file mode 100644 index 000000000..f6ee44809 --- /dev/null +++ b/8382/Torosyan_lr1-7/dice.cpp @@ -0,0 +1,10 @@ +#include +#include +class Random{ +public: +int percentRoll( int percent ) +{ + srand(time(0)); + return (rand() % 100) < percent ? 1 : 0; +} +}; diff --git a/8382/Torosyan_lr1-7/game.cpp b/8382/Torosyan_lr1-7/game.cpp new file mode 100644 index 000000000..324ddcef9 --- /dev/null +++ b/8382/Torosyan_lr1-7/game.cpp @@ -0,0 +1,405 @@ +#include +#include +#include +#include +#include + +#ifndef LOG +#define LOG +#include "log.cpp" +#endif + +#ifndef TERRAIN +#define TERRAIN +#include "terrain.cpp" +#endif + +#ifndef PLAYER +#define PLAYER +#include "player.cpp" +#endif +using std::cin; +using std::cout; +using std::endl; +class Game +{ +public: + Logger gameLog; + Terrain terrain; + int playerCount = 2; + Player lobby[2]; + int turns = 0; + + int percentRoll( int percent ) + { + srand(time(0)); + return (rand() % 100) < percent ? 1 : 0; + } + + void moveUnit( UnitBase* u, int dx, int dy) + { + if(int(sqrt(dx*dx + dy*dy)) > u->movementRange) + { + cout << "This unit can\'t move so far away!"; + return; + } + int X = u->x + dx; + int Y = u->y + dy; + if( terrain.isOutOfBounds(X, Y)) + { + cout << "Out of bounds!"; + return; + } + if( terrain.isOccupied(X, Y)) + { + cout << "There is another unit!"; + return; + } + u->x = X; + u->y = Y; + + gameLog.moveLog( u->name, u->faction, dx, dy); + }; + + void attack( UnitBase* attacker, UnitBase* target) + { + gameLog.attackLog(attacker->name, attacker->faction, target->name, target->faction); + + int dx = target->x - attacker->x; + int dy = target->y - attacker->y; + if(int(sqrt(dx*dx + dy*dy)) > attacker->attackRange) + { + cout << "Target is too far!"; + return; + } + target->HP -= attacker->damage * percentRoll( int( 50 + attacker->pierce / (100 + attacker->pierce) - target->armor / (100 + attacker->armor) ) ); + if(target->HP < 0) target->HP = 0; + if (target->HP == 0) + { + if(target->name == "Headquarters") + return; + terrain.removeUnit( target ); + for(int i = 0; i < terrain.unitCount; i++) + { + if(typeid(terrain.unitList[i]) == typeid(UnitHQ*)) + ((UnitHQ*) terrain.unitList[i])->onUnitDie( target ); + }; + delete target; + } + }; + + void attack( UnitBase* attacker, EntityArmor* target) + { + gameLog.attackLog(attacker->name, attacker->faction, target->name, target->faction); + + int dx = target->x - attacker->x; + int dy = target->y - attacker->y; + if(int(sqrt(dx*dx + dy*dy)) > attacker->attackRange) + { + cout << "Target is too far!"; + return; + } + attacker->armor += attacker->armor <= 95 ? 5 : 100 - attacker->armor; + terrain.removeUnit( target ); + delete target; + } + void attack( UnitBase* attacker, EntityAmmo* target) + { + gameLog.attackLog(attacker->name, attacker->faction, target->name, target->faction); + + int dx = target->x - attacker->x; + int dy = target->y - attacker->y; + if(int(sqrt(dx*dx + dy*dy)) > attacker->attackRange) + { + cout << "Target is too far!"; + return; + } + attacker->pierce += attacker->pierce <= 95 ? 5 : 100 - attacker->pierce; + terrain.removeUnit( target ); + delete target; + } + void attack( UnitBase* attacker, EntityOptics* target) + { + gameLog.attackLog(attacker->name, attacker->faction, target->name, target->faction); + + int dx = target->x - attacker->x; + int dy = target->y - attacker->y; + if(int(sqrt(dx*dx + dy*dy)) > attacker->attackRange) + { + cout << "Target is too far!"; + return; + } + attacker->attackRange++; + terrain.removeUnit( target ); + delete target; + } + void attack( UnitBase* attacker, EntityMedkit* target) + { + gameLog.attackLog(attacker->name, attacker->faction, target->name, target->faction); + + int dx = target->x - attacker->x; + int dy = target->y - attacker->y; + if(int(sqrt(dx*dx + dy*dy)) > attacker->attackRange) + { + cout << "Target is too far!"; + return; + } + attacker->HP += 10; + terrain.removeUnit( target ); + delete target; + } + + void placeBonus( std::string entityType, int x, int y ) + { + if(terrain.isOccupied(x, y) || terrain.isOutOfBounds(x, y)) return; + + if( entityType == "Armor" ) terrain.addUnit( new EntityArmor (x, y) ); else + if( entityType == "Ammo" ) terrain.addUnit( new EntityAmmo (x, y) ); else + if( entityType == "Optics" ) terrain.addUnit( new EntityOptics (x, y) ); else + if( entityType == "Medkit" ) terrain.addUnit( new EntityMedkit (x, y) ); else + throw "There are no " + entityType + "s today. Come tomorrow :3"; + + } + + void createUnit(std::string unitType, UnitHQ* hq) + { + int destX = hq->x, destY = hq->y; + if(!terrain.isOccupied(destX-1, destY-1) && !terrain.isOutOfBounds(destX-1, destY-1)) {destX = hq->x-1; destY = hq->y-1;} else + if(!terrain.isOccupied(destX+0, destY-1) && !terrain.isOutOfBounds(destX+0, destY-1)) {destX = hq->x+0; destY = hq->y-1;} else + if(!terrain.isOccupied(destX+1, destY-1) && !terrain.isOutOfBounds(destX+1, destY-1)) {destX = hq->x+1; destY = hq->y-1;} else + if(!terrain.isOccupied(destX-1, destY+0) && !terrain.isOutOfBounds(destX-1, destY+0)) {destX = hq->x-1; destY = hq->y+0;} else + if(!terrain.isOccupied(destX+1, destY+0) && !terrain.isOutOfBounds(destX+1, destY+0)) {destX = hq->x+1; destY = hq->y+0;} else + if(!terrain.isOccupied(destX-1, destY+1) && !terrain.isOutOfBounds(destX-1, destY+1)) {destX = hq->x-1; destY = hq->y+1;} else + if(!terrain.isOccupied(destX+0, destY+1) && !terrain.isOutOfBounds(destX+0, destY+1)) {destX = hq->x+0; destY = hq->y+1;} else + if(!terrain.isOccupied(destX+1, destY+1) && !terrain.isOutOfBounds(destX+1, destY+1)) {destX = hq->x+1; destY = hq->y+1;} else + throw "The HQ is a bit crowded :c"; + + if( unitType == "Sniper" ) terrain.addUnit( hq->makeSniper ( destX, destY ) ); else + if( unitType == "AntiTank" ) terrain.addUnit( hq->makeAntiTank ( destX, destY ) ); else + if( unitType == "IFV" ) terrain.addUnit( hq->makeIFV ( destX, destY ) ); else + if( unitType == "Tank" ) terrain.addUnit( hq->makeTank ( destX, destY ) ); else + if( unitType == "Bomber" ) terrain.addUnit( hq->makeBomber ( destX, destY ) ); else + if( unitType == "Interceptor" ) terrain.addUnit( hq->makeInterceptor( destX, destY ) ); else + throw "There are no " + unitType + "s today. Come tomorrow :3"; + }; + + void loginPlayers() + { + for(int p = 0; p < playerCount; p++) + { + cout << "\nPlayer " << p+1 << " name: "; + cin >> lobby[p].faction; + lobby[p].money = 3000; + } + } + + void placeHQs() + { + for(int p = 0; p < playerCount; p++) + { + cout << "\nEnter coordinates for your base, " << lobby[p].faction <<" [\"x y\"]: "; + int x, y; + cin >> x >> y; + if(terrain.isOccupied(x, y) || terrain.isOutOfBounds(x, y)) throw "Unable to place HQ here"; + UnitHQ* tmp = new UnitHQ( lobby[p].faction, x, y, terrain.unitCap); + lobby[p].hq = tmp; + terrain.addUnit( tmp ); + + gameLog.placeHQLog( lobby[p].faction, x, y); + } + } + + void update() + { + for(int p = 0; p < playerCount; p++) + { + terrain.render(); + cout << lobby[p].faction << " turn:\n"; + turn(&(lobby[p])); + Sleep(750); + cout << "\nPress enter for next turn."; + cin.get(); + cin.get(); + } + }; + + void turn(Player* p) + { + cout << "\nBase HP: " << p->hq->HP << "\nFunds: " << p->money << "$\nUnit list:\n"; + for(int i = 0; i < p->hq->unitCount; i++) + cout << p->hq->unitList[i]->name << "(" << p->hq->unitList[i]->HP << "% HP)"<<" at [ " << p->hq->unitList[i]->x << ", " << p->hq->unitList[i]->y << " ]" << endl; + string buyOrder; + //BUY PHASE + cout << "BUY PHASE [use \"buy X\" to buy X or anything else to skip]:\n"; + cout << " 1 - [INF] Sniper (200$)\n"; + cout << " 2 - [INF] AntiTank (300$)\n"; + cout << " 3 - [VEH] IFV (500$)\n"; + cout << " 4 - [VEH] Tank (800$)\n"; + cout << " 5 - [AIR] Bomber (1500$)\n"; + cout << " 6 - [AIR] Interceptor (1200$)\n"; + cin >> buyOrder; + if (buyOrder == "buy") + { + int pos; + cin >> pos; + switch(pos) + { + case 1: + { + if( p->money >= 200) + { + cout << "Building..."; + p->money -= 200; + createUnit("Sniper", p->hq); + gameLog.buyLog( p->faction, "Sniper", 200); + } else + { + cout << "Insufficient funds."; + } + } + break; + case 2: + { + if( p->money >= 300) + { + cout << "Building..."; + p->money -= 300; + createUnit("AntiTank", p->hq); + gameLog.buyLog( p->faction, "AntiTank", 300); + } else + { + cout << "Insufficient funds."; + } + } + break; + case 3: + { + if( p->money >= 500) + { + cout << "Building..."; + p->money -= 500; + createUnit("IFV", p->hq); + gameLog.buyLog( p->faction, "IFV", 500); + } else + { + cout << "Insufficient funds."; + } + } + break; + case 4: + { + if( p->money >= 800) + { + cout << "Building..."; + p->money -= 800; + createUnit("Tank", p->hq); + gameLog.buyLog( p->faction, "Tank", 800); + } else + { + cout << "Insufficient funds."; + } + } + break; + case 5: + { + if( p->money >= 1500) + { + cout << "Building..."; + p->money -= 1500; + createUnit("Bomber", p->hq); + gameLog.buyLog( p->faction, "Bomber", 1500); + } else + { + cout << "Insufficient funds."; + } + } + break; + case 6: + { + if( p->money >= 1200) + { + cout << "Building..."; + p->money -= 1200; + createUnit("Interceptor", p->hq); + gameLog.buyLog( p->faction, "Interceptor", 1200); + } else + { + cout << "Insufficient funds."; + } + } + break; + default: {cout << "There are no position #" << pos << ", skipping...\n";} break; + } + } + //MOVE PHASE + cin.get(); + cout << "\nMOVE PHASE: "; + cout << "\nFor each unit, type \"move X Y\" to move it by X Y or anything else to skip: "; + for( int unit = 0; unit < p->hq->unitCount; unit++) + { + cout << endl << p->hq->unitList[unit]->name << " at [" << p->hq->unitList[unit]->x << ", " << p->hq->unitList[unit]->y <<"]: "; + string order; + cin >> order; + if(order == "move") + { + int dx, dy; + cin >> dx >> dy; + moveUnit( p->hq->unitList[unit], dx, dy); + } + } + //ATTACK PHASE + cin.get(); + cout << "\nATTACK PHASE: "; + cout << "\nFor each unit, type \"attack X Y\" to attack position X Y or anything else to skip: "; + for( int unit = 0; unit < p->hq->unitCount; unit++) + { + cout << endl << p->hq->unitList[unit]->name << " at [" << p->hq->unitList[unit]->x << ", " << p->hq->unitList[unit]->y <<"]: "; + string order; + cin >> order; + if(order == "attack") + { + int x, y; + cin >> x >> y; + if(terrain.isOccupied(x, y)) + { + int tgt = 0; + while(!(x == terrain.unitList[tgt]->x && y == terrain.unitList[tgt]->y)) + tgt++; + attack(p->hq->unitList[unit], terrain.unitList[tgt]); + } else cout << "\nNothing to shoot here."; + } + } + } + + int checkWinConditions() // returns id of winner, -1 if game is still running, -2 if draw + { + if( turns >= 64 ) return -2; + if(lobby[0].hq->HP == 0) return 1; + if(lobby[1].hq->HP == 0) return 0; + return -1; + } + + Game( int X, int Y, int UnitCap) : terrain(X, Y, UnitCap), gameLog("game.log") + { + loginPlayers(); + placeBonus( "Armor", 0, 4 ); + placeBonus( "Ammo", 5, 6 ); + placeBonus( "Optics", 2, 7 ); + placeBonus( "Medkit", 8, 3 ); + terrain.render(); + placeHQs(); + while(checkWinConditions() == -1) update(); + switch(checkWinConditions()) + { + case -2: cout << "DRAW"; break; + case 0: cout << lobby[0].faction <<" WINS"; break; + case 1: cout << lobby[1].faction <<" WINS"; break; + default: break; + } + }; + + ~Game() + { + delete[] lobby; + } +}; diff --git a/8382/Torosyan_lr1-7/hq.cpp b/8382/Torosyan_lr1-7/hq.cpp new file mode 100644 index 000000000..f7f545c6f --- /dev/null +++ b/8382/Torosyan_lr1-7/hq.cpp @@ -0,0 +1,12 @@ +class UnitHQ : public UnitBase +{ +public: + const static int + pierce = 0, + armor = 75, + damage = 0, + movementRange = 0; + const std::string + name = "Headquarters"; + UnitHQ( TFaction argFaction, int X, int Y ) : UnitBase( argFaction, X, Y ) {} +}; diff --git a/8382/Torosyan_lr1-7/lab.cbp b/8382/Torosyan_lr1-7/lab.cbp new file mode 100644 index 000000000..6db45b014 --- /dev/null +++ b/8382/Torosyan_lr1-7/lab.cbp @@ -0,0 +1,49 @@ + + + + + + diff --git a/8382/Torosyan_lr1-7/lab.depend b/8382/Torosyan_lr1-7/lab.depend new file mode 100644 index 000000000..c94b0d352 --- /dev/null +++ b/8382/Torosyan_lr1-7/lab.depend @@ -0,0 +1,64 @@ +# depslib dependency file v1.0 +1591599239 source:c:\users\euronics\desktop\oop\lab\main.cpp + + + "game.cpp" + +1591599210 source:c:\users\euronics\desktop\oop\lab\terrain.cpp + + + "units.cpp" + +1591604910 c:\users\euronics\desktop\oop\lab\units.cpp + + + "log.cpp" + +1591604910 source:c:\users\euronics\desktop\oop\lab\units.cpp + + + "log.cpp" + +1591599210 c:\users\euronics\desktop\oop\lab\terrain.cpp + + + "units.cpp" + +1591604910 c:\users\euronics\desktop\oop\lab\game.cpp + + + + + + "log.cpp" + "terrain.cpp" + "player.cpp" + +1591589637 source:c:\users\euronics\desktop\oop\lab\dice.cpp + + + +1591589685 c:\users\euronics\desktop\oop\lab\dice.cpp + + + +1591597067 c:\users\euronics\desktop\oop\lab\player.cpp + + "units.cpp" + +1591590425 c:\users\euronics\desktop\oop\lab\\units.cpp + + + +1591597067 source:c:\users\euronics\desktop\oop\lab\player.cpp + + "units.cpp" + +1591604558 c:\users\euronics\desktop\oop\lab\log.cpp + + + +1591604558 source:c:\users\euronics\desktop\oop\lab\log.cpp + + + diff --git a/8382/Torosyan_lr1-7/lab.layout b/8382/Torosyan_lr1-7/lab.layout new file mode 100644 index 000000000..199e75930 --- /dev/null +++ b/8382/Torosyan_lr1-7/lab.layout @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/8382/Torosyan_lr1-7/log.cpp b/8382/Torosyan_lr1-7/log.cpp new file mode 100644 index 000000000..80c92ef03 --- /dev/null +++ b/8382/Torosyan_lr1-7/log.cpp @@ -0,0 +1,61 @@ +#include +#include +using namespace std; + +class LogFileHandler +{ +public: + + string path; + ofstream log; + LogFileHandler(string Path) : path(Path) + { + log.open(Path); + log << ios_base::app; + } + + ~LogFileHandler() + { + log.close(); + } +}; + +class Logger +{ +public: + + string path; + + Logger(string Path) : path(Path) {}; + + void placeHQLog( string faction, int x, int y ) + { + LogFileHandler lfh(path); + lfh.log << "Player " << faction << " placed their HQ at (" << x << ", " << y << ")\n"; + }; + void moveLog( string name, string faction, int dx, int dy) + { + LogFileHandler lfh(path); + lfh.log << "Unit " << name << " [" << faction << "] moved by (" << dx << ", " << dy << ")\n"; + }; + void attackLog( string aName, string aFaction, string tName, string tFaction) + { + LogFileHandler lfh(path); + lfh.log << aName << " [" << aFaction << "] attacked " << tName << " [" << tFaction << "]\n"; + }; + void buyLog( string faction, string name, int price) + { + LogFileHandler lfh(path); + lfh.log << "Player " << faction << " bought " << name << " for " << price << "\n"; + }; + void HQAddUnitLog( string faction, string name) + { + LogFileHandler lfh(path); + lfh.log << faction << " got " << name << "\n"; + }; + void HQLoseUnitLog( string faction, string name) + { + LogFileHandler lfh(path); + lfh.log << faction << " lost " << name << "\n"; + }; +}; diff --git a/8382/Torosyan_lr1-7/main.cpp b/8382/Torosyan_lr1-7/main.cpp new file mode 100644 index 000000000..266f1f8a1 --- /dev/null +++ b/8382/Torosyan_lr1-7/main.cpp @@ -0,0 +1,13 @@ +#include +#include +#ifndef GAME +#define GAME +#include "game.cpp" +#endif +using namespace std; + +int main() +{ + Game game(10, 10, 30); + return 0; +} diff --git a/8382/Torosyan_lr1-7/player.cpp b/8382/Torosyan_lr1-7/player.cpp new file mode 100644 index 000000000..54c84e2fd --- /dev/null +++ b/8382/Torosyan_lr1-7/player.cpp @@ -0,0 +1,13 @@ +#include +#ifndef UNITS +#define UNITS +#include "units.cpp" +#endif +using std::string; +class Player +{ +public: + int money=0; + std::string faction=""; + UnitHQ* hq=nullptr; +}; diff --git a/8382/Torosyan_lr1-7/terrain.cpp b/8382/Torosyan_lr1-7/terrain.cpp new file mode 100644 index 000000000..f5539ea64 --- /dev/null +++ b/8382/Torosyan_lr1-7/terrain.cpp @@ -0,0 +1,111 @@ +#include +#include +#ifndef UNITS +#define UNITS +#include "units.cpp" +#endif +using std::cout; +using std::endl; + +class Terrain +{ + public: + const int sizeX, sizeY; + const int unitCap; + char** field; // sizeX * sizeY array of landscape types + UnitBase** unitList; // array of unit pointers, not more than unitCap + int unitCount = 0; + + void removeUnit( UnitBase* u ) + { + int pos = 0; + while( unitList[pos] != u && pos++ < unitCount); + for(;pos < unitCount; pos++) + unitList[pos] = unitList[pos+1]; + } + + bool isOutOfBounds( int x, int y) + { + if( x < 0 || y < 0 || x >= sizeX || y >= sizeY) return true; + else return false; + }; + + bool isOccupied( int x, int y) + { + for( int i = 0; i < unitCount; i++) + if(x == unitList[i]->x && y == unitList[i]->y) + return true; + return false; + }; + + void render() + { + system("cls"); + for ( int y = 0; y < sizeY; y++ ){ + for ( int x = 0; x < sizeX; x++ ) + { + bool haveUnit = false; + for(int pos = 0; pos < unitCount; pos++) + if(unitList[pos]->x == x && unitList[pos]->y == y) + { + haveUnit = (unitList[pos]->x == x && unitList[pos]->y == y) ? true : haveUnit; + if(unitList[pos]->faction == "NEUTRAL") cout << '$'; else + if(unitList[pos]->name == "Headquarters") cout << '@'; else + cout << '*'; + } + + if(!haveUnit) + cout << field[y][x]; + } + cout << endl; + } + } + + + + Terrain( int x, int y, int UnitCap ) : sizeX(x), sizeY(y), unitCap(UnitCap) + { + unitList = new UnitBase * [UnitCap]; + + field = new char* [ sizeY ]; + for ( int i = 0; i < sizeY; i++ ) + field[i] = new char [ sizeX ]; + + for ( int y = 0; y < sizeY; y++ ) + for ( int x = 0; x < sizeX; x++ ) + { + field[y][x] = ( x > 4 && y > 4 && x < 8 && y < 8)? 'F' : 'L'; //static map generation + } + + }; + Terrain( const Terrain &t ) : sizeX(t.sizeX), sizeY(t.sizeY), unitCap(t.unitCap) + { + unitList = new UnitBase * [unitCap]; + + field = new char* [ sizeY ]; + for ( int i = 0; i < sizeY; i++ ) + field[i] = new char [ sizeX ]; + + for ( int y = 0; y < sizeY; y++ ) + for ( int x = 0; x < sizeX; x++ ) + { + field[y][x] = t.field[y][x]; //static map generation + } + + }; + + ~Terrain() { + delete[] unitList; + for ( int i = 0; i < sizeY; i++ ) + delete[] field[i]; + delete[] field; + }; + + void addUnit( UnitBase* u ) + { + if ( unitCount == unitCap ) + throw "Too much units!"; + unitList[unitCount++] = u; + }; +}; + diff --git a/8382/Torosyan_lr1-7/units.cpp b/8382/Torosyan_lr1-7/units.cpp new file mode 100644 index 000000000..e6f769686 --- /dev/null +++ b/8382/Torosyan_lr1-7/units.cpp @@ -0,0 +1,251 @@ +#include +#include + +#ifndef LOG +#define LOG +#include "log.cpp" +#endif + +class UnitBase +{ +public: + std::string faction; + int + pierce = 0, armor = 0, damage = 0, movementRange = 0, attackRange = 0; + std::string + name = "thats a bug mah friend"; + int HP; + int x, y; + + UnitBase( std::string argFaction, int X, int Y ) : + faction(argFaction), x(X), y(Y) + { + HP = 100; + }; +}; + +class UnitSniper : public UnitBase +{ +public: + UnitSniper( std::string argFaction, int X, int Y ) : UnitBase( argFaction, X, Y ) + { + pierce = 5; + armor = 5; + damage = 75; + movementRange = 2; + attackRange = 3; + name = "Sniper squad"; + } +}; + +class UnitAntiTank : public UnitBase +{ +public: + UnitAntiTank( std::string argFaction, int X, int Y ) : UnitBase( argFaction, X, Y ) + { + pierce = 40; + armor = 5; + damage = 70; + movementRange = 1; + attackRange = 3; + name = "Anti-tank team"; + } +}; + +class UnitIFV : public UnitBase +{ +public: + UnitIFV( std::string argFaction, int X, int Y ) : UnitBase( argFaction, X, Y ) + { + pierce = 20; + armor = 25; + damage = 55; + movementRange = 4; + attackRange = 2; + name = "IFV platoon"; + } +}; + +class UnitTank : public UnitBase +{ +public: + + UnitTank( std::string argFaction, int X, int Y ) : UnitBase( argFaction, X, Y ) + { + pierce = 40; + armor = 40; + damage = 75; + movementRange = 3; + attackRange = 4; + name = "Heavy tank platoon"; + } +}; + +class UnitBomber : public UnitBase +{ +public: + UnitBomber( std::string argFaction, int X, int Y ) : UnitBase( argFaction, X, Y ) + { + pierce = 60; + armor = 10; + damage = 150; + movementRange = 4; + attackRange = 1; + name = "Heavy bomber"; + } +}; + +class UnitInterceptor : public UnitBase +{ +public: + UnitInterceptor( std::string argFaction, int X, int Y ) : UnitBase( argFaction, X, Y ) + { + pierce = 90; + armor = 20; + damage = 90; + movementRange = 5; + attackRange = 3; + name = "Interceptors wing"; + } +}; + +class UnitHQ : public UnitBase +{ +public: + Logger baseLog; + UnitBase** unitList; + int unitCount = 0; + + UnitHQ( std::string argFaction, int X, int Y, int UnitCap ) : UnitBase( argFaction, X, Y), baseLog("base.log") + { + pierce = 0; + armor = 40; + damage = 0; + movementRange = 0; + attackRange = 0; + name = "Headquarters"; + HP = 200; + unitList = new UnitBase * [UnitCap]; + }; + + ~UnitHQ() + { + delete[] unitList; + } + + void addUnit( UnitBase* u ) + { + baseLog.HQAddUnitLog( u->faction, u->name ); + unitList[unitCount++] = u; + }; + + void removeUnit( UnitBase* u ) + { + baseLog.HQLoseUnitLog( u->faction, u->name ); + int pos = 0; + while( unitList[pos] != u && pos++ < unitCount); + for(;pos < unitCount; pos++) + unitList[pos] = unitList[pos+1]; + } + + void onUnitDie(UnitBase* u ) + { + removeUnit( u ); + }; + void onUnitCreate(UnitBase* u ) + { + addUnit( u ); + }; + + UnitSniper* makeSniper(int X, int Y){ + UnitSniper* tmp = new UnitSniper(faction, X, Y); + addUnit( tmp ); + return tmp; + }; + UnitAntiTank* makeAntiTank(int X, int Y){ + UnitAntiTank* tmp = new UnitAntiTank(faction, X, Y); + addUnit( tmp ); + return tmp; + }; + UnitIFV* makeIFV(int X, int Y){ + UnitIFV* tmp = new UnitIFV(faction, X, Y); + addUnit( tmp ); + return tmp; + }; + UnitTank* makeTank(int X, int Y){ + UnitTank* tmp = new UnitTank(faction, X, Y); + addUnit( tmp ); + return tmp; + }; + UnitBomber* makeBomber(int X, int Y){ + UnitBomber* tmp = new UnitBomber(faction, X, Y); + addUnit( tmp ); + return tmp; + }; + UnitInterceptor* makeInterceptor(int X, int Y){ + UnitInterceptor* tmp = new UnitInterceptor(faction, X, Y); + addUnit( tmp ); + return tmp; + }; +}; + +class EntityArmor : public UnitBase +{ +public: + EntityArmor( int X, int Y ) : UnitBase( "NEUTRAL", X, Y ) + { + pierce = 0; + armor = 5; + damage = 0; + movementRange = 0; + attackRange = 0; + name = "Additional armor"; + } +}; + +class EntityAmmo : public UnitBase +{ +public: + EntityAmmo( int X, int Y ) : UnitBase( "NEUTRAL", X, Y ) + { + pierce = 0; + armor = 5; + damage = 0; + movementRange = 0; + attackRange = 0; + name = "Armor-piercing ammo"; + } +}; + +class EntityOptics : public UnitBase +{ +public: + EntityOptics( int X, int Y ) : UnitBase( "NEUTRAL", X, Y ) + { + pierce = 0; + armor = 5; + damage = 0; + movementRange = 0; + attackRange = 0; + name = "Improved optics"; + } +}; + +class EntityMedkit : public UnitBase +{ +public: + EntityMedkit( int X, int Y ) : UnitBase( "NEUTRAL", X, Y ) + { + pierce = 0; + armor = 5; + damage = 0; + movementRange = 0; + attackRange = 0; + name = "Medi-kits"; + } +}; +/* +* INF: sniper, anti-tank +* VEH: IFV, AA +* AIR: bomber, intercept +*/