Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ This page lists all the individual contributions to the project by their author.
- Weapon owner detachment
- Feedback weapon
- TerrainType & ore minimap color customization
- Laser fixes & improvements
- **Morton (MortonPL)**:
- `XDrawOffset`
- Shield passthrough & absorption
Expand Down
10 changes: 10 additions & 0 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,16 @@ In `rulesmd.ini`:
DetachedFromOwner=false ; boolean
```

### Single-color lasers

- You can now set laser to draw using only `LaserInnerColor` by setting `IsSingleColor`, in same manner as `IsHouseColor` lasers do using player's team color. These lasers respect laser thickness.

In `rulesmd.ini`:
```ini
[SOMEWEAPON] ; WeaponType
IsSingleColor=false ; boolean
```

### Toggle-able ElectricBolt visuals

- You can now specify individual ElectricBolt bolts you want to disable. Note that this is only a visual change.
Expand Down
2 changes: 2 additions & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ New:
- Weapon owner detachment (by Starkku)
- Feedback weapon (by Starkku)
- TerrainType & ore minimap color customization (by Starkku)
- Single-color weapon lasers (by Starkku)

Vanilla fixes:
- Fixed laser drawing code to allow for thicker lasers in house color draw mode (by Kerbiter, ChrisLv_CN)
Expand All @@ -314,6 +315,7 @@ Phobos fixes:
- Fixed shielded objects not decloaking if shield takes damage (by Starkku)
- Fixed critical hit animation playing even if no critical hits were dealt due to `Crit.Affects` or `ImmuneToCrit` settings (by Starkku)
- Fixed `RemoveDisguise` not working on `PermaDisguise` infantry (by Starkku)
- Fixed single-color laser (IsHouseColor, IsSingleColor, LaserTrails) glow falloff to match the vanilla appearance (by Starkku)
</details>


Expand Down
14 changes: 14 additions & 0 deletions src/Ext/Techno/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,3 +445,17 @@ DEFINE_HOOK(0x6FF43F, TechnoClass_FireAt_FeedbackWeapon, 0x6)

return 0;
}

DEFINE_HOOK(0x6FD446, TechnoClass_FireLaser_IsSingleColor, 0x7)
{
GET(WeaponTypeClass* const, pWeapon, ECX);
GET(LaserDrawClass* const, pLaser, EAX);

if (auto const pWeaponExt = WeaponTypeExt::ExtMap.Find(pWeapon))
{
if (!pLaser->IsHouseColor && pWeaponExt->Laser_IsSingleColor)
pLaser->IsHouseColor = true;
}

return 0;
}
2 changes: 2 additions & 0 deletions src/Ext/WeaponType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ void WeaponTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
this->AreaFire_Target.Read(exINI, pSection, "AreaFire.Target");
this->DetachedFromOwner.Read(exINI, pSection, "DetachedFromOwner");
this->FeedbackWeapon.Read(exINI, pSection, "FeedbackWeapon", true);
this->Laser_IsSingleColor.Read(exINI, pSection, "IsSingleColor");
}

template <typename T>
Expand All @@ -67,6 +68,7 @@ void WeaponTypeExt::ExtData::Serialize(T& Stm)
.Process(this->AreaFire_Target)
.Process(this->DetachedFromOwner)
.Process(this->FeedbackWeapon)
.Process(this->Laser_IsSingleColor)
;
};

Expand Down
4 changes: 3 additions & 1 deletion src/Ext/WeaponType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ class WeaponTypeExt
Valueable<AreaFireTarget> AreaFire_Target;
Valueable<bool> DetachedFromOwner;
Nullable<WeaponTypeClass*> FeedbackWeapon;

Valueable<bool> Laser_IsSingleColor;

ExtData(WeaponTypeClass* OwnerObject) : Extension<WeaponTypeClass>(OwnerObject)
, DiskLaser_Radius { 38.2 }
, DiskLaser_Circumference { 240 }
Expand All @@ -49,6 +50,7 @@ class WeaponTypeExt
, AreaFire_Target { AreaFireTarget::Base }
, DetachedFromOwner { false }
, FeedbackWeapon {}
, Laser_IsSingleColor { false }
{ }

virtual ~ExtData() = default;
Expand Down
12 changes: 7 additions & 5 deletions src/Misc/Hooks.LaserDraw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <GeneralStructures.h>
#include <Utilities/Debug.h>
#include <Utilities/Macro.h>
#include <Utilities/GeneralUtils.h>

namespace LaserDrawTemp
{
Expand All @@ -26,13 +27,14 @@ DEFINE_HOOK(0x550F47, LaserDrawClass_DrawInHouseColor_BetterDrawing, 0x0)
GET(LaserDrawClass*, pThis, EBX);
GET_STACK(int, currentThickness, 0x5C)

// Map value from range of [1, Thickness] to [0, pi/2]
double x = 0;
double mult = 1.0;
if (pThis->Thickness > 1)
x = Math::HalfPi * (currentThickness - 1) / (pThis->Thickness - 1);
{
double falloffStep = 1.0 / pThis->Thickness;
double falloffMult = GeneralUtils::FastPow(1.0 - falloffStep, currentThickness);
mult = (1.0 - falloffStep * currentThickness) * falloffMult;
}

// Cosine function for falloff
double mult = Math::cos(x);
unsigned int r = (unsigned int)(mult * LaserDrawTemp::maxColor.R);
unsigned int g = (unsigned int)(mult * LaserDrawTemp::maxColor.G);
unsigned int b = (unsigned int)(mult * LaserDrawTemp::maxColor.B);
Expand Down
14 changes: 14 additions & 0 deletions src/Utilities/GeneralUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,17 @@ int GeneralUtils::ChooseOneWeighted(const double dice, const std::vector<int>* w

return -1;
}

// Direct multiplication pow
double GeneralUtils::FastPow(double x, double n)
{
double r = 1.0;

while (n > 0)
{
r *= x;
--n;
}

return r;
}
2 changes: 1 addition & 1 deletion src/Utilities/GeneralUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ class GeneralUtils
static std::vector<CellStruct> AdjacentCellsInRange(unsigned int range);
static const int GetRangedRandomOrSingleValue(Point2D range);
static const double GetWarheadVersusArmor(WarheadTypeClass* pWH, Armor ArmorType);

static int ChooseOneWeighted(const double dice, const std::vector<int>* weights);
static double FastPow(double x, double n);
};