From 3fda274bb11510a23e9f86094d1853c25eb0b7f8 Mon Sep 17 00:00:00 2001 From: devZoGok Date: Tue, 21 Oct 2025 20:33:37 +0300 Subject: [PATCH] aligning different units to hilly surfaces code refactoring bugfix for units moving by terrain along Z axis code cleanup --- Assets/Scripts/GameObjects/Units/unitData.lua | 11 +- defConfigs.h | 2 +- mapEditorAppState.h | 1 - unit.cpp | 16 ++- unit.h | 2 +- vehicle.cpp | 129 ++++-------------- vehicle.h | 2 +- 7 files changed, 50 insertions(+), 113 deletions(-) diff --git a/Assets/Scripts/GameObjects/Units/unitData.lua b/Assets/Scripts/GameObjects/Units/unitData.lua index 510d486..fe6b1d4 100644 --- a/Assets/Scripts/GameObjects/Units/unitData.lua +++ b/Assets/Scripts/GameObjects/Units/unitData.lua @@ -171,7 +171,7 @@ units = { orderType = OrderType.ATTACK, rateOfFire = 1000, damage = 200, - maxRange = 25, + maxRange = 50, horizontalNode = {name = 'Turret', rotationSpeed = .05, maxFireAngle = .1}, projectile = {id = ProjectileId.HE_SHELL, parent = 'Turret', pos = {x = 0.06, y = 5.82, z = 11.4}, rot = {w = 1, x = 0, y = 0, z = 0}}, fireFx = { @@ -201,6 +201,7 @@ units = { unitType = UnitType.LAND, armor = {ArmorType.STEEL}, isVehicle = true, + alignToSurface = true, health = 500, buildTime = 1000, cost = 500, @@ -213,7 +214,7 @@ units = { albedoPath = 'tank.jpg', colorNodes = {'Antenna_S', 'Antenna_L', 'Hatch'}, selectionSfx = PATH .. 'Sounds/Units/Tanks/selection.ogg', - speed = .1, + speed = .4, destinationOffset = .1, anglePrecision = .1, maxTurnAngle = .1, @@ -254,6 +255,7 @@ units = { unitClass = UnitClass.ARTILLERY, unitType = UnitType.LAND, armor = {ArmorType.MECHANIC}, + alignToSurface = true, isVehicle = true, health = 500, buildTime = 1000, @@ -267,7 +269,7 @@ units = { albedoPath = 'artillery.jpg', colorNodes = {'turret'}, selectionSfx = PATH .. 'Sounds/Units/Tanks/selection.ogg', - speed = .1, + speed = .3, destinationOffset = .1, anglePrecision = .1, maxTurnAngle = .1, @@ -322,6 +324,7 @@ units = { { unitClass = UnitClass.TRANSPORT, unitType = UnitType.HOVER, + alignToSurface = true, isVehicle = true, health = 500, buildTime = 1000, @@ -348,6 +351,7 @@ units = { unitClass = UnitClass.TRANSPORT, unitType = UnitType.HOVER, armor = {ArmorType.MECHANIC}, + alignToSurface = true, isVehicle = true, health = 500, buildTime = 1000, @@ -379,6 +383,7 @@ units = { unitClass = UnitClass.RESOURCE_ROVER, unitType = UnitType.HOVER, armor = {ArmorType.CAST}, + alignToSurface = true, capacity = 3000, loadRate = 1, loadSpeed = 5, diff --git a/defConfigs.h b/defConfigs.h index 616bcd7..b0a5fc1 100755 --- a/defConfigs.h +++ b/defConfigs.h @@ -21,7 +21,7 @@ namespace battleship{ const std::string DEFAULT_TEXTURE = "Textures/defaultTexture.jpg"; const double camPanSpeed = .5, CAMERA_DISTANCE = 100, CAMERA_ZOOM_INCREMENT = 1, cellLength = 7, cellWidth = 7, cellDepth = 7, DIST_FROM_RAY = 15; - const int maxNumGroups = 10, NUM_MAX_ZOOMS = 75; + const int maxNumGroups = 10, NUM_MAX_ZOOMS = 75, NUM_SUBDIVS = 100; const vb01::u32 IMPASS_NODE_VAL = 65535; const static int numAppStates = 5; diff --git a/mapEditorAppState.h b/mapEditorAppState.h index cb3d041..64281e0 100644 --- a/mapEditorAppState.h +++ b/mapEditorAppState.h @@ -72,7 +72,6 @@ namespace battleship{ float *oldLandmassVertHeights = nullptr; bool pushing = false, movingTerrainObject = false, scalingTerrainObject = false, weightsGenerated = false, newMap, cellMarkersVisible = false; const float MIN_RADIUS = 1, MAX_RADIUS = 100, INCREASE_RATE = 1; - const int NUM_SUBDIVS = 100; float circleRadius = MIN_RADIUS, guiThreshold = 200; vb01::Vector3 pushPos = vb01::Vector3::VEC_ZERO; std::vector skyTextures, landmassTextures, waterTextures; diff --git a/unit.cpp b/unit.cpp index 901deb2..3c9142b 100755 --- a/unit.cpp +++ b/unit.cpp @@ -71,6 +71,7 @@ namespace battleship{ vector currTechs = player->getTechnologies(); string name = unitTable["name"]; + alignToSurface = unitTable["alignToSurface"].get_or(false); vehicle = unitTable["isVehicle"]; health += game->calcAbilFromTech(Ability::Type::HEALTH, currTechs, (int)GameObject::type, id); maxHealth = unitTable["health"]; @@ -515,12 +516,17 @@ namespace battleship{ void Unit::placeAt(Vector3 p){ Map *map = Map::getSingleton(); - if(type == UnitType::LAND){ - vector res = RayCaster::cast(Vector3(p.x, 100, p.z), -Vector3::VEC_J, vector{map->getNodeParent()->getChild(0)}, 0, 20); - float angle = upVec.getAngleBetween(res[0].norm); + if(alignToSurface){ + vector res = RayCaster::cast(Vector3(p.x, 100, p.z), -Vector3::VEC_J, map->getNodeParent()->getChildren(), 0, 20); + + if(res.empty() || res[0].mesh->getNode() != map->getNodeParent()->getChild(0)) + model->lookAt(Vector3(dirVec.x, 0, dirVec.z).norm(), Vector3::VEC_J); + else if(res[0].mesh->getNode() == map->getNodeParent()->getChild(0)){ + float angle = upVec.getAngleBetween(res[0].norm); - if(angle > 0) - model->lookAt(leftVec.cross(res[0].norm), res[0].norm); + if(angle > 0) + model->lookAt(leftVec.cross(res[0].norm), res[0].norm); + } } ActiveGameState *activeState = (ActiveGameState*)GameManager::getSingleton()->getStateManager()->getAppStateByType(AppStateType::ACTIVE_STATE); diff --git a/unit.h b/unit.h index 958692f..d9dca9f 100755 --- a/unit.h +++ b/unit.h @@ -159,7 +159,7 @@ namespace battleship{ sf::SoundBuffer *selectionSfxBuffer; sf::Sound *selectionSfx = nullptr; vb01::Node *hpBackgroundNode = nullptr, *hpForegroundNode = nullptr, *losLightNode = nullptr; - bool vehicle, currOrderStarted = false; + bool vehicle, currOrderStarted = false, alignToSurface = false; Condition condition = Condition::ABLE; protected: UnitClass unitClass; diff --git a/vehicle.cpp b/vehicle.cpp index 5b45afa..ee9faab 100644 --- a/vehicle.cpp +++ b/vehicle.cpp @@ -10,6 +10,7 @@ #include #include "pathfinder.h" +#include "defConfigs.h" #include "structure.h" #include "vehicle.h" #include "weapon.h" @@ -105,10 +106,29 @@ namespace battleship{ initProperties(); } + void Vehicle::arrivedAtPathpoint(bool byPlane, float vertDist){ + bool orderHasDir = (orders[0].direction != Vector3::VEC_ZERO); + float angleToOrderDir = dirVec.getAngleBetween(orders[0].direction); + bool destDirWithin = (!orderHasDir || (orderHasDir && angleToOrderDir <= anglePrecision)); + + if(pathPoints.size() == 1 && !destDirWithin) + turn(calculateRotation(orders[0].direction, angleToOrderDir, maxTurnAngle)); + + if(byPlane && ( + (pathPoints.size() > 1 || (pathPoints.size() == 1 && destDirWithin)) && + (type != UnitType::UNDERWATER || (type == UnitType::UNDERWATER && vertDist < 0.5 * height)) + ) + ){ + removePathpoint(); + } + else if(!byPlane && (pathPoints.size() > 1 || (pathPoints.size() == 1 && destDirWithin))) + removePathpoint(); + } + void Vehicle::moveByTerrainQuads(Vector3 hypVec, float destOffset){ Map *map = Map::getSingleton(); Quad *terrQuad = (Quad*)map->getNodeParent()->getChild(0)->getMesh(0); - int numVertDiv = 100, numHorDiv = 100; + int numVertDiv = configData::NUM_SUBDIVS, numHorDiv = configData::NUM_SUBDIVS; Vector3 mapSize = map->getMapSize(); Vector2 sqIdsVec = terrQuad->getSubquadIds(numVertDiv, numHorDiv, pos, mapSize); Vector2 sqIdsEndVec = terrQuad->getSubquadIds(numVertDiv, numHorDiv, pathPoints[0], mapSize); @@ -132,7 +152,7 @@ namespace battleship{ float intersecY = (bottom ? c3.z : c1.z); float xSolY = a * intersecX + b; - float ySolX = (intersecY - b) / a; + float ySolX = (hypVec.x != 0 ? (intersecY - b) / a : points[points.size() - 1].x); float diff, vertDiff, x, y, z; @@ -179,8 +199,8 @@ namespace battleship{ placeAt(endPos); - if(fabs(pathPoints[0].x - pos.x) <= destOffset && fabs(pathPoints[0].z - pos.z) <= destOffset/* && fabs(pathPoints[0].y - pos.y) <= .1*/) - removePathpoint(); + if(fabs(pathPoints[0].x - pos.x) <= destOffset && fabs(pathPoints[0].z - pos.z) <= destOffset) + arrivedAtPathpoint(false); } void Vehicle::moveByPlane(Vector3 hypVec, float destOffset){ @@ -203,27 +223,13 @@ namespace battleship{ float dist = pos.y - pathPoints[0].y; float movementAmmount = (speed > fabs(dist) ? dist : speed); - if(dist > 0) - movementAmmount *= -1; + if(dist > 0) movementAmmount *= -1; advance(movementAmmount, MoveDir::UP); } - if(pos.getDistanceFrom(linDest) <= destOffset){ - bool orderHasDir = (orders[0].direction != Vector3::VEC_ZERO); - float angleToOrderDir = dirVec.getAngleBetween(orders[0].direction); - bool destDirWithin = (!orderHasDir || (orderHasDir && angleToOrderDir <= anglePrecision)); - - if(pathPoints.size() == 1 && !destDirWithin) - turn(calculateRotation(orders[0].direction, angleToOrderDir, maxTurnAngle)); - - if( - (pathPoints.size() > 1 || (pathPoints.size() == 1 && destDirWithin)) && - (type != UnitType::UNDERWATER || (type == UnitType::UNDERWATER && vertDist < 0.5 * height)) - ){ - removePathpoint(); - } - } + if(pos.getDistanceFrom(linDest) <= destOffset) + arrivedAtPathpoint(true, vertDist); } void Vehicle::navigate(float destOffset){ @@ -250,85 +256,11 @@ namespace battleship{ moveByTerrainQuads(hypVec, destOffset); else moveByPlane(hypVec, destOffset); - } - /* - int numHorSubquads = terrQuad->getNumHorSubquads(); - int numVertSubquads = terrQuad->getNumVertSubquads(); - Vector3 mapSize = map->getMapSize(); - Vector2 subquadSize = terrQuad->getSubquadSize(); - Vector3 pointA = pos, pointB = pathPoints[0]; - - if(pointA.x > pointB.x) swap(pointA.x, pointB.x); - if(pointA.z > pointB.z) swap(pointA.z, pointB.z); - - // y = ax + b - float a = hypVec.x / hypVec.z; - float b = pos.z / (a * pos.x); - - vector, float>> intersecPointDists; - - for(int x = 0; x < numHorSubquads; x++){ - float currX = -.5 * mapSize.x + x * subquadSize.x; - if(!(pointA.x <= currX && currX <= pointB.x)) continue; - - Vector2 pos2D = Vector2(pos.x, pos.z); - - int y; - for(y = 0; y < numVertSubquads; y++){ - float currY = -.5 * mapSize.z + y * subquadSize.y; - if(!(pointA.z <= currY && currY <= pointB.z)) continue; - - intersecPointDists.push_back(make_pair(make_pair(x, y), Vector2((currY - b) / a, currY).getDistanceFrom(pos2D))); - } - - intersecPointDists.push_back(make_pair(make_pair(x, y), Vector2(currX, a * currX + b).getDistanceFrom(pos2D))); - } - - for (int i = 0; i < intersecPointDists.size(); i++) - for (int j = 0; j < intersecPointDists.size() - i - 1; j++) - if (intersecPointDists[j] > intersecPointDists[j + 1]) - swap(intersecPointDists[j], intersecPointDists[j + 1]); - - float currDist = 0; - int lastId; - - for(int i = 0; i < intersecPointDists.size(); i++){ - currDist += intersecPointDists[i].second; - lastId = i; - - if(currDist + intersecPointDists[i].second > speed) break; - } - - Vector3 p1, p2; - //p1 = terrQuad->getSubQuadPoint(intersecPointDists[lastId]); - //p2 = terrQuad->getSubQuadPoint(intersecPointDists[lastId - 1]); - - Vector3 vec = p2 - p1; - } - */ - - void Vehicle::alignToSurface(){ - /* - Map *map = Map::getSingleton(); - TerrainObject terr = map->getTerrainObject(0); - vector res = RayCaster::cast(Vector3(pos.x, terr.size.y, pos.z), Vector3(0, -1, 0), terr.node); - - if(!res.empty()){ - placeAt(res[0].pos); - - float angle = upVec.getAngleBetween(res[0].norm); - Vector3 axis = upVec.cross(res[0].norm).norm(); - Quaternion rotQuat = Quaternion(angle, axis); - orientAt(rotQuat * rot); - } - */ } void Vehicle::move(Order order) { navigate(0.5 * Map::getSingleton()->getCellSize().x); - //if(type == UnitType::LAND) alignToSurface(); - if(pathPoints.empty()) removeOrder(0); } @@ -524,12 +456,7 @@ namespace battleship{ } } } - else{ - navigate(0.5 * Map::getSingleton()->getCellSize().x); - - if(type == UnitType::LAND) - alignToSurface(); - } + else navigate(0.5 * Map::getSingleton()->getCellSize().x); } void Vehicle::select(){ diff --git a/vehicle.h b/vehicle.h index c2cc92f..3479f2b 100644 --- a/vehicle.h +++ b/vehicle.h @@ -41,12 +41,12 @@ namespace battleship{ std::vector pathPoints; bool pursuingTarget = false; + void arrivedAtPathpoint(bool, float = 0); void moveByTerrainQuads(vb01::Vector3, float); void moveByPlane(vb01::Vector3, float); void navigate(float = 0.); void navigateToTarget(float); void preparePathpoints(Order&, vb01::Vector3, bool = false); - void alignToSurface(); virtual void attack(Order); void garrison(Order); void patrol(Order);