mirror of
https://github.com/ApfelTeeSaft/PlanetFleet.git
synced 2026-08-26 19:33:38 +00:00
begun implementing vertical target tracking
This commit is contained in:
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -163,15 +163,11 @@ units = {
|
||||
{
|
||||
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
|
||||
},
|
||||
horizontalNode = {name = 'Turret', rotationSpeed = .05, maxFireAngle = .1},
|
||||
projectile = {id = ProjectileId.SHELL, parent = 'Turret', pos = {x = 0.06, y = 5.82, z = 11.4}, rot = {w = 1, x = 0, y = 0, z = 0}},
|
||||
fireFx = {
|
||||
{
|
||||
vfx = false,
|
||||
@@ -221,21 +217,25 @@ units = {
|
||||
{
|
||||
weapons = {
|
||||
{
|
||||
type = WeaponClass.HITSCAN,
|
||||
type = WeaponClass.SHELL,
|
||||
orderType = OrderType.ATTACK,
|
||||
rateOfFire = 2000,
|
||||
damage = 5000,
|
||||
maxRange = 30,
|
||||
horizontalNode = {name = 'turret', rotationSpeed = .05, maxFireAngle = .1},
|
||||
verticalNode = {name = 'tubes', rotationSpeed = .05, maxFireAngle = .1},
|
||||
projectile = {id = ProjectileId.SHELL, parent = 'tubes', pos = {x = 0.95, y = 2.16, z = 4.11}, rot = {w = 1, x = 0, y = 0, z = 0}},
|
||||
fireFx = {
|
||||
{
|
||||
vfx = true,
|
||||
duration = 50,
|
||||
parent = 'tubes',
|
||||
pos = {x = 0.95, y = 2.16, z = 4.11},
|
||||
rot = {w = 1, x = 0, y = 0, z = 0},
|
||||
mesh = {
|
||||
path = PATH .. vfxPrefix .. 'muzzleFlash.xml',
|
||||
color = {x = 1, y = 1, z = 0, a = 1},
|
||||
},
|
||||
pos = {x = 1, y = 5.8, z = 3.9},
|
||||
rot = {w = 1, x = 0, y = 0, z = 0},
|
||||
--scale = .5
|
||||
},
|
||||
{
|
||||
@@ -244,8 +244,6 @@ units = {
|
||||
path = PATH .. 'Sounds/Units/Tanks/attack.ogg',
|
||||
}
|
||||
},
|
||||
landHitFx = {explosionVfx, explosionSfx},
|
||||
unitHitFx = {explosionVfx, explosionSfx}
|
||||
}
|
||||
},
|
||||
unitClass = UnitClass.ARTILLERY,
|
||||
|
||||
@@ -35,31 +35,33 @@ namespace battleship{
|
||||
Unit::Weapon::Weapon(Unit *u, sol::table unitTable, int wid) :
|
||||
unit(u),
|
||||
id(wid),
|
||||
type((Weapon::Type)unitTable["weapons"][wid + 1]["type"]),
|
||||
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"];
|
||||
orderType = (Order::TYPE)weaponTable["orderType"];
|
||||
|
||||
initProjectileData(weaponTable);
|
||||
|
||||
sol::optional<sol::table> nodeTblOpt = unitTable["weapons"][wid + 1]["node"];
|
||||
sol::optional<sol::table> horNodeTblOpt = unitTable["weapons"][wid + 1]["horizontalNode"];
|
||||
sol::optional<sol::table> vertNodeTblOpt = unitTable["weapons"][wid + 1]["verticalNode"];
|
||||
|
||||
if(nodeTblOpt != sol::nullopt) initNode(weaponTable);
|
||||
if(horNodeTblOpt != sol::nullopt) horNode = initNode(weaponTable, true);
|
||||
if(vertNodeTblOpt != sol::nullopt) vertNode = initNode(weaponTable, false);
|
||||
|
||||
fireFx = initFx(weaponTable, "fireFx", true);
|
||||
if(fireFx) FxManager::getSingleton()->addFx(fireFx);
|
||||
}
|
||||
|
||||
|
||||
void Unit::Weapon::initNode(sol::table weaponTable){
|
||||
sol::table nodeTbl = weaponTable["node"];
|
||||
Node* Unit::Weapon::initNode(sol::table weaponTable, bool horizontal){
|
||||
sol::table nodeTbl = weaponTable[horizontal ? "horizontalNode" : "verticalNode"];
|
||||
maxFireAngle = nodeTbl["maxFireAngle"];
|
||||
rotSpeed = nodeTbl["rotationSpeed"];
|
||||
|
||||
string name = nodeTbl["name"];
|
||||
node = unit->getModel()->findDescendant(name, true);
|
||||
return unit->getModel()->findDescendant(name, true);
|
||||
}
|
||||
|
||||
void Unit::Weapon::initProjectileData(sol::table weaponTable){
|
||||
@@ -85,6 +87,14 @@ namespace battleship{
|
||||
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"];
|
||||
@@ -92,18 +102,15 @@ namespace battleship{
|
||||
}
|
||||
}
|
||||
|
||||
//TODO implement node child search by name
|
||||
FxManager::Fx* Unit::Weapon::initFx(sol::table weaponTable, string fxKey, bool attached){
|
||||
sol::optional<sol::table> fxOpt = weaponTable[fxKey];
|
||||
|
||||
if(fxOpt == sol::nullopt)
|
||||
return nullptr;
|
||||
if(fxOpt == sol::nullopt) return nullptr;
|
||||
|
||||
sol::table fxTbl = weaponTable[fxKey];
|
||||
int numComponents = fxTbl.size();
|
||||
|
||||
if(numComponents == 0)
|
||||
return nullptr;
|
||||
if(numComponents == 0) return nullptr;
|
||||
|
||||
vector<FxManager::Fx::Component> fxComponents;
|
||||
|
||||
@@ -218,14 +225,29 @@ namespace battleship{
|
||||
if(fireFx) fm->removeFx(fireFx);
|
||||
}
|
||||
|
||||
//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();
|
||||
Vector3 Unit::Weapon::calcOrientVec(int id){
|
||||
Vector3 orientVec;
|
||||
|
||||
switch(id){
|
||||
case 0:
|
||||
orientVec = unit->getDirVec();
|
||||
break;
|
||||
case 1:
|
||||
orientVec = unit->getLeftVec();
|
||||
break;
|
||||
case 2:
|
||||
orientVec = unit->getUpVec();
|
||||
break;
|
||||
}
|
||||
|
||||
if(horNode) orientVec = horNode->getOrientation() * orientVec;
|
||||
if(vertNode) orientVec = vertNode->getOrientation() * orientVec;
|
||||
|
||||
return orientVec;
|
||||
}
|
||||
|
||||
//TODO replace unit pos with absolute weapon pos for withinAngle
|
||||
void Unit::Weapon::update(){
|
||||
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);
|
||||
@@ -235,7 +257,9 @@ namespace battleship{
|
||||
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);
|
||||
|
||||
Vector3 dirVec = calcOrientVec(0);
|
||||
bool withinAngle = (horNode ? 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));
|
||||
@@ -305,39 +329,37 @@ namespace battleship{
|
||||
}
|
||||
}
|
||||
else{
|
||||
Vector3 leftVec = unit->getLeftVec();
|
||||
Vector3 upVec = unit->getUpVec();
|
||||
Vector3 dirVec = unit->getDirVec();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
Quaternion r = projPar->localToGlobalOrientation(projRot);
|
||||
Vector3 p = projPar->localToGlobalPosition(projPos);
|
||||
unit->getPlayer()->addProjectile(GameObjectFactory::createProjectile(unit, projId, p, r));
|
||||
}
|
||||
|
||||
lastFireTime = getTime();
|
||||
}
|
||||
|
||||
void Unit::Weapon::trackTarget(Vector3 targPos){
|
||||
if(!node) return;
|
||||
|
||||
//TODO improve to allow for vertical alignment
|
||||
void Unit::Weapon::alignNode(Vector3 targPos, Node *node, bool horizontal){
|
||||
Vector3 targDir = targPos - unit->getPos();
|
||||
Vector3 targDirHor = Vector3(targDir.x, 0, targDir.z).norm();
|
||||
Vector3 dirVecHor = Vector3(dirVec.x, 0, dirVec.z).norm();
|
||||
Vector3 targDirHor = Vector3(targDir.x, 0, targDir.z).norm(), targDirVert;
|
||||
|
||||
Vector3 dirVec = calcOrientVec(0);
|
||||
Vector3 dirVecHor = Vector3(dirVec.x, 0, dirVec.z).norm(), dirVecVert;
|
||||
|
||||
Vector3 leftVec = calcOrientVec(1);
|
||||
bool negate = (Vector3(leftVec.x, 0, leftVec.z).norm().getAngleBetween(targDirHor) < PI / 2);
|
||||
|
||||
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;
|
||||
Quaternion rot = Quaternion((negate ? 1 : -1) * rotAngle, unit->getUpVec()) * node->getOrientation();
|
||||
node->setOrientation(rot);
|
||||
}
|
||||
|
||||
void Unit::Weapon::trackTarget(Vector3 targPos){
|
||||
if(horNode) alignNode(targPos, horNode, true);
|
||||
//if(vertNode) alignNode(targPos, vertNode, false);
|
||||
}
|
||||
|
||||
Unit::Unit(Player *player, int id, Vector3 pos, Quaternion rot, State st) : GameObject(GameObject::Type::UNIT, id, player, pos, rot), state(st){
|
||||
selectable = true;
|
||||
|
||||
@@ -755,25 +777,13 @@ namespace battleship{
|
||||
case Order::TYPE::EJECT:
|
||||
return !garrisonSlots.empty();
|
||||
case Order::TYPE::LAUNCH:
|
||||
{
|
||||
for(Weapon *weapon : weapons)
|
||||
if(weapon->getType() == Weapon::Type::CRUISE_MISSILE)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
return !getWeaponsByOrder(Order::TYPE::LAUNCH).empty();
|
||||
case Order::TYPE::SUPPLY:
|
||||
case Order::TYPE::LOAD:
|
||||
case Order::TYPE::UNLOAD:
|
||||
return unitClass == UnitClass::RESOURCE_ROVER;
|
||||
case Order::TYPE::HACK:
|
||||
{
|
||||
for(Weapon *weapon : weapons)
|
||||
if(weapon->getType() == Weapon::Type::CRUISE_MISSILE)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
return !getWeaponsByOrder(Order::TYPE::HACK).empty();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -88,14 +88,11 @@ namespace battleship{
|
||||
public:
|
||||
class Weapon{
|
||||
public:
|
||||
enum class Type{HITSCAN, SHELL, TORPEDO, CRUISE_MISSILE, HACK};
|
||||
|
||||
Weapon(Unit*, sol::table, int);
|
||||
~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;}
|
||||
inline int getDamage(){return damage;}
|
||||
@@ -104,21 +101,22 @@ namespace battleship{
|
||||
inline Unit* getUnit(){return unit;}
|
||||
inline Order::TYPE getOrderType(){return orderType;}
|
||||
private:
|
||||
Type type;
|
||||
Unit *unit = nullptr;
|
||||
Order::TYPE orderType;
|
||||
int id, projId = -1, rateOfFire, damage = 0;
|
||||
float minRange = 0, maxRange, rotSpeed, maxFireAngle;
|
||||
vb01::Vector3 projPos;
|
||||
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);
|
||||
vb01::Quaternion projRot;
|
||||
vb01::Vector3 projPos;
|
||||
float horConstraint = 1.57, vertConstraint = 1.57;
|
||||
vb01::Node *horNode = nullptr, *vertNode = nullptr, *projPar = nullptr;
|
||||
static std::string LASER_FLAG;
|
||||
|
||||
vb01::Vector3 calcOrientVec(int);
|
||||
void alignNode(vb01::Vector3, vb01::Node*, bool);
|
||||
void initProjectileData(sol::table);
|
||||
void initNode(sol::table);
|
||||
vb01::Node* initNode(sol::table, bool);
|
||||
FxManager::Fx* initFx(sol::table, std::string, bool);
|
||||
void useFx(FxManager::Fx*, vb01::Vector3, bool);
|
||||
inline bool canFire(){return vb01::getTime() - lastFireTime > rateOfFire;}
|
||||
|
||||
Reference in New Issue
Block a user