using a variable number of nodes for unit weapons

This commit is contained in:
devZoGok
2025-11-14 16:16:26 +02:00
parent f39c67793f
commit fcd9468edf
3 changed files with 61 additions and 53 deletions
+10 -6
View File
@@ -172,7 +172,7 @@ units = {
rateOfFire = 1000,
damage = 200,
maxRange = 50,
horizontalNode = {name = 'Turret', rotationSpeed = .05, maxFireAngle = .1},
nodes = {{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 = {
{
@@ -228,8 +228,10 @@ units = {
rateOfFire = 2000,
damage = 5000,
maxRange = 70,
horizontalNode = {name = 'turret', rotationSpeed = .05, maxFireAngle = .1},
verticalNode = {name = 'tubes', rotationSpeed = .05, maxFireAngle = .1},
nodes = {
{name = 'turret', rotationSpeed = .05, maxFireAngle = .1},
{name = 'tubes', rotationSpeed = .05, maxFireAngle = .1}
},
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 = {
{
@@ -887,7 +889,7 @@ units = {
rateOfFire = 1000,
damage = 0,
maxRange = 25,
horizontalNode = {name = 'turret', rotationSpeed = .05, maxFireAngle = .1},
nodes = {{name = 'turret', rotationSpeed = .05, maxFireAngle = .1}},
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 = {
{
@@ -1014,8 +1016,10 @@ units = {
rateOfFire = 100,
damage = 50,
maxRange = 50,
horizontalNode = {name = 'TurretBody', rotationSpeed = .05, maxFireAngle = .1},
--verticalNode = {name = 'TurretArms', rotationSpeed = .05, maxFireAngle = .1},
nodes = {
{name = 'TurretBody', rotationSpeed = .05, maxFireAngle = .1},
{name = 'TurretArms', rotationSpeed = .05, maxFireAngle = .1}
},
fireFx = {
{
vfx = true,
+48 -45
View File
@@ -26,12 +26,7 @@ namespace battleship{
orderType = (Order::TYPE)weaponTable["orderType"];
initProjectileData(weaponTable);
sol::optional<sol::table> horNodeTblOpt = unitTable["weapons"][wid + 1]["horizontalNode"];
sol::optional<sol::table> vertNodeTblOpt = unitTable["weapons"][wid + 1]["verticalNode"];
if(horNodeTblOpt != sol::nullopt) horNode = initNode(weaponTable, true);
if(vertNodeTblOpt != sol::nullopt) vertNode = initNode(weaponTable, false);
initNodes(weaponTable);
sol::optional<sol::table> fireFxOpt = weaponTable["fireFx"];
@@ -43,52 +38,60 @@ namespace battleship{
}
}
void Weapon::initNodes(sol::table weaponTable){
sol::optional<sol::table> nodesTblOpt = weaponTable["nodes"];
Node* Weapon::initNode(sol::table weaponTable, bool horizontal){
sol::table nodeTbl = weaponTable[horizontal ? "horizontalNode" : "verticalNode"];
maxFireAngle = nodeTbl["maxFireAngle"];
rotSpeed = nodeTbl["rotationSpeed"];
if(nodesTblOpt == sol::nullopt) return;
string name = nodeTbl["name"];
return unit->getModel()->findDescendant(name, true);
sol::table tbl = weaponTable["nodes"];
int numNodes = tbl.size();
for(int i = 0; i < numNodes; i++){
sol::table nodeTbl = weaponTable["nodes"][i + 1];
maxFireAngle = nodeTbl["maxFireAngle"];
rotSpeed = nodeTbl["rotationSpeed"];
string name = nodeTbl["name"];
nodes.push_back(unit->getModel()->findDescendant(name, true));
}
}
void Weapon::initProjectileData(sol::table weaponTable){
string projTableKey = "projectile";
sol::optional<sol::table> proj = weaponTable[projTableKey];
if(proj != sol::nullopt){
projId = weaponTable[projTableKey]["id"];
sol::table projTable = generateView()["projectiles"];
ProjectileClass pc = (ProjectileClass)projTable[projId + 1]["projectileClass"];
if(proj == sol::nullopt) return;
if(pc == ProjectileClass::CRUISE_MISSILE){
minRange = 0;
float rotAngle = projTable[projId + 1]["rotAngle"];
float speed = projTable[projId + 1]["speed"];
float base = PI / 2, alpha = 0;
projId = weaponTable[projTableKey]["id"];
sol::table projTable = generateView()["projectiles"];
ProjectileClass pc = (ProjectileClass)projTable[projId + 1]["projectileClass"];
while(base - alpha > .001){
minRange += speed * sin(alpha);
alpha += (base - alpha > rotAngle ? rotAngle : base - alpha);
}
if(pc == ProjectileClass::CRUISE_MISSILE){
minRange = 0;
float rotAngle = projTable[projId + 1]["rotAngle"];
float speed = projTable[projId + 1]["speed"];
float base = PI / 2, alpha = 0;
minRange *= 2;
while(base - alpha > .001){
minRange += speed * sin(alpha);
alpha += (base - alpha > rotAngle ? rotAngle : base - alpha);
}
projPar = unit->getModel();
sol::optional<string> parNameOpt = weaponTable[projTableKey]["parent"];
if(parNameOpt != sol::nullopt){
string parName = weaponTable[projTableKey]["parent"];
projPar = unit->getModel()->findDescendant(parName, true);
}
sol::table posTable = weaponTable[projTableKey]["pos"];
projPos = Vector3(posTable["x"], posTable["y"], posTable["z"]);
sol::table rotTable = weaponTable[projTableKey]["rot"];
projRot = Quaternion(rotTable["w"], rotTable["x"], rotTable["y"], rotTable["z"]);
minRange *= 2;
}
projPar = unit->getModel();
sol::optional<string> parNameOpt = weaponTable[projTableKey]["parent"];
if(parNameOpt != sol::nullopt){
string parName = weaponTable[projTableKey]["parent"];
projPar = unit->getModel()->findDescendant(parName, true);
}
sol::table posTable = weaponTable[projTableKey]["pos"];
projPos = Vector3(posTable["x"], posTable["y"], posTable["z"]);
sol::table rotTable = weaponTable[projTableKey]["rot"];
projRot = Quaternion(rotTable["w"], rotTable["x"], rotTable["y"], rotTable["z"]);
}
Weapon::~Weapon(){
@@ -112,8 +115,8 @@ namespace battleship{
bool withinRange = (minRange <= targDist && targDist <= maxRange);
bool withinAngle = true;
if(horNode){
Vector3 dirVec = horNode->getGlobalAxis(2);
if(!nodes.empty()){
Vector3 dirVec = nodes[0]->getGlobalAxis(2);
withinAngle = Vector3(dirVec.x, 0, dirVec.z).norm().getAngleBetween((targPos - unit->getPos()).norm()) <= maxFireAngle;
}
@@ -208,21 +211,21 @@ namespace battleship{
//TODO improve to allow for vertical alignment
void Weapon::trackTarget(Vector3 targPos){
if(!horNode) return;
if(nodes.empty()) return;
Vector3 unitPos = unit->getPos();
Vector3 targDir = (targPos - unitPos).norm();
targDir = getVecToPlane(unitPos, targDir, unit->getUpVec());
Vector3 dirVec = getVecToPlane(unitPos, horNode->getGlobalAxis(2), unit->getUpVec());
Vector3 leftVec = horNode->getGlobalAxis(0);
Vector3 dirVec = getVecToPlane(unitPos, nodes[0]->getGlobalAxis(2), unit->getUpVec());
Vector3 leftVec = nodes[0]->getGlobalAxis(0);
bool negate = (leftVec.getAngleBetween(targDir) < PI / 2);
float angle = dirVec.getAngleBetween(targDir);
float rotAngle = (rotSpeed < angle ? rotSpeed : angle);
Quaternion rot = Quaternion((negate ? 1 : -1) * rotAngle, Vector3::VEC_J) * horNode->getOrientation();
horNode->setOrientation(rot);
Quaternion rot = Quaternion((negate ? 1 : -1) * rotAngle, Vector3::VEC_J) * nodes[0]->getOrientation();
nodes[0]->setOrientation(rot);
}
CryoGun::CryoGun(Unit *u, sol::table unitTable, int wid) : Weapon(u, unitTable, wid){}
+3 -2
View File
@@ -42,11 +42,12 @@ namespace battleship{
vb01::Quaternion projRot;
vb01::Vector3 projPos;
float horConstraint = 1.57, vertConstraint = 1.57;
vb01::Node *horNode = nullptr, *vertNode = nullptr, *projPar = nullptr;
std::vector<vb01::Node*> nodes;
vb01::Node *projPar = nullptr;
static std::string LASER_FLAG;
void initProjectileData(sol::table);
vb01::Node* initNode(sol::table, bool);
void initNodes(sol::table);
void useFx(FxManager::Fx*, vb01::Vector3, bool);
inline bool canFire(){return vb01::getTime() - lastFireTime > rateOfFire;}
protected: