From 93db1a3eff35cf6ea26bb3b29547859096282dfb Mon Sep 17 00:00:00 2001 From: Ion Agorria Date: Tue, 23 Apr 2024 19:24:29 +0200 Subject: [PATCH] ET units / Lighting gun improvements --- Source/Render/src/lighting.cpp | 48 +++++--- Source/Render/src/lighting.h | 8 +- Source/Units/IronLegion.cpp | 14 ++- Source/Units/RealUnit.cpp | 11 +- Source/Units/SecondGun.cpp | 202 ++++++++++++++++++--------------- 5 files changed, 161 insertions(+), 122 deletions(-) diff --git a/Source/Render/src/lighting.cpp b/Source/Render/src/lighting.cpp index 2a0bb243d..8dc2c4516 100644 --- a/Source/Render/src/lighting.cpp +++ b/Source/Render/src/lighting.cpp @@ -5,19 +5,21 @@ LightingParameters::LightingParameters() { - generate_time=0.1f; + generate_time=0.100f; //How often generate new pattern texture_name="RESOURCE\\Effect\\freeze.tga"; - strip_width_begin=5; - strip_width_time=15; - strip_length=40; - fade_time=0.5f; - lighting_amplitude=40; + strip_width_begin=2.5f; + strip_width_time=5.0f; + strip_length=30.0f; //How long each segment will be + fade_time=0.150f; + min_amplitude=4.0f; //The min width that the arc pattern will have from the line center + max_amplitude=8.0f; //The max width that the arc pattern will have from the line center } cLighting::cLighting() :cIUnkClass(0) { time=0; + scaler=1.0f; pTexture=GetTexLibrary()->GetElement(param.texture_name.c_str()); } @@ -61,7 +63,7 @@ void cLighting::Draw(cCamera *pCamera) void cLighting::OneLight::Draw(cCamera *pCamera,cLighting* parent) { /* - sColor4c color(255,255,255); + sColor4c color(255,255,255, 255); for(int i=1;iSetWorldMat4f(nullptr); DrawBuffer* db = gb_RenderDevice->GetDrawBuffer(sVertexXYZDT1::fmt, PT_TRIANGLESTRIP); - float size=parent->param.strip_width_begin+time*parent->param.strip_width_time; + float scale = max(1.0f, parent->scaler * 0.5f); + float size = parent->param.strip_width_begin * scale; + size += time * parent->param.strip_width_time * scale; sVertexXYZDT1 *vb = db->LockTriangleStripSteps(strip_list.size()); for (size_t i = 0; i < strip_list.size(); ++i) { const OneStrip& p = strip_list[i]; @@ -161,11 +165,12 @@ void cLighting::Animate(float dt) } } -void cLighting::Init(Vect3f pos_begin_, std::vector& pos_end_) +void cLighting::Init(Vect3f pos_begin_, std::vector& pos_end_, float scaler_) { global_pos.set(Mat3f::ID,pos_begin); pos_begin=pos_begin_; pos_end=pos_end_; + scaler=scaler_; xassert(!pos_end.empty()); } @@ -203,12 +208,13 @@ void cLighting::OneLight::Generate(Vect3f pos_begin_,Vect3f pos_end_,cCamera *pC std::vector pos(size+2); pos[0]=pos[pos.size()-1]=0; - float amplitude=parent->param.lighting_amplitude; - for(int i=2;i<=size;i*=2) - { - GenerateInterpolate(pos,i,amplitude); - amplitude*=0.5f; - } + float min_amp=parent->param.min_amplitude * parent->scaler; + float max_amp=min(min_amp * parent->scaler, parent->param.max_amplitude); + for(int i=2;i<=size;i*=2) { + GenerateInterpolate(pos,i,min_amp,max_amp); + min_amp *= 0.5f; + max_amp *= 0.75f; + } Vect3f tangent=pos_end-pos_begin; tangent.Normalize(); @@ -231,14 +237,20 @@ void cLighting::OneLight::Generate(Vect3f pos_begin_,Vect3f pos_end_,cCamera *pC BuildStrip(pCamera,parent); } -void cLighting::OneLight::GenerateInterpolate(std::vector& pos,int size,float amplitude) +void cLighting::OneLight::GenerateInterpolate(std::vector& pos,int size,float min_amp, float max_amp) { RandomGenerator& r=xm_random_generator; std::vector p(size);\ int i; - for(i=0;i& pos_end); + void Init(Vect3f pos_begin, std::vector& pos_end,float scaler); void SetParameters(LightingParameters& param_); virtual void PreDraw(cCamera *UCamera); @@ -31,6 +32,7 @@ class cLighting:public cIUnkClass protected: void Generate(Vect3f pos_begin,Vect3f pos_end,cCamera *pCamera); float time; + float scaler; MatXf global_pos; Vect3f pos_begin; std::vector pos_end; @@ -56,7 +58,7 @@ class cLighting:public cIUnkClass void Generate(Vect3f pos_begin,Vect3f pos_end,cCamera *pCamera,cLighting* parent); void Draw(cCamera *pCamera,cLighting* parent); void Animate(float dt); - void GenerateInterpolate(std::vector& pos,int size,float amplitude); + void GenerateInterpolate(std::vector& pos,int size,float min_amp, float max_amp); float get(std::vector& p,float t); void BuildStrip(cCamera *pCamera,cLighting* parent); diff --git a/Source/Units/IronLegion.cpp b/Source/Units/IronLegion.cpp index 0d75ff6b6..c9198a93e 100644 --- a/Source/Units/IronLegion.cpp +++ b/Source/Units/IronLegion.cpp @@ -111,9 +111,17 @@ void terUnitLegionary::AvatarQuant() avatar()->Show(); realAvatar()->setSight(SightFactor); - realAvatar()->setHeal(HealFactor); - realAvatar()->setFreeze(FreezeFactor); - realAvatar()->setHot(HotFactor); + + float maxFactor = 1.0f; + //Conductors have electro effect in mesh that becomes red when hot, mitigate this + const AttributeLegionary* attrs = attr(); + if (attrs && attrs->ID == UNIT_ATTRIBUTE_CONDUCTOR) { + maxFactor = 0.5f; + } + + realAvatar()->setHeal(min(HealFactor, maxFactor)); + realAvatar()->setFreeze(min(FreezeFactor, maxFactor)); + realAvatar()->setHot(min(HotFactor, maxFactor)); if(MoveSoundPoint){ MoveSoundPoint->setVolume(SpeedFactor); diff --git a/Source/Units/RealUnit.cpp b/Source/Units/RealUnit.cpp index 9dfe5eae4..b518c74d5 100644 --- a/Source/Units/RealUnit.cpp +++ b/Source/Units/RealUnit.cpp @@ -399,9 +399,9 @@ void terUnitReal::Quant() if(HotCount > 0){ HotCount--; HotFactor = 1.0f; - } - else - average(HotFactor,0, 0.3f); + } else { + average(HotFactor, 0, 0.3f); + } if(weapon_) weapon_->quant(); @@ -1223,8 +1223,9 @@ void terUnitReal::freeZeroLayer() void terUnitReal::handleLaserHit() { terEffectControllerList::iterator it = find(effectControllers_.begin(),effectControllers_.end(),EFFECT_ID_LASER_HIT); - if(it != effectControllers_.end()) - it->createEffect(this); + if (it != effectControllers_.end()) { + it->createEffect(this); + } } void terUnitReal::fireStop() diff --git a/Source/Units/SecondGun.cpp b/Source/Units/SecondGun.cpp index 94786176a..e9bb64b92 100644 --- a/Source/Units/SecondGun.cpp +++ b/Source/Units/SecondGun.cpp @@ -186,7 +186,7 @@ class AimControllerBase { public: AimControllerBase(terUnitBase* owner) : owner_(owner){ } - virtual ~AimControllerBase(){ } + virtual ~AimControllerBase() = default; terUnitBase* owner() const { xassert(owner_); return owner_; } @@ -216,23 +216,31 @@ class AimControllerOmnidirectional : public AimControllerBase { public: AimControllerOmnidirectional(terUnitBase* owner) : AimControllerBase(owner) { } - ~AimControllerOmnidirectional(){ } + ~AimControllerOmnidirectional() override = default; - bool init(cLogicObject* logic_root,cObjectNodeRoot* model_root,const terWeaponControllerSetup& setup){ return true; } + bool init(cLogicObject* logic_root,cObjectNodeRoot* model_root,const terWeaponControllerSetup& setup) override { + return true; + } - void updateLogic(){ } + void updateLogic() override { } - void avatarQuant(){ } - void avatarInterpolation(){ } + void avatarQuant() override { } + void avatarInterpolation() override { } - void aim(float psi,float theta){ } - bool isAimed(float psi,float theta) const { return true; } - bool isAimed(float psi,float theta,int& fire_status) const { return true; } + void aim(float psi,float theta) override { } + bool isAimed(float psi,float theta) const override { return true; } + bool isAimed(float psi,float theta,int& fire_status) const override { return true; } - void aimDefault(){ } + void aimDefault() override { } - bool getTargetingPosition(Vect3f& targeting0,Vect3f& targeting1) const { targeting0 = owner()->position(); targeting1 = owner()->position() + Vect3f::K; return true; } - void getGunPosition(Vect3f& pos) const { pos = owner()->position(); } + bool getTargetingPosition(Vect3f& targeting0,Vect3f& targeting1) const override { + targeting0 = owner()->position(); + targeting1 = owner()->position() + Vect3f::K; + return true; + } + void getGunPosition(Vect3f& pos) const override { + pos = owner()->position(); + } private: }; @@ -241,24 +249,23 @@ class AimControllerDirectional : public AimControllerBase { public: AimControllerDirectional(terUnitBase* owner) : AimControllerBase(owner), targetingObject_(NULL) { } - ~AimControllerDirectional(){ } + ~AimControllerDirectional() = default; - bool init(cLogicObject* logic_root,cObjectNodeRoot* model_root,const terWeaponControllerSetup& setup); + bool init(cLogicObject* logic_root,cObjectNodeRoot* model_root,const terWeaponControllerSetup& setup) override; - void updateLogic(){ psi_.updateLogic(Z_AXIS); theta_.updateLogic(X_AXIS); } + void updateLogic() override { psi_.updateLogic(Z_AXIS); theta_.updateLogic(X_AXIS); } - void avatarQuant(){ psi_.avatarQuant(); theta_.avatarQuant(); } - void avatarInterpolation(){ psi_.avatarInterpolation(Z_AXIS); theta_.avatarInterpolation(X_AXIS); } + void avatarQuant() override { psi_.avatarQuant(); theta_.avatarQuant(); } + void avatarInterpolation() override { psi_.avatarInterpolation(Z_AXIS); theta_.avatarInterpolation(X_AXIS); } - void aim(float psi,float theta){ psi_.change(psi); theta_.change(theta); } - bool isAimed(float psi,float theta) const { return (psi_ == psi && theta_ == theta); } - bool isAimed(float psi,float theta,int& fire_status) const; + void aim(float psi,float theta) override { psi_.change(psi); theta_.change(theta); } + bool isAimed(float psi,float theta) const override { return (psi_ == psi && theta_ == theta); } + bool isAimed(float psi,float theta,int& fire_status) const override; - void aimDefault(){ psi_.changeToDefault(); theta_.changeToDefault(); } + void aimDefault() override { psi_.changeToDefault(); theta_.changeToDefault(); } - bool getTargetingPosition(Vect3f& targeting0,Vect3f& targeting1) const; - void getGunPosition(Vect3f& pos) const - { + bool getTargetingPosition(Vect3f& targeting0,Vect3f& targeting1) const override; + void getGunPosition(Vect3f& pos) const override { owner()->avatar()->updateLogicObject(); if(theta_.logicObjectPosition(pos)) return; @@ -279,25 +286,25 @@ class WeaponDerivedBase : public terWeapon { public: WeaponDerivedBase(terUnitReal* owner) : terWeapon(owner), aimController_(owner), turnSuggestPrm_(NULL){ turnSuggestPrm_ = owner->attr()->weaponSetup.turnSuggestPrm; } - ~WeaponDerivedBase(){ } + ~WeaponDerivedBase() override = default; - bool init(){ + bool init() override { xassert(owner()->attr()->weaponSetup.enabled()); if(!terWeapon::init()) return false; return aimController_.init(owner()->LogicObjectPoint,owner()->avatar()->GetModelPoint(),owner()->attr()->weaponSetup.controllerSetup); } - void updateLogic(){ if(isEnabled()) aimController_.updateLogic(); } + void updateLogic() override { if(isEnabled()) aimController_.updateLogic(); } - void avatarQuant(){ if(isEnabled()) aimController_.avatarQuant(); } - void avatarInterpolation(){ if(isEnabled()) aimController_.avatarInterpolation(); } + void avatarQuant() override { if(isEnabled()) aimController_.avatarQuant(); } + void avatarInterpolation() override { if(isEnabled()) aimController_.avatarInterpolation(); } protected: const AimControllerBase* aimController() const { return &aimController_; } - bool aim(const Vect3f& to,int& status){ + bool aim(const Vect3f& to,int& status) override { float psi,theta; if(turnSuggestPrm_) @@ -318,7 +325,7 @@ class WeaponDerivedBase : public terWeapon return ret; } - void aimDefault(){ aimController_.aimDefault(); } + void aimDefault() override { aimController_.aimDefault(); } const RigidBodyPrm* turnSuggestPrm() const { return turnSuggestPrm_; } @@ -338,8 +345,8 @@ class terWeaponArtillery : public WeaponDirectionalBase { public: terWeaponArtillery(terUnitReal* owner) : WeaponDirectionalBase(owner) { } - bool fire(const Vect3f& to,terUnitBase* target); - int estimatedDamage() const; + bool fire(const Vect3f& to,terUnitBase* target) override; + int estimatedDamage() const override; }; /// Оружие, стреляющее ракетами. @@ -347,15 +354,15 @@ class terWeaponLauncher : public WeaponDirectionalBase { public: terWeaponLauncher(terUnitReal* owner); - bool fire(const Vect3f& to,terUnitBase* target); - int estimatedDamage() const; + bool fire(const Vect3f& to,terUnitBase* target) override; + int estimatedDamage() const override; - void moveQuant(); + void moveQuant() override; - bool isLoaded() const { return (WeaponDirectionalBase::isLoaded() && owner()->isDockReady(missileIndex_)); } - void enable(); + bool isLoaded() const override { return (WeaponDirectionalBase::isLoaded() && owner()->isDockReady(missileIndex_)); } + void enable() override; - void unload(); + void unload() override; private: @@ -369,14 +376,14 @@ class terWeaponLaser : public WeaponDirectionalBase public: terWeaponLaser(terUnitReal* owner); - void avatarQuant(); + void avatarQuant() override; - bool fire(const Vect3f& to,terUnitBase* target); - bool fireTest(const Vect3f& to,terUnitBase* target,int& status) const; + bool fire(const Vect3f& to,terUnitBase* target) override; + bool fireTest(const Vect3f& to,terUnitBase* target,int& status) const override; - int estimatedDamage() const; + int estimatedDamage() const override; - void disable(); + void disable() override; }; /// Замораживающее оружие - стреляет как лазер, лишает на время способности атаковать. @@ -385,7 +392,7 @@ class terWeaponFreezeLaser : public terWeaponLaser public: terWeaponFreezeLaser(terUnitReal* owner) : terWeaponLaser(owner) { } - bool fire(const Vect3f& to,terUnitBase* target); + bool fire(const Vect3f& to,terUnitBase* target) override; }; class terWeaponHealLaser : public terWeaponLaser @@ -393,7 +400,7 @@ class terWeaponHealLaser : public terWeaponLaser public: terWeaponHealLaser(terUnitReal* owner) : terWeaponLaser(owner) { } - bool fire(const Vect3f& to,terUnitBase* target); + bool fire(const Vect3f& to,terUnitBase* target) override; }; /// Электроразрядник - бьёт врага молнией. @@ -401,19 +408,20 @@ class terWeaponLighting : public WeaponDirectionalBase { public: terWeaponLighting(terUnitReal* owner); - ~terWeaponLighting(); + ~terWeaponLighting() override; void quant(); - bool fire(const Vect3f& to,terUnitBase* target); - bool fireTest(const Vect3f& to,terUnitBase* target,int& status) const; + bool fire(const Vect3f& to,terUnitBase* target) override; + //bool fireRequest(const Vect3f* to,terUnitBase* target,int& status) override; + bool fireTest(const Vect3f& to,terUnitBase* target,int& status) const override; - int estimatedDamage() const; + int estimatedDamage() const override; - void destroyLink(); + void destroyLink() override; - void kill(); - void disable(); + void kill() override; + void disable() override; private: /// визуализация молнии @@ -422,11 +430,10 @@ class terWeaponLighting : public WeaponDirectionalBase /// цель terUnitBase* target_; - bool releaseLighting() - { + bool releaseLighting() { if(lighting_){ lighting_->Release(); - lighting_ = 0; + lighting_ = nullptr; return true; } @@ -444,10 +451,10 @@ class terWeaponPiercer : public WeaponOmnidirectionalBase public: terWeaponPiercer(terUnitReal* owner) : WeaponOmnidirectionalBase(owner), targetPos_(0,0,0) { fire_ = false; } - void quant(); + void quant() override ; - bool fire(const Vect3f& to,terUnitBase* target); - int estimatedDamage() const { return 0; } + bool fire(const Vect3f& to,terUnitBase* target) override ; + int estimatedDamage() const override { return 0; } private: @@ -1591,10 +1598,10 @@ void terWeaponConductor::quant() } } - lighting_->Init(v0, vect); - } - else - releaseLighting(); + lighting_->Init(v0, vect, (setup().laserWidth / 2.0f) * 10.0f); + } else { + releaseLighting(); + } } bool terWeaponConductor::fire(const Vect3f& to,terUnitBase* target) @@ -2145,8 +2152,8 @@ bool terWeaponInvisibilityGenerator::fire(const Vect3f& to,terUnitBase* target) //------------------------------------------------------- terWeaponLighting::terWeaponLighting(terUnitReal* owner) : WeaponDirectionalBase(owner), - target_(NULL), - lighting_(NULL) + lighting_(nullptr), + target_(nullptr) { } @@ -2158,35 +2165,42 @@ void terWeaponLighting::quant() { WeaponDirectionalBase::quant(); - if(isSwitchedOn() && target_ && owner()->alive()){ + if (isSwitchedOn() && target_ && owner()->alive() && isFireAnimationPlaying()) { xassert(owner()); + + if (lighting_) { + Vect3f v0,v1; + aimController()->getTargetingPosition(v0,v1); + v1 = target_->position(); + + std::vector vect; + vect.push_back(v1); + //On default ET AttrLib Eflair has 2.0, Impaler 4.0 + lighting_->Init(v0, vect, setup().laserWidth / 2.0f); + } - if(isFireAnimationPlaying()){ - if(fireEnabled()){ - target_->SetHotCount(5); - target_->setDamage(owner()->damageData(),owner()); - owner()->DestroyLink(); - destroyLink(); - if(!target_) - return; - } - - if(!lighting_){ - lighting_ = new cLighting; - terScene->AttachObj(lighting_); - } - - Vect3f v0,v1; - aimController()->getTargetingPosition(v0,v1); - v1 = target_->position(); - - std::vector vect; - vect.push_back(v1); - lighting_->Init(v0, vect); - } - } - else - releaseLighting(); + if (fireEnabled()) { + startFireDelay(); + + //If lighting is not created we don't damage, so we give enough time for it to show + //the fire is delayed thanks to startFireDelay() so it wont kill before arc is displayed + if (!lighting_) { + lighting_ = new cLighting; + terScene->AttachObj(lighting_); + } else { + target_->SetHotCount(5); + target_->setDamage(owner()->damageData(), owner()); + + owner()->DestroyLink(); + destroyLink(); + if (!target_) { + return; + } + } + } + } else if (lighting_) { + releaseLighting(); + } } bool terWeaponLighting::fire(const Vect3f& to,terUnitBase* target) @@ -2199,7 +2213,9 @@ bool terWeaponLighting::fire(const Vect3f& to,terUnitBase* target) bool terWeaponLighting::fireTest(const Vect3f& to,terUnitBase* target,int& status) const { - if(!WeaponDirectionalBase::fireTest(to,target,status)) return false; + if (!WeaponDirectionalBase::fireTest(to,target,status)) { + return false; + } xassert(owner());