diff --git a/Assets/Scripts/Core/options.lua b/Assets/Scripts/Core/options.lua index 1d78aed..1a072b1 100644 --- a/Assets/Scripts/Core/options.lua +++ b/Assets/Scripts/Core/options.lua @@ -39,6 +39,7 @@ mappings = { {bind = 48, trigger = 84, action = true, bindType = 0, inOptions = false}, {bind = 49, trigger = 89, action = true, bindType = 0, inOptions = false}, {bind = 50, trigger = 85, action = true, bindType = 0, inOptions = false}, + {bind = 51, trigger = 79, action = true, bindType = 0, inOptions = false}, {bind = 7, trigger = 312, action = false, bindType = 2, inOptions = false}, {bind = 8, trigger = 313, action = false, bindType = 2, inOptions = false}, diff --git a/Assets/Scripts/GameObjects/Units/unitData.lua b/Assets/Scripts/GameObjects/Units/unitData.lua index 37a82fc..35505b0 100644 --- a/Assets/Scripts/GameObjects/Units/unitData.lua +++ b/Assets/Scripts/GameObjects/Units/unitData.lua @@ -24,7 +24,7 @@ UnitId = { REFINERY = 21, FORT = 22 } -WeaponClass = {HITSCAN = 0, SHELL = 1, TORPEDO = 2, CRUISE_MISSILE = 3} +WeaponClass = {HITSCAN = 0, SHELL = 1, TORPEDO = 2, CRUISE_MISSILE = 3, HACK = 4} UnitClass = { WAR_MECH = 0, TANK = 1, @@ -122,17 +122,21 @@ units = { garrisonCategory = 2 }, { - weapons = {}, + weapons = { + {type = WeaponClass.HITSCAN, rateOfFire = 2000, fireSfx = PATH .. 'Sounds/Units/WarMechs/fire.ogg', damage = 20, maxRange = 8}, + }, unitClass = UnitClass.ENGINEER, unitType = UnitType.HOVER, armor = {ArmorType.MECHANIC}, isVehicle = true, health = 500, + hackRange = 30, buildTime = 1000, + hackTime = 1000, cost = 500, size = {x = 1, y = 8, z = 13.45}, hitboxOffset = {x = 0, y = 0, z = 0}, - lineOfSight = 5, + lineOfSight = 20, name = 'Engineer', basePath = PATH .. vehiclePrefix .. 'Engineers/', meshPath = 'engineer.xml', diff --git a/activeGameState.cpp b/activeGameState.cpp index 5b07799..4692a9f 100755 --- a/activeGameState.cpp +++ b/activeGameState.cpp @@ -330,6 +330,7 @@ namespace battleship{ unit->setState(state); } + //TODO only allow appropriate orders for units void ActiveGameState::onAction(int bind, bool isPressed) { GameObjectFrameController *ufCtr = GameObjectFrameController::getSingleton(); @@ -445,6 +446,13 @@ namespace battleship{ } break; + case Bind::HACK: + if(isPressed){ + if(gameObjHoveredOn && gameObjHoveredOn->getType() == GameObject::Type::UNIT && gameObjHoveredOn->getPlayer()->getTeam() != mainPlayer->getTeam()) + issueOrder(Order::TYPE::HACK, vector{Order::Target((Unit*)gameObjHoveredOn)}, shiftPressed); + + break; + } case Bind::TOGGLE_SUB: break; case Bind::ZOOM_IN: diff --git a/binds.h b/binds.h index 97c66ac..6e8f14b 100644 --- a/binds.h +++ b/binds.h @@ -53,7 +53,8 @@ namespace battleship{ EJECT_GARRISON, ENABLE_CHASE_STATE, ENABLE_STAND_GROUND_STATE, - ENABLE_HOLD_FIRE_STATE + ENABLE_HOLD_FIRE_STATE, + HACK }; } diff --git a/defConfigs.h b/defConfigs.h index 96afc13..8a74fcd 100755 --- a/defConfigs.h +++ b/defConfigs.h @@ -26,7 +26,7 @@ namespace battleship{ const static int numAppStates = 4; const static int numStaticBinds[numAppStates]{6, 0, 5, 19}; - const static int numConfBinds[numAppStates]{0, 1, 26, 0}; + const static int numConfBinds[numAppStates]{0, 1, 27, 0}; const static int maxStaticBinds = 19; const static int maxConfBinds = 23; const static int numScripts = 5; diff --git a/engineer.cpp b/engineer.cpp index 98d60c7..b2015d8 100644 --- a/engineer.cpp +++ b/engineer.cpp @@ -1,15 +1,52 @@ #include "engineer.h" -#include "map.h" -#include "player.h" +#include "activeGameState.h" #include "structure.h" +#include "player.h" +#include "game.h" +#include "map.h" #include +#include + +#include namespace battleship{ + using namespace std; using namespace vb01; using namespace gameBase; - Engineer::Engineer(Player *player, int id, Vector3 pos, Quaternion rot, Unit::State state) : Vehicle(player, id, pos, rot, state){} + Engineer::Engineer(Player *player, int id, Vector3 pos, Quaternion rot, Unit::State state) : Vehicle(player, id, pos, rot, state){ + hackRange = generateView()["units"][id + 1]["hackRange"]; + + Vector2 size = Vector2(lenHpBar, 10); + hackStatusBackground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(0, 0, 0, 1)); + hackStatusForeground = Unit::createBar(Vector2::VEC_ZERO, size, Vector4(1, 0, 1, 1)); + } + + Engineer::~Engineer(){ + removeBar(hackStatusBackground); + removeBar(hackStatusForeground); + } + + void Engineer::update(){ + Vehicle::update(); + + ActiveGameState *activeState = (ActiveGameState*)GameManager::getSingleton()->getStateManager()->getAppStateByType(AppStateType::ACTIVE_STATE); + Player *mainPlayer = (activeState ? activeState->getPlayer() : nullptr); + + vector selectingPlayers = Unit::getSelectingPlayers(); + bool mainPlayerSelecting = (activeState && find(selectingPlayers.begin(), selectingPlayers.end(), mainPlayer) != selectingPlayers.end()); + + if(hackStatus < 100) + Unit::displayUnitStats(hackStatusForeground, hackStatusBackground, hackStatus, 100, mainPlayer == player && mainPlayerSelecting, Vector2(0, -10)); + else{ + hackStatusBackground->setVisible(false); + hackStatusForeground->setVisible(false); + } + + if(orders.empty() || orders[0].type != Order::TYPE::HACK) + hackStatus = 0; + } void Engineer::build(Order order){ if(pathPoints.empty()){ @@ -38,4 +75,31 @@ namespace battleship{ alignToSurface(); } } + + void Engineer::hack(Order order){ + Unit *targUnit = order.targets[0].unit; + bool withinRange = (targUnit->getPos().getDistanceFrom(pos) < hackRange); + int hackRate = int(generateView()["units"][id + 1]["hackTime"]) / 100; + bool canHack = (getTime() - lastIncrementTime > hackRate); + + if(withinRange && canHack){ + hackStatus++; + pursuingTarget = false; + } + else if(!withinRange){ + hackStatus = 0; + + if(!pursuingTarget){ + preparePathpoints(order, targUnit->getPos()); + pursuingTarget = true; + } + else + navigateToTarget(.9 * hackRange); + } + + if(hackStatus >= 100){ + Game::getSingleton()->changeUnitPlayer(order.targets[0].unit, player); + removeOrder(0); + } + } } diff --git a/engineer.h b/engineer.h index b0082e3..f038591 100644 --- a/engineer.h +++ b/engineer.h @@ -5,16 +5,26 @@ #include "vehicle.h" +namespace vb01{ + class Node; +} + namespace battleship{ class Structure; class Engineer : public Vehicle{ public: Engineer(Player*, int, vb01::Vector3, vb01::Quaternion, Unit::State); - void build(Order); + ~Engineer(); + void update(); private: + int hackStatus = 0; + float hackRange; vb01::s64 lastIncrementTime = 0; - int buildRate = 100; + vb01::Node *hackStatusBackground = nullptr, *hackStatusForeground = nullptr; + + void build(Order); + void hack(Order); }; } diff --git a/game.cpp b/game.cpp index bed889a..24bfef0 100644 --- a/game.cpp +++ b/game.cpp @@ -197,4 +197,21 @@ namespace battleship{ fx.activate(); addFx(fx); } + + void Game::changeUnitPlayer(Unit *unit, Player *newPlayer){ + Player *oldPlayer = unit->getPlayer(); + vector &oldPlayerUnits = oldPlayer->getUnits(); + int oldId = -1; + + for(int i = 0; i < oldPlayerUnits.size(); i++) + if(oldPlayerUnits[i] == unit){ + oldId = i; + break; + } + + oldPlayerUnits.erase(oldPlayerUnits.begin() + oldId); + newPlayer->addUnit(unit); + unit->setPlayer(newPlayer); + unit->halt(); + } } diff --git a/game.h b/game.h index 445ec22..cb9c575 100644 --- a/game.h +++ b/game.h @@ -10,6 +10,7 @@ namespace sf{ } namespace battleship{ + class Unit; class Player; class Projectile; @@ -21,6 +22,7 @@ namespace battleship{ void removeFx(int, bool); void removeAllElements(); void explode(vb01::Vector3, int, float, sf::Sound*); + void changeUnitPlayer(Unit*, Player*); inline void addFx(Fx f){fx.push_back(f);} inline void addPlayer(Player *pl){players.push_back(pl);} inline std::vector& getPlayers(){return players;} diff --git a/gameObject.h b/gameObject.h index 03da68b..62611f4 100644 --- a/gameObject.h +++ b/gameObject.h @@ -39,6 +39,7 @@ namespace battleship{ inline float getHeight() {return height;} inline float getLength() {return length;} inline vb01::Model* getModel() {return model;} + inline void setPlayer(Player *pl){player = pl;} inline Player* getPlayer(){return player;} inline void toggleDebugging(bool d){this->debugging=d;} inline vb01::Vector3 getDirVec() {return dirVec;} diff --git a/player.cpp b/player.cpp index 9b0a223..26faa92 100755 --- a/player.cpp +++ b/player.cpp @@ -55,6 +55,9 @@ namespace battleship{ case Order::TYPE::SUPPLY: color = Vector3(1, 1, 0); break; + case Order::TYPE::HACK: + color = Vector3(1, 0, 1); + break; } LineRenderer *lineRenderer = LineRenderer::getSingleton(); diff --git a/unit.cpp b/unit.cpp index a7a2f63..f111577 100755 --- a/unit.cpp +++ b/unit.cpp @@ -388,6 +388,9 @@ namespace battleship{ case Order::TYPE::SUPPLY: supply(order); break; + case Order::TYPE::HACK: + hack(order); + break; default: break; } diff --git a/unit.h b/unit.h index 1f6c007..2052d9e 100755 --- a/unit.h +++ b/unit.h @@ -35,7 +35,7 @@ namespace battleship{ class Engineer; struct Order { - enum class TYPE {ATTACK, BUILD, MOVE, GARRISON, EJECT, PATROL, LAUNCH, SUPPLY}; + enum class TYPE {ATTACK, BUILD, MOVE, GARRISON, EJECT, PATROL, LAUNCH, SUPPLY, HACK}; struct Target{ Unit *unit = nullptr; vb01::Vector3 pos; @@ -81,7 +81,7 @@ namespace battleship{ public: class Weapon{ public: - enum class Type{HITSCAN, SHELL, TORPEDO, CRUISE_MISSILE}; + enum class Type{HITSCAN, SHELL, TORPEDO, CRUISE_MISSILE, HACK}; Weapon(Unit*, sol::table); ~Weapon(); @@ -190,6 +190,7 @@ namespace battleship{ virtual void patrol(Order){} virtual void launch(Order); virtual void supply(Order){} + virtual void hack(Order){} float calculateRotation(vb01::Vector3, float, float); void removeBar(vb01::Node*); vb01::Node* createBar(vb01::Vector2, vb01::Vector2, vb01::Vector4); diff --git a/vehicle.h b/vehicle.h index 15a34ec..6794d7b 100644 --- a/vehicle.h +++ b/vehicle.h @@ -19,7 +19,6 @@ namespace battleship{ inline int getGarrisonCategory(){return garrisonCategory;} private: Unit *garrisonable = nullptr; - bool pursuingTarget = false; int patrolPointId = 0, garrisonCategory; float speed, maxTurnAngle, anglePrecision; vb01::Material *debugMat = nullptr; @@ -27,7 +26,6 @@ namespace battleship{ inline int getNextPatrolPointId(int numPoints) {return patrolPointId == numPoints - 1 ? 0 : patrolPointId + 1;} void enterGarrisonable(); - void navigateToTarget(float); void halt(); void turn(float); void addOrder(Order); @@ -38,8 +36,10 @@ namespace battleship{ void select(); protected: std::vector pathPoints; + bool pursuingTarget = false; void navigate(float = 0.); + void navigateToTarget(float); void preparePathpoints(Order&, vb01::Vector3, bool = false); void alignToSurface(); void attack(Order);