diff --git a/activeGameState.cpp b/activeGameState.cpp index cb2ddd7..ee726ff 100755 --- a/activeGameState.cpp +++ b/activeGameState.cpp @@ -343,8 +343,18 @@ namespace battleship{ bool canSelect = canSelectHoveredOnGameObj(); bool ownGameObj = (gameObjHoveredOn && gameObjHoveredOn->getPlayer()->getTeam() == mainPlayer->getTeam()); - if(gameObjHoveredOn && (gameObjHoveredOn->getType() == GameObject::Type::UNIT && ((Unit*)gameObjHoveredOn)->getNumGarrisonSlots() > 0 && ownGameObj)) - issueOrder(Order::TYPE::GARRISON, vector{Order::Target((Unit*)gameObjHoveredOn, gameObjHoveredOn->getPos())}, shiftPressed); + if(gameObjHoveredOn && (gameObjHoveredOn->getType() == GameObject::Type::UNIT && ownGameObj)){ + bool canGarrison = true; + + for(int i = 0; i < mainPlayer->getNumSelectedUnits(); i++) + if(!((Unit*)gameObjHoveredOn)->canGarrison((Vehicle*)mainPlayer->getSelectedUnit(i))){ + canGarrison = false; + break; + } + + if(canGarrison) + issueOrder(Order::TYPE::GARRISON, vector{Order::Target((Unit*)gameObjHoveredOn, gameObjHoveredOn->getPos())}, shiftPressed); + } else if(gameObjHoveredOn && (controlPressed || !ownGameObj)) issueOrder(Order::TYPE::ATTACK, vector{Order::Target((Unit*)gameObjHoveredOn, gameObjHoveredOn->getPos())}, shiftPressed); else if(controlPressed && !gameObjHoveredOn){ diff --git a/pathfinder.cpp b/pathfinder.cpp index fbe8f41..29254e8 100644 --- a/pathfinder.cpp +++ b/pathfinder.cpp @@ -60,15 +60,13 @@ namespace battleship{ if((ship && cells[vertStrich].type != Map::Cell::WATER) || ((UnitType)unitType == UnitType::LAND && cells[vertStrich].type != Map::Cell::LAND)) canMoveToStrichCell = false; - if(canMoveToStrichCell){ - int edgeNode = cells[vertStrich].edges[i].destCellId; - bool isChecked = cellsByCheck[edgeNode].second; + int edgeNode = cells[vertStrich].edges[i].destCellId, cellTypeFactor = (canMoveToStrichCell ? 1 : 100); + bool isChecked = cellsByCheck[edgeNode].second; - if(!isChecked && (distances[vertStrich] + cells[vertStrich].edges[i].weight < distances[edgeNode])){ - distances[edgeNode] = distances[vertStrich] + cells[vertStrich].edges[i].weight; - paths[edgeNode] = paths[vertStrich]; - paths[edgeNode].push_back(edgeNode); - } + if(!isChecked && (distances[vertStrich] + cells[vertStrich].edges[i].weight * cellTypeFactor < distances[edgeNode])){ + distances[edgeNode] = distances[vertStrich] + cells[vertStrich].edges[i].weight * cellTypeFactor; + paths[edgeNode] = paths[vertStrich]; + paths[edgeNode].push_back(edgeNode); } } } diff --git a/unit.cpp b/unit.cpp index ca2b6c7..5abc271 100755 --- a/unit.cpp +++ b/unit.cpp @@ -54,7 +54,8 @@ namespace battleship{ void Unit::initProperties(){ GameObject::initProperties(); - sol::table SOL_LUA_STATE = generateView()[GameObject::getGameObjTableName()]; + sol::state_view SOL_LUA_VIEW = generateView(); + sol::table SOL_LUA_STATE = SOL_LUA_VIEW[GameObject::getGameObjTableName()]; string name = SOL_LUA_STATE["name"][id + 1]; health = SOL_LUA_STATE["health"][id + 1]; maxHealth = health; @@ -65,16 +66,18 @@ namespace battleship{ lineOfSight = SOL_LUA_STATE["lineOfSight"][id + 1]; unitClass = (UnitClass)SOL_LUA_STATE["unitClass"][id + 1]; type = (UnitType)SOL_LUA_STATE["unitType"][id + 1]; - int capacity = SOL_LUA_STATE["garrisonCapacity"][id + 1]; - for(int i = 0; i < capacity; i++){ + SOL_LUA_VIEW.script("numGarrisonSlots = #units.garrisonCapacity[" + to_string(id + 1) + "]"); + int numGarrisonSlots = SOL_LUA_VIEW["numGarrisonSlots"]; + + for(int i = 0; i < numGarrisonSlots; i++){ Vector2 size = 10 * Vector2::VEC_IJ; Vector2 pos = Vector2(1.5 * size.x * i, 20); Node *bg = createBar(pos, size, Vector4(0, 0, 0, 1)); Node *fg = createBar(pos, size, Vector4(0, 1, 0, 1)); - garrisonSlots.push_back(GarrisonSlot(bg, fg, pos)); + int category = SOL_LUA_STATE["garrisonCapacity"][id + 1][i + 1]; + garrisonSlots.push_back(GarrisonSlot(bg, fg, pos, category)); } - } void Unit::destroySound(){ @@ -109,6 +112,14 @@ namespace battleship{ orientAt(rot); } + bool Unit::canGarrison(Vehicle *vehicle){ + for(int i = 0; i < garrisonSlots.size(); i++) + if(!garrisonSlots[i].vehicle && garrisonSlots[i].category >= vehicle->getGarrisonCategory()) + return true; + + return false; + } + Node* Unit::createBar(Vector2 pos, Vector2 size, Vector4 color){ Root *root = Root::getSingleton(); Material *mat = new Material(root->getLibPath() + "gui"); @@ -189,17 +200,17 @@ namespace battleship{ Player *mainPlayer = (activeState ? activeState->getPlayer() : nullptr); vector selectingPlayers = getSelectingPlayers(); - bool mainPlayerSelecting = find(selectingPlayers.begin(), selectingPlayers.end(), mainPlayer) != selectingPlayers.end(); - bool ownerSelecting = (mainPlayer == player && mainPlayerSelecting); + bool mainPlayerSelecting = (find(selectingPlayers.begin(), selectingPlayers.end(), mainPlayer) != selectingPlayers.end()); + bool mainPlayerOwner = (player == mainPlayer); + bool renderSelectables = (mainPlayer && mainPlayerOwner); - renderOrderLine(ownerSelecting); + renderOrderLine(renderSelectables); executeOrders(); displayUnitStats(hpForegroundNode, hpBackgroundNode, health, maxHealth, mainPlayerSelecting); - if(ownerSelecting) - for(GarrisonSlot &slot : garrisonSlots) - displayUnitStats(slot.foreground, slot.background, (int)((bool)slot.vehicle), (int)true, mainPlayerSelecting, slot.offset); + for(GarrisonSlot &slot : garrisonSlots) + displayUnitStats(slot.foreground, slot.background, (int)((bool)slot.vehicle), (int)true, renderSelectables, slot.offset); if (health <= DEATH_HP) blowUp(); diff --git a/unit.h b/unit.h index 0a8cf9e..62a44c9 100755 --- a/unit.h +++ b/unit.h @@ -62,10 +62,11 @@ namespace battleship{ public: struct GarrisonSlot{ Vehicle *vehicle = nullptr; + int category; vb01::Node *background, *foreground; vb01::Vector2 offset; - GarrisonSlot(vb01::Node *bg, vb01::Node *fg, vb01::Vector2 off, Vehicle *v = nullptr) : background(bg), foreground(fg), offset(off), vehicle(v){} + GarrisonSlot(vb01::Node *bg, vb01::Node *fg, vb01::Vector2 off, int cat, Vehicle *v = nullptr) : background(bg), foreground(fg), offset(off), category(cat), vehicle(v){} }; Unit(Player*, int, vb01::Vector3, vb01::Quaternion); @@ -79,6 +80,7 @@ namespace battleship{ std::vector getProjectiles(); virtual void addOrder(Order); virtual void reinit(); + bool canGarrison(Vehicle*); inline Engineer* toEngineer(){return (Engineer*)this;} inline Transport* toTransport(){return (Transport*)this;} inline Factory* toFactory(){return (Factory*)this;} diff --git a/vehicle.cpp b/vehicle.cpp index b35a51d..77837e5 100644 --- a/vehicle.cpp +++ b/vehicle.cpp @@ -49,7 +49,7 @@ namespace battleship{ if(order.type != Order::TYPE::EJECT){ Order::Target targ = order.targets[0]; Vector3 targPos = (targ.unit ? targ.unit->getPos() : targ.pos); - preparePathpoints(targPos); + preparePathpoints(order, targPos); if(!pathPoints.empty()) orders.push_back(order); @@ -87,6 +87,7 @@ namespace battleship{ maxTurnAngle = SOL_LUA_STATE["maxTurnAngle"][id + 1]; speed = SOL_LUA_STATE["speed"][id + 1]; anglePrecision = SOL_LUA_STATE["anglePrecision"][id + 1]; + garrisonCategory = SOL_LUA_STATE["garrisonCategory"][id + 1]; } @@ -184,7 +185,7 @@ namespace battleship{ void Vehicle::navigateToTarget(float minDist){ if(!pursuingTarget){ Vector3 targPos = (orders[0].targets[0].unit ? orders[0].targets[0].unit->getPos() : orders[0].targets[0].pos); - preparePathpoints(targPos); + preparePathpoints(orders[0], targPos); pursuingTarget = true; if(orders[0].type == Order::TYPE::GARRISON) addPathpoint(targPos); @@ -195,7 +196,7 @@ namespace battleship{ void Vehicle::garrison(Order order){ Unit *targUnit = order.targets[0].unit; - float distToGarrisonable = pos.getDistanceFrom(targUnit->getPos()), garrisonDist = .1; + float distToGarrisonable = pos.getDistanceFrom(targUnit->getPos()), garrisonDist = .5 * Map::getSingleton()->getCellSize().x; if(distToGarrisonable > garrisonDist) navigateToTarget(garrisonDist); @@ -206,7 +207,7 @@ namespace battleship{ void Vehicle::patrol(Order order){ if(pathPoints.empty()){ patrolPointId = getNextPatrolPointId(order.targets.size()); - preparePathpoints(order.targets[patrolPointId].pos); + preparePathpoints(order, order.targets[patrolPointId].pos); } navigate(.5 * Map::getSingleton()->getCellSize().x); @@ -226,25 +227,31 @@ namespace battleship{ debugPathPoints.push_back(n); } - void Vehicle::preparePathpoints(Vector3 destPos){ + void Vehicle::preparePathpoints(Order &order, Vector3 destPos){ removeAllPathpoints(); Map *map = Map::getSingleton(); vector &cells = map->getCells(); int source = map->getCellId(pos); - int dest = map->getCellId(destPos); + bool ship = (type == UnitType::UNDERWATER || type == UnitType::SEA_LEVEL); + bool waterVehCanMove = (ship && cells[source].type == Map::Cell::WATER); + bool landVehCanMove = (type == UnitType::LAND && cells[source].type == Map::Cell::LAND); - if(type == UnitType::UNDERWATER || type == UnitType::SEA_LEVEL || type == UnitType::LAND){ - Map::Cell::Type cellType = (type == UnitType::LAND ? Map::Cell::LAND : Map::Cell::WATER); - bool canReach = (cells[source].type == cellType && cells[dest].type == cellType); - - if(!canReach) return; - } + if(!(waterVehCanMove || landVehCanMove)) return; Pathfinder *pathfinder = Pathfinder::getSingleton(); + int dest = map->getCellId(destPos); vector path = pathfinder->findPath(cells, source, dest, (int)type); + for(int i = 0; i < path.size(); i++) + if((ship && cells[path[i]].type != Map::Cell::WATER) || (type == UnitType::LAND && cells[path[i]].type != Map::Cell::LAND)){ + path = vector(path.begin(), path.begin() + i); + order.targets[0].unit = nullptr; + order.targets[0].pos = cells[path[i - 1]].pos; + break; + } + for(int p : path) addPathpoint(cells[p].pos); } diff --git a/vehicle.h b/vehicle.h index 2c5fe2b..9c4c0af 100644 --- a/vehicle.h +++ b/vehicle.h @@ -8,8 +8,6 @@ namespace vb01{ } namespace battleship{ - class Garrisonable; - class Vehicle : public Unit{ public: Vehicle(Player*, int, vb01::Vector3, vb01::Quaternion); @@ -18,10 +16,11 @@ namespace battleship{ void move(Order); void exitGarrisonable(); inline Unit* getGarrisonable(){return garrisonable;} + inline int getGarrisonCategory(){return garrisonCategory;} private: Unit *garrisonable = nullptr; bool pursuingTarget = false; - int patrolPointId = 0; + int patrolPointId = 0, garrisonCategory; float speed, maxTurnAngle, anglePrecision; vb01::Material *debugMat = nullptr; std::vector debugPathPoints; @@ -34,7 +33,7 @@ namespace battleship{ void addOrder(Order); void advance(float, MoveDir = MoveDir::FORW); void addPathpoint(vb01::Vector3); - void preparePathpoints(vb01::Vector3); + void preparePathpoints(Order&, vb01::Vector3); void removePathpoint(int = 0); void removeAllPathpoints(); void select();