I've been doing a bit of messing around in the code to try to implement one of the previous mechanics in AI War 1, knockback (or translocating shots ala AI War 1). There's some moderate success so far:
https://youtu.be/LRzaRUalo3c - Video demonstrating the knockback working properly ( Knockback = 3000, mass limit = 5 )
There's also some issues and concerns with my code as it is currently:
1. If the shot kills the ship outright and there's another ship stacked inside of it, the stacked ship doesn't inherit knockback
(fixed for stacks, leaving unchanged for ships that spawn on death (hydra heads))2. As seen in the video, ships that are knocked back kinda pause for a moment before moving again.
3. As a concern, I'm not really sure if this will play well in multiplayer when it comes out (momentary desyncs)
4. Minor concern that I'll probably ignore, if a weapon has AoE and hits a bunch of ships under a shield... the knockback on the shield would be pretty insane since it stacks linearly. ( 3000 knockback with 800 range AoE -
https://youtu.be/zz-bxcihMLQ )
5. The way movement planning is coded now, ships can't preemptively "move forward" to counteract the knockback, they will only start moving back into range on the next frame.
How it functions so far:
1. base_knockback_per_shot="some positive or negative integer" and knockback_to_ships_mass_tx_less_than="some mass value" must be defined in the XML, optionally added_knockback_per_shot_per_mark="some positive or negative integer". Positive numbers for knockback to push away, negative to pull towards.
2. If the ship is mobile, not protected by a shield (but it can push back things with bubble shields), and has less or equal mass than the number defined (and some other fail conditions I'm forgetting right now) then knockback is calculated. The formula is: Knockback Distance = (base + per_mark * mark level) * ( 1 - (target ship mass / (mass limit * 2)) ). So a ship can receive between 100% and 50% of the knockback depending on how heavy it is, to differentiate weights.
3. The knockback from multiple shots in a frame gets pooled together, and is then applied during movement planning for the next frame. For Chris - this knockback arcenpoint is pooled, cleared from pool, and serialized, but I'm still unsure of how to test if its working properly.
The Guts (Arcen people PM me on the forum and I can provide my source files if you want to help out and look)
ArcenCore:
EntitySystemTypeData: Added the variables BaseKnockbackPerShot, AddedKnockbackPerShot, and KnockbackPerShotToShipsMass_tXLessThan. XML reading is set up, and knockback total is calculated in the ForMark section
EntitySystem: Added public int GetKnockbackPowerAgainst, returning the knockback from the above equation if it passes checks
GameEntity_Squad: Added public ArcenPoint KnockbackToBeAppliedNextFrame, public void TakeKnockback that adds to the ArcenPoint, and added a TakeKnockback call to TakeDamage for when protecting shields take damage, and when unprotected ships take damage. TakeKnockback also accepts an optional override angle for knocking in other directions, set the override to a negative number to calculate normally.
ArcenExternal:
MovementPlanning: Added Inner_HandleSquadKnockback that gets called at the very beginning of movement planning for each ship. If that ships' KnockbackToBeAppliedNextFrame.X != 0, set FramePlan_DoMove to true, and set up NextMovePoint and CurrentPlannedMove to current position + knockback offset. After that, do the normal movement code; if the code were to report CurrentPlannedMove=ZeroZeroPoint, it first checks that DoMove is still false so it doesn't cancel knockback. When calculating the next move for the frame at the very end, it adds the knockback to the resulting point (you will get knocked back farther if moving away, knocked back less if moving towards it).