diff --git a/Assets/Scripts/GameObjects/Units/unitData.lua b/Assets/Scripts/GameObjects/Units/unitData.lua index 6792418..1c582b9 100644 --- a/Assets/Scripts/GameObjects/Units/unitData.lua +++ b/Assets/Scripts/GameObjects/Units/unitData.lua @@ -47,6 +47,7 @@ units = { health = {500, 600, 200, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500}, cost = {500, 600, 200, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500}, range = {15, 20, 45, 15, 14, 14, 13, 13, 12, 12, 15, 0, 25}, + damage = {15, 20, 45, 15, 14, 14, 13, 13, 12, 12, 15, 100, 100}, rateOfFire = {50, 60, 80, 100, 100, 100, 100, 100, 0, 0, 0, 0, 100}, garrisonCapacity = {0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0}, diff --git a/CMakeLists.txt b/CMakeLists.txt index e388e0a..6dbcad4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ set(CORE gameManager.cpp game.cpp defConfigs.cpp ${CONSOLE} ${CONTROLLERS}) set(PROJECTILES projectile.cpp) set(FX fx.cpp) set(VEHICLES vehicle.cpp engineer.cpp transport.cpp) -set(STRUCTURES structure.cpp factory.cpp) +set(STRUCTURES structure.cpp factory.cpp pointDefense.cpp) set(UNITS gameObjectFactory.cpp unit.cpp ${STRUCTURES} ${VEHICLES}) set(CONTENT player.cpp pathfinder.cpp map.cpp gameObject.cpp gameObjectFrame.h resourceDeposit.cpp ${UNITS} ${PROJECTILES} ${FX}) set(GAME_SRC ${STATES} ${GUI} ${CORE} ${CONTENT} ${UTIL}) diff --git a/concreteGuiManager.cpp b/concreteGuiManager.cpp index 323f91b..a9b5cb0 100644 --- a/concreteGuiManager.cpp +++ b/concreteGuiManager.cpp @@ -161,6 +161,7 @@ namespace battleship{ break; case LAND_FACTORY_TRAIN: button = new TrainButton(pos, size, name, (int)guiTable["trigger"], (string)guiTable["imagePath"], (int)UnitClass::LAND_FACTORY, (int)guiTable["unitId"]); + break; case NAVAL_FACTORY_TRAIN: button = new TrainButton(pos, size, name, (int)guiTable["trigger"], (string)guiTable["imagePath"], (int)UnitClass::NAVAL_FACTORY, (int)guiTable["unitId"]); break; diff --git a/gameObjectFactory.cpp b/gameObjectFactory.cpp index 8b04477..6836764 100644 --- a/gameObjectFactory.cpp +++ b/gameObjectFactory.cpp @@ -5,6 +5,7 @@ #include "transport.h" #include "projectile.h" #include "resourceDeposit.h" +#include "pointDefense.h" #include "defConfigs.h" #include @@ -28,9 +29,10 @@ namespace battleship{ case UnitClass::LAND_FACTORY: case UnitClass::NAVAL_FACTORY: return new Factory(player, id, pos, rot, buildStatus); + case UnitClass::POINT_DEFENSE: + return new PointDefense(player, id, pos, rot, buildStatus); case UnitClass::MARKET: case UnitClass::LAB: - case UnitClass::POINT_DEFENSE: return new Structure(player, id, pos, rot, buildStatus); default: return new Vehicle(player, id, pos, rot); diff --git a/player.cpp b/player.cpp index 2312583..054a835 100755 --- a/player.cpp +++ b/player.cpp @@ -1,6 +1,7 @@ #include #include "player.h" +#include "structure.h" #include "stateManager.h" #include "activeGameState.h" #include "resourceDeposit.h" @@ -70,15 +71,21 @@ namespace battleship{ targets.push_back(Order::Target()); for (Unit *u : selectedUnits) { - bool targetingSelf = false; + bool targetingSelf = false, structBuilt = true; - for(Order::Target &targ : targets) + for(Order::Target &targ : targets){ if(targ.unit && targ.unit == u){ targetingSelf = true; break; } - if(targetingSelf) continue; + if(!u->isVehicle() && ((Structure*)u)->getBuildStatus() < 100){ + structBuilt = false; + break; + } + } + + if(targetingSelf || !structBuilt) continue; int lineId = -1; ActiveGameState *activeState = ((ActiveGameState*)GameManager::getSingleton()->getStateManager()->getAppStateByType(AppStateType::ACTIVE_STATE)); diff --git a/pointDefense.cpp b/pointDefense.cpp new file mode 100644 index 0000000..463c9b0 --- /dev/null +++ b/pointDefense.cpp @@ -0,0 +1,29 @@ +#include "pointDefense.h" + +namespace battleship{ + using namespace vb01; + + PointDefense::PointDefense(Player *player, int id, Vector3 pos, Quaternion rot, int buildStatus) : Structure(player, id, pos, rot, buildStatus){ + turretDir = dirVec; + } + + void PointDefense::attack(Order order){ + Unit *targUnit = order.targets[0].unit; + Vector3 targDir = ((targUnit ? targUnit->getPos() : order.targets[0].pos) - pos).norm(); + float angleToTarg = targDir.getAngleBetween(turretDir); + + if(angleToTarg > .05) + rotateTurret(calculateRotation(targDir, angleToTarg, .1)); + else if(canFire()) + fire(); + + Unit::attack(order); + } + + void PointDefense::rotateTurret(float angle){ + Node *turretNode = model->getChild(0)->getChild(0); + Quaternion rotQuat = Quaternion(angle, Vector3::VEC_J); + turretNode->setOrientation(rotQuat * turretNode->getOrientation()); + turretDir = rotQuat * turretDir; + } +} diff --git a/pointDefense.h b/pointDefense.h new file mode 100644 index 0000000..b02a176 --- /dev/null +++ b/pointDefense.h @@ -0,0 +1,18 @@ +#ifndef POINT_DEFENSE_H +#define POINT_DEFENSE_H + +#include "structure.h" + +namespace battleship{ + class PointDefense : public Structure{ + public: + PointDefense(Player*, int, vb01::Vector3, vb01::Quaternion, int); + private: + vb01::Vector3 turretDir; + + void attack(Order); + void rotateTurret(float); + }; +} + +#endif diff --git a/structure.h b/structure.h index 94ff898..1a2eea7 100644 --- a/structure.h +++ b/structure.h @@ -12,9 +12,9 @@ namespace battleship{ public: Structure(Player*, int, vb01::Vector3, vb01::Quaternion, int = 0); ~Structure(); + virtual void update(); inline int getBuildStatus(){return buildStatus;} inline void incrementBuildStatus(){buildStatus++;} - virtual void update(); private: int buildStatus = 0; protected: diff --git a/unit.cpp b/unit.cpp index 7baf3d6..3c824a5 100755 --- a/unit.cpp +++ b/unit.cpp @@ -62,6 +62,7 @@ namespace battleship{ rateOfFire = SOL_LUA_STATE["rateOfFire"][id + 1]; range = SOL_LUA_STATE["range"][id + 1]; + damage = SOL_LUA_STATE["damage"][id + 1]; lineOfSight = SOL_LUA_STATE["lineOfSight"][id + 1]; unitClass = (UnitClass)SOL_LUA_STATE["unitClass"][id + 1]; type = (UnitType)SOL_LUA_STATE["unitType"][id + 1]; @@ -131,6 +132,26 @@ namespace battleship{ delete node; } + float Unit::calculateRotation(Vector3 dir, float angle, float maxTurnAngle){ + float rotSpeed = (maxTurnAngle > angle ? angle : maxTurnAngle); + + if(isTargetToTheRight(dir, leftVec)) + rotSpeed *= -1; + + return rotSpeed; + } + + void Unit::fire(){ + fireSfx->play(); + + Unit *targetUnit = orders[0].targets[0].unit; + + if(targetUnit) + targetUnit->takeDamage(damage); + + lastFireTime = getTime(); + } + void Unit::initUnitStats(){ } diff --git a/unit.h b/unit.h index 7e069d9..58452e1 100755 --- a/unit.h +++ b/unit.h @@ -6,6 +6,8 @@ #include #include +#include + #include "gameManager.h" #include "gameObject.h" #include "projectile.h" @@ -81,6 +83,8 @@ namespace battleship{ inline UnitClass getUnitClass() {return unitClass;} inline void takeDamage(int damage) {health -= damage;} inline int getPlayerId() {return playerId;} + inline bool isVehicle(){return gameBase::generateView()["units"]["isVehicle"][id + 1];} + inline bool isTargetToTheRight(vb01::Vector3 dir, vb01::Vector3 lv){return lv.getAngleBetween(dir) > vb01::PI / 2;} private: void updateScreenCoordinates(); void init(); @@ -96,7 +100,7 @@ namespace battleship{ std::vector orders; sf::SoundBuffer *fireSfxBuffer; sf::Sound *fireSfx = nullptr; - int health, maxHealth, cost, id, playerId, lenHpBar = 200, rateOfFire; + int health, damage, maxHealth, cost, id, playerId, lenHpBar = 200, rateOfFire; s64 orderLineDispTime = 0, lastFireTime = 0; float lineOfSight, range; std::vector garrisonSlots; @@ -114,9 +118,12 @@ namespace battleship{ virtual void move(Order){} virtual void patrol(Order){} virtual void launch(Order){} + float calculateRotation(vb01::Vector3, float, float); + virtual void fire(); void removeBar(vb01::Node*); vb01::Node* createBar(vb01::Vector2, vb01::Vector2, vb01::Vector4); void displayUnitStats(vb01::Node*, vb01::Node*, int, int, vb01::Vector2 offset = vb01::Vector2::VEC_ZERO); + inline bool canFire(){return vb01::getTime() - lastFireTime > rateOfFire;} }; } diff --git a/vehicle.cpp b/vehicle.cpp index a7ecffd..d7ada08 100644 --- a/vehicle.cpp +++ b/vehicle.cpp @@ -89,14 +89,6 @@ namespace battleship{ anglePrecision = SOL_LUA_STATE["anglePrecision"][id + 1]; } - float Vehicle::calculateRotation(Vector3 dir, float angle){ - float rotSpeed = (maxTurnAngle > angle ? angle : maxTurnAngle); - - if(leftVec.getAngleBetween(dir) > PI / 2) - rotSpeed *= -1; - - return rotSpeed; - } void Vehicle::navigate(float destOffset){ Vector3 hypVec = (pathPoints[0] - pos); @@ -109,7 +101,7 @@ namespace battleship{ float angle = (destDir != Vector3::VEC_ZERO ? dirVec.getAngleBetween(destDir) : -1); if(angle > anglePrecision && pos.getDistanceFrom(linDest) > destOffset) - turn(calculateRotation(destDir, angle)); + turn(calculateRotation(destDir, angle, maxTurnAngle)); else{ if(pos.getDistanceFrom(linDest) > destOffset){ float dist = pos.getDistanceFrom(linDest); @@ -133,7 +125,7 @@ namespace battleship{ bool destDirWithin = (!orderHasDir || (orderHasDir && angleToOrderDir <= anglePrecision)); if(pathPoints.size() == 1 && !destDirWithin) - turn(calculateRotation(orders[0].direction, angleToOrderDir)); + turn(calculateRotation(orders[0].direction, angleToOrderDir, maxTurnAngle)); if(pathPoints.size() > 1 || (pathPoints.size() == 1 && destDirWithin)){ if(type == UnitType::UNDERWATER && vertDist < 0.5 * height) @@ -290,21 +282,10 @@ namespace battleship{ else pursuingTarget = false; - if(distToTarg <= range && getTime() - lastFireTime > rateOfFire){ + if(distToTarg <= range && canFire()) fire(); - - lastFireTime = getTime(); - } } - void Vehicle::fire(){ - fireSfx->play(); - - Unit *targetUnit = orders[0].targets[0].unit; - - if(targetUnit) - targetUnit->takeDamage(1); - } void Vehicle::toggleSelection(bool selection){ if(!garrisonable) diff --git a/vehicle.h b/vehicle.h index 69ed44e..5cd2031 100644 --- a/vehicle.h +++ b/vehicle.h @@ -28,7 +28,6 @@ namespace battleship{ inline int getNextPatrolPointId(int numPoints) {return patrolPointId == numPoints - 1 ? 0 : patrolPointId + 1;} void enterGarrisonable(); - float calculateRotation(vb01::Vector3, float); void navigateToTarget(float); void halt(); void turn(float); @@ -48,7 +47,6 @@ namespace battleship{ void garrison(Order); void patrol(Order); virtual void initProperties(); - virtual void fire(); }; }