mirror of
https://github.com/ApfelTeeSaft/PlanetFleet.git
synced 2026-08-26 19:33:38 +00:00
tank turrets tracking targets
This commit is contained in:
@@ -90,6 +90,7 @@ units = {
|
||||
weapons = {
|
||||
{
|
||||
type = WeaponClass.HITSCAN,
|
||||
orderType = OrderType.ATTACK,
|
||||
rateOfFire = 100,
|
||||
maxRange = 10,
|
||||
damage = 50,
|
||||
@@ -161,10 +162,16 @@ units = {
|
||||
weapons = {
|
||||
{
|
||||
type = WeaponClass.SHELL,
|
||||
orderType = OrderType.ATTACK,
|
||||
projectile = {id = ProjectileId.SHELL, pos = {x = 0.06, y = 5.82, z = 11.4}, rot = {w = 1, x = 0, y = 0, z = 0}},
|
||||
rateOfFire = 1000,
|
||||
damage = 200,
|
||||
maxRange = 25,
|
||||
node = {
|
||||
name = 'Turret',
|
||||
rotationSpeed = .05,
|
||||
maxFireAngle = .1
|
||||
},
|
||||
fireFx = {
|
||||
{
|
||||
vfx = false,
|
||||
@@ -215,6 +222,7 @@ units = {
|
||||
weapons = {
|
||||
{
|
||||
type = WeaponClass.HITSCAN,
|
||||
orderType = OrderType.ATTACK,
|
||||
rateOfFire = 2000,
|
||||
damage = 5000,
|
||||
maxRange = 30,
|
||||
@@ -265,7 +273,7 @@ units = {
|
||||
},
|
||||
{
|
||||
weapons = {
|
||||
{type = WeaponClass.HITSCAN, rateOfFire = 2000, fireSfx = PATH .. 'Sounds/Units/WarMechs/fire.ogg', damage = 20, maxRange = 8},
|
||||
{type = WeaponClass.HITSCAN, orderType = OrderType.ATTACK, rateOfFire = 2000, fireSfx = PATH .. 'Sounds/Units/WarMechs/fire.ogg', damage = 20, maxRange = 8},
|
||||
},
|
||||
buildableUnits = {
|
||||
{id = UnitId.LAND_FACTORY, buildable = true, trigger = 76},
|
||||
@@ -304,7 +312,7 @@ units = {
|
||||
garrisonCategory = 3
|
||||
},
|
||||
{
|
||||
weapons = {{type = WeaponClass.HITSCAN, rateOfFire = 2000, fireSfx = PATH .. 'Sounds/Units/WarMechs/fire.ogg', damage = 50, maxRange = 20}},
|
||||
weapons = {{type = WeaponClass.HITSCAN, orderType = OrderType.ATTACK, rateOfFire = 2000, fireSfx = PATH .. 'Sounds/Units/WarMechs/fire.ogg', damage = 50, maxRange = 20}},
|
||||
unitClass = UnitClass.TRANSPORT,
|
||||
unitType = UnitType.HOVER,
|
||||
isVehicle = true,
|
||||
@@ -329,7 +337,7 @@ units = {
|
||||
garrisonCategory = 3
|
||||
},
|
||||
{
|
||||
weapons = {{type = WeaponClass.HITSCAN, rateOfFire = 2000, fireSfx = PATH .. 'Sounds/Units/Tanks/attack.ogg', damage = 100, maxRange = 25}},
|
||||
weapons = {{type = WeaponClass.HITSCAN, orderType = OrderType.ATTACK, rateOfFire = 2000, fireSfx = PATH .. 'Sounds/Units/Tanks/attack.ogg', damage = 100, maxRange = 25}},
|
||||
unitClass = UnitClass.TRANSPORT,
|
||||
unitType = UnitType.HOVER,
|
||||
armor = {ArmorType.MECHANIC},
|
||||
@@ -391,6 +399,7 @@ units = {
|
||||
weapons = {
|
||||
{
|
||||
type = WeaponClass.HITSCAN,
|
||||
orderType = OrderType.ATTACK,
|
||||
rateOfFire = 200,
|
||||
damage = 300,
|
||||
maxRange = 15,
|
||||
@@ -442,6 +451,7 @@ units = {
|
||||
weapons = {
|
||||
{
|
||||
type = WeaponClass.HITSCAN,
|
||||
orderType = OrderType.ATTACK,
|
||||
rateOfFire = 200,
|
||||
fireFx = {
|
||||
{
|
||||
@@ -493,6 +503,7 @@ units = {
|
||||
weapons = {
|
||||
{
|
||||
type = WeaponClass.HITSCAN,
|
||||
orderType = OrderType.ATTACK,
|
||||
rateOfFire = 200,
|
||||
damage = 300,
|
||||
maxRange = 15,
|
||||
@@ -543,6 +554,7 @@ units = {
|
||||
weapons = {
|
||||
{
|
||||
type = WeaponClass.HITSCAN,
|
||||
orderType = OrderType.ATTACK,
|
||||
rateOfFire = 200,
|
||||
fireSfx = PATH .. 'Sounds/Units/Cruisers/fire.ogg',
|
||||
damage = 300,
|
||||
@@ -594,6 +606,7 @@ units = {
|
||||
weapons = {
|
||||
{
|
||||
type = WeaponClass.HITSCAN,
|
||||
orderType = OrderType.ATTACK,
|
||||
rateOfFire = 100,
|
||||
damage = 80,
|
||||
maxRange = 100,
|
||||
@@ -643,6 +656,7 @@ units = {
|
||||
weapons = {
|
||||
{
|
||||
type = WeaponClass.HITSCAN,
|
||||
orderType = OrderType.ATTACK,
|
||||
rateOfFire = 450,
|
||||
damage = 500,
|
||||
maxRange = 100,
|
||||
@@ -669,6 +683,7 @@ units = {
|
||||
},
|
||||
{
|
||||
type = WeaponClass.CRUISE_MISSILE,
|
||||
orderType = OrderType.LAUNCH,
|
||||
projectile = {id = ProjectileId.CRUISE_MISSILE, pos = {x = 0, y = 15, z = 0}, rot = {w = .707, x = -.707, y = 0, z = 0}},
|
||||
rateOfFire = 500,
|
||||
maxRange = 30,
|
||||
@@ -707,6 +722,7 @@ units = {
|
||||
weapons = {
|
||||
{
|
||||
type = WeaponClass.TORPEDO,
|
||||
orderType = OrderType.ATTACK,
|
||||
rateOfFire = 1000,
|
||||
fireFx = {
|
||||
{
|
||||
@@ -721,6 +737,7 @@ units = {
|
||||
},
|
||||
{
|
||||
type = WeaponClass.CRUISE_MISSILE,
|
||||
orderType = OrderType.LAUNCH,
|
||||
rateOfFire = 500,
|
||||
maxRange = 30,
|
||||
fireFx = {
|
||||
@@ -759,6 +776,7 @@ units = {
|
||||
weapons = {
|
||||
{
|
||||
type = WeaponClass.TORPEDO,
|
||||
orderType = OrderType.ATTACK,
|
||||
projectile = {id = ProjectileId.TORPEDO, pos = {x = 0, y = -.27, z = 4.6}, rot = {w = 1, x = 0, y = 0, z = 0}},
|
||||
damage = 200,
|
||||
maxRange = 20,
|
||||
@@ -885,9 +903,15 @@ units = {
|
||||
weapons = {
|
||||
{
|
||||
type = WeaponClass.HITSCAN,
|
||||
orderType = OrderType.ATTACK,
|
||||
rateOfFire = 100,
|
||||
damage = 50,
|
||||
maxRange = 50,
|
||||
node = {
|
||||
name = 'TurretBody',
|
||||
rotationSpeed = .05,
|
||||
maxFireAngle = .1
|
||||
},
|
||||
fireFx = {
|
||||
{
|
||||
vfx = true,
|
||||
|
||||
@@ -41,12 +41,27 @@ namespace battleship{
|
||||
{
|
||||
sol::table weaponTable = unitTable["weapons"][wid + 1];
|
||||
maxRange = weaponTable["maxRange"];
|
||||
orderType = (Order::TYPE)weaponTable["orderType"];
|
||||
initProjectileData(weaponTable);
|
||||
|
||||
sol::optional<sol::table> nodeTblOpt = unitTable["weapons"][wid + 1]["node"];
|
||||
|
||||
if(nodeTblOpt != sol::nullopt) initNode(weaponTable);
|
||||
|
||||
fireFx = initFx(weaponTable, "fireFx", true);
|
||||
if(fireFx) FxManager::getSingleton()->addFx(fireFx);
|
||||
}
|
||||
|
||||
|
||||
void Unit::Weapon::initNode(sol::table weaponTable){
|
||||
sol::table nodeTbl = weaponTable["node"];
|
||||
maxFireAngle = nodeTbl["maxFireAngle"];
|
||||
rotSpeed = nodeTbl["rotationSpeed"];
|
||||
|
||||
string name = nodeTbl["name"];
|
||||
node = unit->getModel()->findDescendant(name, true);
|
||||
}
|
||||
|
||||
void Unit::Weapon::initProjectileData(sol::table weaponTable){
|
||||
string projTableKey = "projectile";
|
||||
sol::optional<sol::table> proj = weaponTable[projTableKey];
|
||||
@@ -177,23 +192,14 @@ namespace battleship{
|
||||
|
||||
flashNode->setVisible(false);
|
||||
Node *parNode = (attached ? unit->getModel() : Root::getSingleton()->getRootNode());
|
||||
sol::optional<string> parOpt = compTbl["parent"];
|
||||
sol::optional<string> parNameOpt = compTbl["parent"];
|
||||
|
||||
if(parOpt != sol::nullopt){
|
||||
vector<Node*> descendants;
|
||||
unit->getModel()->getDescendants(descendants);
|
||||
if(parNameOpt != sol::nullopt){
|
||||
string parName = compTbl["parent"];
|
||||
parNode = nullptr;
|
||||
|
||||
for(Node *desc : descendants)
|
||||
if(desc->getName() == parName){
|
||||
parNode = desc;
|
||||
break;
|
||||
}
|
||||
parNode = unit->getModel()->findDescendant(parName, true);
|
||||
}
|
||||
|
||||
parNode->attachChild(flashNode);
|
||||
|
||||
fxComponents.push_back(FxManager::Fx::Component((void*)flashNode, vfx, duration, compPos, offset));
|
||||
}
|
||||
else{
|
||||
@@ -212,7 +218,31 @@ namespace battleship{
|
||||
if(fireFx) fm->removeFx(fireFx);
|
||||
}
|
||||
|
||||
void Unit::Weapon::update(){}
|
||||
//TODO replace unit pos with absolute weapon pos for withinAngle
|
||||
void Unit::Weapon::update(){
|
||||
if(node){
|
||||
dirVec = rot * unit->getDirVec();
|
||||
leftVec = rot * unit->getLeftVec();
|
||||
upVec = rot * unit->getUpVec();
|
||||
}
|
||||
|
||||
int numOrders = unit->getNumOrders();
|
||||
int ordTp = (numOrders > 0 ? (int)unit->getOrder(0).type : -1);
|
||||
Unit *targUnit = (ordTp != -1 ? unit->getOrder(0).targets[0].unit : nullptr);
|
||||
|
||||
if(ordTp == (int)orderType){
|
||||
Vector3 targPos = (targUnit ? targUnit->getPos() : unit->getOrder(0).targets[0].pos);
|
||||
float targDist = unit->getPos().getDistanceFrom(targPos);
|
||||
|
||||
bool withinRange = (minRange <= targDist && targDist <= maxRange);
|
||||
bool withinAngle = (node ? Vector3(dirVec.x, 0, dirVec.z).norm().getAngleBetween((targPos - unit->getPos()).norm()) <= maxFireAngle : true);
|
||||
|
||||
if((Order::TYPE)ordTp == Order::TYPE::ATTACK && withinRange && withinAngle)
|
||||
fire(unit->getOrder(0));
|
||||
}
|
||||
else
|
||||
trackTarget(unit->getPos() + unit->getDirVec());
|
||||
}
|
||||
|
||||
void Unit::Weapon::useFx(FxManager::Fx *fx, Vector3 targPos, bool fire){
|
||||
if(fx && !fire)
|
||||
@@ -278,14 +308,36 @@ namespace battleship{
|
||||
Vector3 leftVec = unit->getLeftVec();
|
||||
Vector3 upVec = unit->getUpVec();
|
||||
Vector3 dirVec = unit->getDirVec();
|
||||
Vector3 p = unit->getPos() + leftVec * projPos.x + upVec * projPos.y + dirVec * projPos.z;
|
||||
|
||||
Quaternion r = projRot * unit->getRot();
|
||||
Vector3 p = unit->getPos() + leftVec * projPos.x + upVec * projPos.y + dirVec * projPos.z;
|
||||
|
||||
if(node){
|
||||
r = node->localToGlobalOrientation(projRot);
|
||||
p = node->localToGlobalPosition(projPos);
|
||||
}
|
||||
|
||||
unit->getPlayer()->addProjectile(GameObjectFactory::createProjectile(unit, projId, p, r));
|
||||
}
|
||||
|
||||
lastFireTime = getTime();
|
||||
}
|
||||
|
||||
void Unit::Weapon::trackTarget(Vector3 targPos){
|
||||
if(!node) return;
|
||||
|
||||
Vector3 targDir = targPos - unit->getPos();
|
||||
Vector3 targDirHor = Vector3(targDir.x, 0, targDir.z).norm();
|
||||
Vector3 dirVecHor = Vector3(dirVec.x, 0, dirVec.z).norm();
|
||||
|
||||
float angle = dirVecHor.getAngleBetween(targDirHor);
|
||||
bool right = (Vector3(leftVec.x, 0, leftVec.z).norm().getAngleBetween(targDirHor) < PI / 2);
|
||||
float rotAngle = (rotSpeed < angle ? rotSpeed : angle);
|
||||
|
||||
rot = Quaternion((right ? 1 : -1) * rotAngle, Vector3::VEC_J) * rot;
|
||||
node->setOrientation(rot);
|
||||
}
|
||||
|
||||
Unit::Unit(Player *player, int id, Vector3 pos, Quaternion rot, State st) : GameObject(GameObject::Type::UNIT, id, player, pos, rot), state(st){
|
||||
selectable = true;
|
||||
|
||||
@@ -681,12 +733,18 @@ namespace battleship{
|
||||
|
||||
removeOrder(0);
|
||||
}
|
||||
|
||||
vector<Weapon*> attackWeapons = getWeaponsByOrder(Order::TYPE::ATTACK);
|
||||
Vector3 targPos = (order.targets[0].unit ? order.targets[0].unit->getPos() : order.targets[0].pos);
|
||||
|
||||
for(Weapon *weapon : attackWeapons)
|
||||
weapon->trackTarget(targPos);
|
||||
}
|
||||
|
||||
bool Unit::validateOrder(Order order){
|
||||
switch (order.type) {
|
||||
case Order::TYPE::ATTACK:
|
||||
return !weapons.empty();
|
||||
return !getWeaponsByOrder(Order::TYPE::ATTACK).empty();
|
||||
case Order::TYPE::BUILD:
|
||||
return unitClass == UnitClass::ENGINEER;
|
||||
case Order::TYPE::PATROL:
|
||||
@@ -721,6 +779,16 @@ namespace battleship{
|
||||
}
|
||||
}
|
||||
|
||||
vector<Unit::Weapon*> Unit::getWeaponsByOrder(Order::TYPE type){
|
||||
vector<Weapon*> weaps;
|
||||
|
||||
for(Weapon *w : weapons)
|
||||
if(w->getOrderType() == type)
|
||||
weaps.push_back(w);
|
||||
|
||||
return weapons;
|
||||
}
|
||||
|
||||
void Unit::receiveOrder(Order order, bool add) {
|
||||
if(!validateOrder(order)) return;
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@ namespace battleship{
|
||||
~Weapon();
|
||||
virtual void update();
|
||||
virtual void fire(Order);
|
||||
void trackTarget(vb01::Vector3);
|
||||
inline Type getType(){return type;}
|
||||
inline int getProjectileId(){return projId;}
|
||||
inline int getRateOfFire(){return rateOfFire;}
|
||||
@@ -101,18 +102,23 @@ namespace battleship{
|
||||
inline int getMinRange(){return minRange;}
|
||||
inline int getMaxRange(){return maxRange;}
|
||||
inline Unit* getUnit(){return unit;}
|
||||
inline Order::TYPE getOrderType(){return orderType;}
|
||||
private:
|
||||
Type type;
|
||||
int id, projId = -1, rateOfFire, damage = 0;
|
||||
float minRange = 0, maxRange;
|
||||
float minRange = 0, maxRange, rotSpeed, maxFireAngle;
|
||||
vb01::Vector3 projPos;
|
||||
vb01::Quaternion projRot;
|
||||
vb01::Quaternion projRot, rot = vb01::Quaternion::QUAT_W;
|
||||
vb01::s64 lastFireTime = 0;
|
||||
Unit *unit = nullptr;
|
||||
FxManager::Fx *fireFx = nullptr;
|
||||
vb01::Node *node = nullptr;
|
||||
Order::TYPE orderType;
|
||||
vb01::Vector3 upVec = vb01::Vector3(0, 1, 0), dirVec = vb01::Vector3(0, 0, 1), leftVec = vb01::Vector3(1, 0, 0);
|
||||
static std::string LASER_FLAG;
|
||||
|
||||
void initProjectileData(sol::table);
|
||||
void initNode(sol::table);
|
||||
FxManager::Fx* initFx(sol::table, std::string, bool);
|
||||
void useFx(FxManager::Fx*, vb01::Vector3, bool);
|
||||
inline bool canFire(){return vb01::getTime() - lastFireTime > rateOfFire;}
|
||||
@@ -215,6 +221,7 @@ namespace battleship{
|
||||
void removeBar(vb01::Node*);
|
||||
vb01::Node* createBar(vb01::Vector2, vb01::Vector2, vb01::Vector4);
|
||||
void displayUnitStats(vb01::Node*, vb01::Node*, int, int, bool, vb01::Vector2 offset = vb01::Vector2::VEC_ZERO);
|
||||
std::vector<Weapon*> getWeaponsByOrder(Order::TYPE);
|
||||
inline std::vector<Armor> getArmorTypes(){return armorTypes;}
|
||||
};
|
||||
}
|
||||
|
||||
+9
-11
@@ -316,12 +316,19 @@ namespace battleship{
|
||||
Unit::attack(order);
|
||||
int currNumOrders = orders.size();
|
||||
|
||||
if(weapons.empty() || prevNumOrders != currNumOrders) return;
|
||||
if(prevNumOrders != currNumOrders) return;
|
||||
|
||||
Order::Target target = order.targets[0];
|
||||
Vector3 targVec = (target.unit ? target.unit->getPos() : target.pos) - pos;
|
||||
float distToTarg = targVec.getLength();
|
||||
Weapon *weapon = weapons[0];
|
||||
|
||||
vector<Weapon*> attackWeapons = getWeaponsByOrder(Order::TYPE::ATTACK);
|
||||
Weapon *weapon = attackWeapons[0];
|
||||
|
||||
for(Weapon *w : attackWeapons)
|
||||
if(w->getMaxRange() > weapon->getMaxRange())
|
||||
weapon = w;
|
||||
|
||||
float minDist = weapon->getMaxRange();
|
||||
|
||||
if(order.playerAssigned || (!order.playerAssigned && state == Unit::State::CHASE)){
|
||||
@@ -334,15 +341,6 @@ namespace battleship{
|
||||
removeOrder(0);
|
||||
return;
|
||||
}
|
||||
|
||||
float angleToTarg = targVec.norm().getAngleBetween(dirVec);
|
||||
|
||||
if(distToTarg <= weapon->getMaxRange()){
|
||||
if(angleToTarg <= anglePrecision)
|
||||
weapon->fire(order);
|
||||
else if(angleToTarg > anglePrecision)
|
||||
turn(calculateRotation(targVec.norm(), angleToTarg, maxTurnAngle));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user