diff --git a/Assets/Scripts/GameObjects/Units/unitData.lua b/Assets/Scripts/GameObjects/Units/unitData.lua index 73426ff..76e736e 100644 --- a/Assets/Scripts/GameObjects/Units/unitData.lua +++ b/Assets/Scripts/GameObjects/Units/unitData.lua @@ -173,7 +173,8 @@ units = { rateOfFire = 1000, damage = 200, maxRange = 50, - nodes = {{name = 'Turret', rotationSpeed = .05, maxFireAngle = .1}}, + maxFireAngle = .1, + nodes = {{name = 'Turret', rotationSpeed = .05, vertical = false}}, 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 = { { @@ -230,9 +231,10 @@ units = { rateOfFire = 2000, damage = 5000, maxRange = 70, + maxFireAngle = .1, nodes = { - {name = 'turret', rotationSpeed = .05, maxFireAngle = .1}, - {name = 'tubes', rotationSpeed = .05, maxFireAngle = .1} + {name = 'turret', rotationSpeed = .05, vertical = false}, + --{name = 'tubes', rotationSpeed = .05, vertical = true} }, projectile = {id = ProjectileId.MISSILE, parent = 'tubes', pos = {x = 0.95, y = 2.16, z = 4.11}, rot = {w = 1, x = 0, y = 0, z = 0}}, fireFx = { @@ -896,7 +898,8 @@ units = { rateOfFire = 1000, damage = 0, maxRange = 25, - nodes = {{name = 'turret', rotationSpeed = .05, maxFireAngle = .1}}, + maxFireAngle = .1, + nodes = {{name = 'turret', rotationSpeed = .05, vertical = false}}, projectile = {id = ProjectileId.EMP_SHELL, parent = 'turret', pos = {x = 0.06, y = 5.82, z = 11.4}, rot = {w = .998, x = -.066, y = 0, z = 0}}, fireFx = { { @@ -1024,11 +1027,12 @@ units = { { orderType = OrderType.ATTACK, rateOfFire = 100, - damage = 50, - maxRange = 50, + damage = 17, + maxRange = 100, + maxFireAngle = .4, nodes = { - {name = 'TurretBody', rotationSpeed = .05, maxFireAngle = .1}, - {name = 'TurretArms', rotationSpeed = .05, maxFireAngle = .1} + {name = 'TurretBody', rotationSpeed = .1, vertical = false}, + {name = 'TurretArms', rotationSpeed = .1, angleConstraint = 1.1, vertical = true} }, fireFx = { { diff --git a/weapon.cpp b/weapon.cpp index 0d6d3a0..3cb84ee 100644 --- a/weapon.cpp +++ b/weapon.cpp @@ -20,13 +20,12 @@ namespace battleship{ Weapon::Weapon(Unit *u, sol::table unitTable, int wid) : unit(u), id(wid), - maxAngle(PI / 2 * .7), rateOfFire(unitTable["weapons"][wid + 1]["rateOfFire"]), damage(unitTable["weapons"][wid + 1]["damage"].get_or(0)) { sol::table weaponTable = unitTable["weapons"][wid + 1]; maxRange = weaponTable["maxRange"]; - maxFireAngle = weaponTable["maxFireAngle"].get_or(.4); + maxFireAngle = weaponTable["maxFireAngle"].get_or(.1); orderType = (Order::TYPE)weaponTable["orderType"]; initProjectileData(weaponTable); @@ -52,10 +51,20 @@ namespace battleship{ for(int i = 0; i < numNodes; i++){ sol::table nodeTbl = weaponTable["nodes"][i + 1]; - rotSpeed = nodeTbl["rotationSpeed"]; + float rotSpeed = nodeTbl["rotationSpeed"]; + bool vertical = nodeTbl["vertical"]; + + sol::optional angleConstrOpt = nodeTbl["angleConstraint"]; + float angleConstr; + + if(angleConstrOpt != sol::nullopt) + angleConstr = nodeTbl["angleConstraint"]; + else angleConstr = (vertical ? PI / 2 : 0); string name = nodeTbl["name"]; - nodes.push_back(unit->getModel()->findDescendant(name, true)); + Node *node = unit->getModel()->findDescendant(name, true); + + components.push_back(Component(node, rotSpeed, angleConstr, vertical)); } } @@ -114,14 +123,10 @@ namespace battleship{ if(ordTp == (int)orderType){ Vector3 targPos = (targDestruct ? targDestruct->getPos() : unit->getOrder(0).targets[0].pos); float targDist = unit->getPos().getDistanceFrom(targPos); - bool withinRange = (minRange <= targDist && targDist <= maxRange); - bool withinAngle = true; - if(!nodes.empty()){ - Vector3 dirVec = nodes[nodes.size() - 1]->getGlobalAxis(2); - withinAngle = Vector3(dirVec.x, 0, dirVec.z).norm().getAngleBetween((targPos - unit->getPos()).norm()) <= maxFireAngle; - } + Vector3 dirVec = (components.empty() ? unit->getDirVec() : components[components.size() - 1].node->getGlobalAxis(2)); + bool withinAngle = (dirVec.getAngleBetween((targPos - unit->getPos()).norm()) <= maxFireAngle); if((Order::TYPE)ordTp == Order::TYPE::ATTACK && withinRange && withinAngle) fire(unit->getOrder(0)); @@ -211,42 +216,39 @@ namespace battleship{ lastFireTime = getTime(); } - void Weapon::alignNode(Node *node, Vector3 targPos, bool vertical){ - Vector3 unitPos = unit->getPos(); - Vector3 unitUp = unit->getUpVec(); - Vector3 targDir = (targPos - unitPos).norm(); - - Vector3 compVec, rotAxis; - float rotAngle; - - if(vertical){ - compVec = getVecToPlane(unitPos, targDir, unitUp); - float angle1 = targDir.getAngleBetween(compVec); - float angle2 = node->getGlobalAxis(2).getAngleBetween(getVecToPlane(unitPos, node->getGlobalAxis(2), unitUp)); - float angleDiff = angle1 - angle2; - rotAngle = (rotSpeed < fabs(angleDiff) ? rotSpeed : fabs(angleDiff)) * (angleDiff > 0 ? -1 : 1); - - if(angle2 - rotAngle > maxAngle) - rotAngle = -(fabs(rotAngle) - (angle2 + fabs(rotAngle) - maxAngle)); - - rotAxis = Vector3::VEC_I; - } - else{ - targDir = getVecToPlane(unitPos, targDir, unitUp); - compVec = node->getGlobalAxis(2); - bool negate = (node->getGlobalAxis(0).getAngleBetween(targDir) < PI / 2); - float angle = compVec.getAngleBetween(targDir); - rotAngle = (negate ? 1 : -1) * (rotSpeed < angle ? rotSpeed : angle); - rotAxis = Vector3::VEC_J; - } - - Quaternion rot = Quaternion(rotAngle, rotAxis) * node->getOrientation(); - node->setOrientation(rot); - } - //TODO improve to allow for vertical alignment void Weapon::trackTarget(Vector3 targPos){ - if(nodes.size() >= 1) alignNode(nodes[0], targPos, false); - if(nodes.size() >= 2) alignNode(nodes[1], targPos, true); + for(Component &component : components){ + Vector3 unitPos = unit->getPos(); + Vector3 unitUp = unit->getUpVec(); + Vector3 targDir = (targPos - unitPos).norm(); + Vector3 targDirProj = getVecToPlane(unitPos, targDir, unitUp); + + Vector3 nodeDir = component.node->getGlobalAxis(2); + + Vector3 rotAxis; + float rotAngle; + + if(component.vertical){ + float angle1 = targDir.getAngleBetween(targDirProj); + float angle2 = nodeDir.getAngleBetween(getVecToPlane(unitPos, nodeDir, unitUp)); + float angleDiff = angle1 - angle2; + rotAngle = (component.rotSpeed < fabs(angleDiff) ? component.rotSpeed : fabs(angleDiff)) * (angleDiff > 0 ? -1 : 1); + + if(angle2 - rotAngle > component.angleConstr) + rotAngle = -(fabs(rotAngle) - (angle2 + fabs(rotAngle) - component.angleConstr)); + + rotAxis = Vector3::VEC_I; + } + else{ + bool negate = (component.node->getGlobalAxis(0).getAngleBetween(targDirProj) < PI / 2); + float angle = nodeDir.getAngleBetween(targDirProj); + rotAngle = (negate ? 1 : -1) * (component.rotSpeed < angle ? component.rotSpeed : angle); + rotAxis = Vector3::VEC_J; + } + + Quaternion rot = Quaternion(rotAngle, rotAxis) * component.node->getOrientation(); + component.node->setOrientation(rot); + } } } diff --git a/weapon.h b/weapon.h index d9abd5f..787e22d 100644 --- a/weapon.h +++ b/weapon.h @@ -21,6 +21,18 @@ namespace battleship{ public: enum class Type{FREEZER = 1}; + struct Component{ + vb01::Node *node = nullptr; + float rotSpeed, angleConstr; + bool vertical; + + Component(vb01::Node *n, float rs, float ac, bool v) : + node(n), + rotSpeed(rs), + angleConstr(ac), + vertical(v) {} + }; + Weapon(Unit*, sol::table, int); ~Weapon(); virtual void update(); @@ -37,22 +49,21 @@ namespace battleship{ Unit *unit = nullptr; Order::TYPE orderType; int id, projId = -1, damage = 0; - float minRange = 0, maxRange, rotSpeed, maxFireAngle, horConstraint = 1.57, vertConstraint = 1.57, maxAngle; + float minRange = 0, maxRange, maxFireAngle; vb01::s64 lastFireTime = 0; FxManager::Fx *fireFx = nullptr; vb01::Quaternion projRot; vb01::Vector3 projPos; - std::vector nodes; vb01::Node *projPar = nullptr; static std::string LASER_FLAG; void initProjectileData(sol::table); void initNodes(sol::table); void useFx(FxManager::Fx*, vb01::Vector3, bool); - void alignNode(vb01::Node*, vb01::Vector3, bool); inline bool canFire(){return vb01::getTime() - lastFireTime > rateOfFire;} protected: int rateOfFire; + std::vector components; virtual void updateTarget(GameObject*); };