Sorry I didn't see that link to tigsource!
Anyway, it looks good! I don't know Operation Carnage, but I loved Smash TV. ^^
Try it! It's abandonware (free) and a lot of fun.
http://www.midnightsynergy.com/ancient.htm---
Today I spent all day on a weapon system.
It sucks, it introduces unnecessary complexity and makes heavy use of capturing lambdas... but:
* Creating new weapons is very easy
* Weapons have a lot of flexibility (it's not a bunch of parameters, it's a lambda that can do anything)
* Thanks to value semantics, I can have copies of weapons with slight variations
* I can easily give an enemy, the player or a turret a certain weapon both at compile-time and run-time and it will work
Example code explained:
1. Notice the return type, `OBWpn`. It's not a reference or a pointer, it's a copy. This allows, for example, to have an enemy use a special version of an existing weapon.
2. For simple weapons, such as the first one (`EPlasmaBulletGun`), the `onShoot` delegate does not capture anything. Non-capturing lambdas with
Don Clugston's fast delegates get inlined by clang++ as a normal function call. Yes. (g++ does a worse job, but it's still faster than capturing lambdas).
3. Every projectile the weapon creates goes through `mWpn.shotProjectile`, which fires a callback other entities can attach to. So I could have a "piercing bullets power-up", that, when active, attaches to `OBWpn::onShotProjectile(OBCProjectile&)` delegate, and sets every spawned projectile as piercing.
4. In case of a power-up that modifies the way the weapon shoots, and not projectile parameters, there is a similar delegate in `OBCWpnController`, a component attached to entities with guns that controls fire delay and contains a `OBWpn` object.
So, let's analyze `createEPlasmaGun(int mFanCount)`.
The first instruction creates a `OBWpn` object called result, with parameters:
* Shoot delay: 75.f
* Projectile damage: 1.f
* Projectile speed: 260.f
* Sound ID: "Sounds/machineGun.wav"
The second instruction subscribes (`+=`) a capturing lambda to the weapon's `onShoot` delegate. Inside the lambda we tell the weapon to create `PJStarPlasma` projectiles and fire them in a fan-like formation. When the shots have been fired, we adjust their speed so that "outer" shoots are slower.
Then we return the weapon to the caller.
It works, but it's
very messy. Does anyone have any suggestion on how to improve it?