From 8e47df2597415bf55b80a45c5bc53424aa0fc86d Mon Sep 17 00:00:00 2001 From: devZoGok Date: Sun, 22 Oct 2023 12:03:07 +0300 Subject: [PATCH] implemented garrisoned unit ejection --- activeGameState.cpp | 24 +++++++++++---- engineer.cpp | 2 +- unit.cpp | 27 ++++++++++++++--- unit.h | 7 +++-- vehicle.cpp | 73 ++++++++++++++++++++++++++------------------- vehicle.h | 10 +++++-- 6 files changed, 96 insertions(+), 47 deletions(-) diff --git a/activeGameState.cpp b/activeGameState.cpp index b784862..ca07fb9 100755 --- a/activeGameState.cpp +++ b/activeGameState.cpp @@ -220,6 +220,7 @@ namespace battleship{ dragboxNode->setPosition(Vector3(selectionBoxOrigin.x, selectionBoxOrigin.y, 0)); } + //TODO fix ejectable unit selection with multiple transports selected void ActiveGameState::issueOrder(Order::TYPE type, bool addOrder) { Vector3 color; @@ -241,11 +242,23 @@ namespace battleship{ break; } - targets.push_back(Order::Target()); - - if(type == Order::TYPE::PATROL) + if(type == Order::TYPE::PATROL){ for(int i = targets.size() - 2; i >= 0; i--) targets[i + 1] = targets[i]; + } + else if(type == Order::TYPE::EJECT){ + vector units = mainPlayer->getSelectedUnits(); + + for(Unit *u : units){ + const vector &garrisonSlots = u->getGarrisonSlots(); + + for(Unit::GarrisonSlot slot : garrisonSlots) + if(slot.vehicle) + targets.push_back(Order::Target((Unit*)slot.vehicle)); + } + } + else + targets.push_back(Order::Target()); LineRenderer *lineRenderer = LineRenderer::getSingleton(); Order order; @@ -396,8 +409,9 @@ namespace battleship{ CameraController::getSingleton()->setLookingAround(isPressed); break; case Bind::HALT: - for (Unit *u : mainPlayer->getSelectedUnits()) - u->halt(); + if(isPressed) + for (Unit *u : mainPlayer->getSelectedUnits()) + u->halt(); break; //TODO reimplement submarine diving mechanic case Bind::LEFT_CONTROL: diff --git a/engineer.cpp b/engineer.cpp index 433af48..bb84c6e 100644 --- a/engineer.cpp +++ b/engineer.cpp @@ -26,7 +26,7 @@ namespace battleship{ } } else{ - navigate(order, 0.5 * Map::getSingleton()->getCellSize().x); + navigate(0.5 * Map::getSingleton()->getCellSize().x); if(type == UnitType::LAND) alignToSurface(); diff --git a/unit.cpp b/unit.cpp index 60c4bd1..d79f38c 100755 --- a/unit.cpp +++ b/unit.cpp @@ -14,6 +14,7 @@ #include "unit.h" #include "util.h" #include "game.h" +#include "vehicle.h" #include "inGameAppState.h" #include "defConfigs.h" #include "pathfinder.h" @@ -216,6 +217,7 @@ namespace battleship{ } } + //TODO remove order argument from action methods void Unit::executeOrders() { if (orders.size() > 0) { Order order = orders[0]; @@ -233,6 +235,9 @@ namespace battleship{ case Order::TYPE::GARRISON: garrison(order); break; + case Order::TYPE::EJECT: + eject(order); + break; case Order::TYPE::PATROL: patrol(order); break; @@ -245,6 +250,15 @@ namespace battleship{ } } + void Unit::eject(Order order){ + if(garrisonSlots.size() > 0){ + for(Order::Target targ : order.targets) + ((Vehicle*)targ.unit)->exitGarrisonable(); + + removeOrder(0); + } + } + void Unit::setOrder(Order order) { while (!orders.empty()) removeOrder(0); @@ -258,12 +272,17 @@ namespace battleship{ removeOrder(orders.size() - 1); } - void Unit::updateGarrison(Vehicle *garrison){ - for(GarrisonSlot &slot : garrisonSlots) - if(!slot.vehicle){ - slot.vehicle = garrison; + void Unit::updateGarrison(Vehicle *garrVeh, bool entering){ + for(GarrisonSlot &slot : garrisonSlots){ + if(entering && !slot.vehicle){ + slot.vehicle = garrVeh; break; } + else if(!entering && slot.vehicle == garrVeh){ + slot.vehicle = nullptr; + break; + } + } } void Unit::addOrder(Order order){ diff --git a/unit.h b/unit.h index cb26e4b..ba89a46 100755 --- a/unit.h +++ b/unit.h @@ -34,7 +34,7 @@ namespace battleship{ vb01::Vector3 pos; Target(){} - Target(Unit *u, vb01::Vector3 p) : unit(u), pos(p){} + Target(Unit *u, vb01::Vector3 p = vb01::Vector3::VEC_ZERO) : unit(u), pos(p){} }; TYPE type; @@ -65,12 +65,13 @@ namespace battleship{ virtual void update(); virtual void blowUp(); virtual void halt(); - void updateGarrison(Vehicle*); + void updateGarrison(Vehicle*, bool); virtual void toggleSelection(bool); void setOrder(Order); std::vector getProjectiles(); virtual void addOrder(Order); virtual void reinit(); + inline const std::vector& getGarrisonSlots(){return garrisonSlots;} inline vb01::Vector3 getCorner(int i){return corners[i];} inline vb01::Vector2 getScreenPos(){return screenPos;} inline vb01::Vector3* getPosPtr() {return &pos;} @@ -108,9 +109,9 @@ namespace battleship{ virtual void initSound(); virtual void initUnitStats(); virtual void executeOrders(); + virtual void eject(Order); virtual void attack(Order){} virtual void garrison(Order){} - virtual void eject(Order){} virtual void build(Order){} virtual void move(Order){} virtual void patrol(Order){} diff --git a/vehicle.cpp b/vehicle.cpp index f87894b..8d38a97 100644 --- a/vehicle.cpp +++ b/vehicle.cpp @@ -36,7 +36,7 @@ namespace battleship{ void Vehicle::update(){ Unit::update(); - model->setVisible(!garrisoned); + model->setVisible(!garrisonable); } void Vehicle::halt(){ @@ -48,9 +48,13 @@ namespace battleship{ } void Vehicle::addOrder(Order order){ - preparePathpoints(order); + if(order.type != Order::TYPE::EJECT){ + preparePathpoints(order); - if(!pathPoints.empty()) + if(!pathPoints.empty()) + orders.push_back(order); + } + else orders.push_back(order); } @@ -85,7 +89,7 @@ namespace battleship{ anglePrecision = SOL_LUA_STATE["anglePrecision"][id + 1]; } - void Vehicle::navigate(Order order, float destOffset){ + void Vehicle::navigate(float destOffset){ Vector3 hypVec = (pathPoints[0] - pos); float hypAngle = hypVec.norm().getAngleBetween(upVec) - PI / 2; float offset = hypVec.getLength() * sin(hypAngle); @@ -146,7 +150,7 @@ namespace battleship{ } void Vehicle::move(Order order) { - navigate(order, 0.5 * Map::getSingleton()->getCellSize().x); + navigate(0.5 * Map::getSingleton()->getCellSize().x); if(type == UnitType::LAND) alignToSurface(); @@ -155,28 +159,41 @@ namespace battleship{ removeOrder(0); } + void Vehicle::exitGarrisonable(){ + placeAt(garrisonable->getPos()); + garrisonable->updateGarrison(this, false); + garrisonable = nullptr; + } + + void Vehicle::enterGarrisonable(){ + Unit *targUnit = orders[0].targets[0].unit; + targUnit->updateGarrison(this, true); + + removeAllPathpoints(); + removeOrder(0); + + garrisonable = targUnit; + pursuingTarget = false; + } + + void Vehicle::navigateToMovingTarget(float minDist){ + if(!pursuingTarget){ + preparePathpoints(orders[0]); + pursuingTarget = true; + } + + navigate(minDist); + } + void Vehicle::garrison(Order order){ float garrisonDist = 1.25 * Map::getSingleton()->getCellSize().x; Unit *targUnit = order.targets[0].unit; float distToGarrisonable = pos.getDistanceFrom(targUnit->getPos()); - if(distToGarrisonable > garrisonDist){ - if(!pursuingTarget){ - preparePathpoints(order); - pursuingTarget = true; - } - - navigate(order, garrisonDist); - } - else{ - targUnit->updateGarrison(this); - - removeAllPathpoints(); - removeOrder(0); - - garrisoned = true; - pursuingTarget = false; - } + if(distToGarrisonable > garrisonDist) + navigateToMovingTarget(garrisonDist); + else + enterGarrisonable(); } //TODO add hover unit type @@ -241,14 +258,8 @@ namespace battleship{ float distToTarg = pos.getDistanceFrom(target.unit ? target.unit->getPos() : target.pos); float minDist = range; - if(distToTarg > minDist){ - if(!pursuingTarget){ - preparePathpoints(order); - pursuingTarget = true; - } - - navigate(order, .5 * Map::getSingleton()->getCellSize().x); - } + if(distToTarg > minDist) + navigateToMovingTarget(.5 * Map::getSingleton()->getCellSize().x); else{ pursuingTarget = false; @@ -270,7 +281,7 @@ namespace battleship{ } void Vehicle::toggleSelection(bool selection){ - if(!garrisoned) + if(!garrisonable) Unit::toggleSelection(selection); } } diff --git a/vehicle.h b/vehicle.h index 1f045b3..a787b13 100644 --- a/vehicle.h +++ b/vehicle.h @@ -16,15 +16,19 @@ namespace battleship{ ~Vehicle(); virtual void update(); void move(Order); - bool isGarrisoned(){return garrisoned;} + void exitGarrisonable(); + inline Unit* getGarrisonable(){return garrisonable;} private: - bool pursuingTarget = false, garrisoned = false; + Unit *garrisonable = nullptr; + bool pursuingTarget = false; int patrolPointId = 0; float speed, maxTurnAngle, anglePrecision; vb01::Material *debugMat = nullptr; std::vector debugPathPoints; inline int getNextPatrolPointId(int numPoints) {return patrolPointId == numPoints - 1 ? 0 : patrolPointId + 1;} + void enterGarrisonable(); + void navigateToMovingTarget(float); void halt(); void turn(float); void addOrder(Order); @@ -36,7 +40,7 @@ namespace battleship{ protected: std::vector pathPoints; - void navigate(Order, float = 0.); + void navigate(float = 0.); void alignToSurface(); void attack(Order); void garrison(Order);