point defenses aim vertically towards missiles

This commit is contained in:
devZoGok
2025-12-05 14:43:18 +02:00
parent 1d0bf8d349
commit 1cfa181918
6 changed files with 104 additions and 50 deletions
+5 -3
View File
@@ -24,18 +24,20 @@ set(TRADING_BUTTONS activeStateBackButton.cpp playerTradeButton.cpp tradingScree
set(MENU_BUTTONS mainMenuButton.cpp singlePlayerButton.cpp exitButton.cpp backButton.cpp playButton.cpp)
set(MAP_EDITOR_BUTTONS mapEditorButton.cpp newMapButton.cpp loadMapButton.cpp exportButton.cpp)
set(BUTTONS statsButton.cpp activeStateButton.cpp minimapButton.cpp ${TRADING_BUTTONS} ${OPTIONS_BUTTONS} ${MENU_BUTTONS} ${MAP_EDITOR_BUTTONS} ${UNIT_BUTTONS})
set(LISTBOXES skyboxTextureListbox.cpp landTextureListbox.cpp gameObjectListbox.cpp mapListbox.cpp)
set(GUI tooltip.cpp concreteGuiManager.cpp ${BUTTONS} ${LISTBOXES})
set(CONTROLLERS gameObjectFrameController.cpp cameraController.cpp)
set(CONSOLE console.cpp abstractCommand.cpp addUnitCommand.cpp addResourceCommand.cpp addTechnologyCommand.cpp toggleDebugCommand.cpp)
set(CORE gameManager.cpp game.cpp environment.cpp fxManager.cpp defConfigs.cpp ${CONSOLE} ${CONTROLLERS})
set(CORE gameManager.cpp game.cpp pathfinder.cpp environment.cpp fxManager.cpp defConfigs.cpp player.cpp trader.cpp ${CONSOLE} ${CONTROLLERS})
set(PROJECTILES projectile.cpp missile.cpp cruiseMissile.cpp shell.cpp)
set(VEHICLES vehicle.cpp submarine.cpp engineer.cpp resourceRover.cpp freezer.cpp)
set(STRUCTURES structure.cpp factory.cpp pointDefense.cpp extractor.cpp researchStruct.cpp iceSheet.cpp)
set(UNITS gameObjectFactory.cpp unit.cpp weapon.cpp ${STRUCTURES} ${VEHICLES})
set(CONTENT player.cpp trader.cpp pathfinder.cpp map.cpp gameObject.cpp destructable.cpp gameObjectFrame.h resourceDeposit.cpp ${UNITS} ${PROJECTILES})
set(WEAPONS weapon.cpp cryoGun.cpp)
set(UNITS unit.cpp ${WEAPONS} ${STRUCTURES} ${VEHICLES})
set(CONTENT map.cpp gameObject.cpp destructable.cpp gameObjectFrame.h gameObjectFactory.cpp resourceDeposit.cpp ${UNITS} ${PROJECTILES})
set(UTIL util.cpp binds.h)
+20
View File
@@ -0,0 +1,20 @@
#include "cryoGun.h"
#include "destructable.h"
#include "unit.h"
namespace battleship{
using namespace std;
using namespace vb01;
using namespace gameBase;
CryoGun::CryoGun(Unit *u, sol::table unitTable, int wid) : Weapon(u, unitTable, wid){}
void CryoGun::updateTarget(GameObject *target){
if(canFreeze()){
Destructable *destructTarg = target->getDestructable();
destructTarg->setFreezeStatus(destructTarg->getFreezeStatus() + 1);
lastFreezeTime = getTime();
}
}
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef CRYOGUN_H
#define CRYOGUN_H
#include "weapon.h"
#include <util.h>
#include <solUtil.h>
namespace battleship{
class Unit;
class CryoGun : public Weapon{
public:
CryoGun(Unit*, sol::table, int);
private:
vb01::s64 lastFreezeTime = 0;
void updateTarget(GameObject*);
inline bool canFreeze(){return vb01::getTime() - lastFreezeTime > rateOfFire;}
};
}
#endif
+9 -2
View File
@@ -13,6 +13,7 @@
#include <ext.hpp>
#include "unit.h"
#include "cryoGun.h"
#include "weapon.h"
#include "util.h"
#include "game.h"
@@ -141,8 +142,14 @@ namespace battleship{
if(wtOpt != sol::nullopt) wt = unitTable[tblName][i + 1]["type"];
Weapon *weapon = ((Weapon::Type)wt == Weapon::Type::FREEZER ? new CryoGun(this, unitTable, i) : new Weapon(this, unitTable, i));
weapons.push_back(weapon);
switch((Weapon::Type)wt){
case Weapon::Type::FREEZER:
weapons.push_back(new CryoGun(this, unitTable, i));
break;
default:
weapons.push_back(new Weapon(this, unitTable, i));
break;
}
}
}
}
+41 -31
View File
@@ -3,6 +3,7 @@
#include <particleEmitter.h>
#include "map.h"
#include "unit.h"
#include "util.h"
#include "weapon.h"
#include "player.h"
@@ -19,11 +20,13 @@ 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);
orderType = (Order::TYPE)weaponTable["orderType"];
initProjectileData(weaponTable);
@@ -49,7 +52,6 @@ namespace battleship{
for(int i = 0; i < numNodes; i++){
sol::table nodeTbl = weaponTable["nodes"][i + 1];
maxFireAngle = nodeTbl["maxFireAngle"];
rotSpeed = nodeTbl["rotationSpeed"];
string name = nodeTbl["name"];
@@ -117,7 +119,7 @@ namespace battleship{
bool withinAngle = true;
if(!nodes.empty()){
Vector3 dirVec = nodes[0]->getGlobalAxis(2);
Vector3 dirVec = nodes[nodes.size() - 1]->getGlobalAxis(2);
withinAngle = Vector3(dirVec.x, 0, dirVec.z).norm().getAngleBetween((targPos - unit->getPos()).norm()) <= maxFireAngle;
}
@@ -129,10 +131,8 @@ namespace battleship{
}
void Weapon::useFx(FxManager::Fx *fx, Vector3 targPos, bool fire){
if(fx && !fire)
FxManager::getSingleton()->addFx(fx);
else if(!fx)
return;
if(fx && !fire) FxManager::getSingleton()->addFx(fx);
else if(!fx) return;
fx->toggleComponents(true);
@@ -211,32 +211,42 @@ 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.empty()) return;
Vector3 unitPos = unit->getPos();
Vector3 targDir = (targPos - unitPos).norm();
targDir = getVecToPlane(unitPos, targDir, unit->getUpVec());
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) * nodes[0]->getOrientation();
nodes[0]->setOrientation(rot);
}
CryoGun::CryoGun(Unit *u, sol::table unitTable, int wid) : Weapon(u, unitTable, wid){}
void CryoGun::updateTarget(GameObject *target){
if(canFreeze()){
Destructable *destructTarg = target->getDestructable();
destructTarg->setFreezeStatus(destructTarg->getFreezeStatus() + 1);
lastFreezeTime = getTime();
}
if(nodes.size() >= 1) alignNode(nodes[0], targPos, false);
if(nodes.size() >= 2) alignNode(nodes[1], targPos, true);
}
}
+4 -14
View File
@@ -1,14 +1,14 @@
#ifndef WEAPON_H
#define WEAPON_H
#include "unit.h"
#include <vector>
#include <util.h>
#include <quaternion.h>
#include <solUtil.h>
#include "unit.h"
namespace vb01{
class Node;
}
@@ -37,12 +37,11 @@ namespace battleship{
Unit *unit = nullptr;
Order::TYPE orderType;
int id, projId = -1, damage = 0;
float minRange = 0, maxRange, rotSpeed, maxFireAngle;
float minRange = 0, maxRange, rotSpeed, maxFireAngle, horConstraint = 1.57, vertConstraint = 1.57, maxAngle;
vb01::s64 lastFireTime = 0;
FxManager::Fx *fireFx = nullptr;
vb01::Quaternion projRot;
vb01::Vector3 projPos;
float horConstraint = 1.57, vertConstraint = 1.57;
std::vector<vb01::Node*> nodes;
vb01::Node *projPar = nullptr;
static std::string LASER_FLAG;
@@ -50,22 +49,13 @@ namespace battleship{
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;
virtual void updateTarget(GameObject*);
};
class CryoGun : public Weapon{
public:
CryoGun(Unit*, sol::table, int);
private:
vb01::s64 lastFreezeTime = 0;
void updateTarget(GameObject*);
inline bool canFreeze(){return vb01::getTime() - lastFreezeTime > rateOfFire;}
};
}
#endif