While I understand the best way to implement smoke shells would be via LoS blocking, that isn’t possible right now (w/o rewriting detection system in lua). So here’s another approach.
Basically we can introduce a new weapon, that does almost 0 damage, but has quite a large AoE. Any unit hit by that (detectable with HitByWeaponId) will have its sightdistance set to 0 for the duration of the smoke (and maybe be script-cloaked as well). Another possible effect could be the disabling of LoS weapons for those units (or at least setting them to be highly inaccurate, not sure if accuracy can be affected from script side). Indirect fire weapons (howitzers, mortars and such) should not be affected, as they usually don’t see the target anyway.
So, before an attack, a player can bombard enemy positions with smoke shells, effectively preventing any fire from there for some time. Or a player can shoot some smoke at his own retreating units to hide them from chasing enemy.
This approach has some shortcomings ofc. First, units entering the smoked area after the actual smoke weapon hit will not be affected, and second, smoked areas won’t prevent units from seeing through them, but it still will be a new side to battle.
First drawback can probably be solved with lua, can we detect weapon hits with some callins (as in coordinates of the actual impact point)? Second requires LoS blocking.
We can use a weapon to trigger the smoked area but maintain a table of ‘smoked’ sections of the map in lua, with some timer on the smoke after the weapon detonates. Any unit within a section would have it’s LOS reduced and be cloaked. This can probably be optimized to be a feasible load. Graphical display of it would be somewhat tricky.
The problem with this is that a unit outside the smoke can see another unit outside the smoke on the other side of the smoke cloud, i.e. through the smoke if neither unit is within the smoked sector. The only way around that currently would be pretty horrifically computationally expensive with ray tracing, AFAICS.
edit: Unless we make all smoke clouds larger than the largest LOS of any unit?
I’d say being able to see through the smoke is acceptable given the amount of work it would be to fix that
If accuracy can’t easily be affected it could be idea to make it affect rate of fire instead (just like in/not in supply radius does now.) So dudes inside a smoke screen could fire at, for example, only 50% rate of fire.
Hardly feasible - that would make for gigantic smoke clouds with our current sight ranges. However seeing through the screen should not be that large of a problem.
Explosion() lua callin allows to catch weapon impact coordinates, right? And then some lua can keep a table of those points (with expiration timers) and check for units entering/leaving some radius from them. However that sounds like being O(n*m) computationally expensive (n = unit count, m = active smoke explosion count), so very few weapons should be able to produce smoke.
Spring functions like GetUnitsInRectangle / GetUnitsInSphere do better then this (they use a grid), but (of course) it’s still O(n*m), but with n = number of nearby units.
How to use: add the following to weapon customParams:
smokeRadius = … (in linear units)
smokeDuration = … (in seconds)
After such a weapon hits something, a smoke cloud will be created, with the specified radius, and it will last a specified amount of seconds. Any unit entering the cloud is rendered blind. Sight is restored shortly after leaving the smoke (or the smoke expiring).
What’s still lacking: a visual indication of that same smoke cloud. Currently units just turn blind in the middle of nowhere.
Also, some other effect than just blindness might be desirable, like cloaking and/or accuracy reduction. Maybe smoke moving with the wind?
Technical details: cloud expiration is checked every frame. Units being inside/leaving smoke are checked every second, which should not produce a noticeable CPU load. Multiple simultaneous clouds of different sizes are possible.
Update: made the smoked units cloak (and uncloak when out of smoke). Still no visual effect.
Added a WIP CEG for smokeshells, need to tweak it a bit so its smaller and stays closer to the ground, but yeah.