diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index d37cf1fc8..8f6f87767 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -14,6 +14,7 @@ Version 1.8.1 (not released yet) - Change default 'Use' key to E - Fix "Play (camera)" editor button for level filenames with spaces - Fix a patch for a possible buffer overflow in "Play" editor button caused by a long filepath +- Fix cull radius for particle emitters with growing particles Version 1.8.0 (released 2022-09-17) ----------------------------------- diff --git a/game_patch/object/particle.cpp b/game_patch/object/particle.cpp index 41ba799a8..6a2e7e6fa 100644 --- a/game_patch/object/particle.cpp +++ b/game_patch/object/particle.cpp @@ -52,12 +52,26 @@ CodeInjection particle_should_take_damage_injection{ } }; -CodeInjection particle_move_all_update_world_pos_fix{ - 0x004964AE, +CodeInjection particle_emitter_update_cull_radius_injection{ + 0x00497E13, [](auto& regs) { rf::ParticleEmitter* emitter = regs.esi; - rf::Vector3 dir; - emitter->get_pos_and_dir(&emitter->world_pos, &dir); + rf::Vector3 pos, dir; + emitter->get_pos_and_dir(&pos, &dir); + + rf::Particle *p = emitter->particle_list.next; + float max_dist_sq = 0.0f; + float max_pradius = 0.0; + + while (p != &emitter->particle_list) { + float dist_sq = (p->pos - pos).len_sq(); + max_dist_sq = std::max(max_dist_sq, dist_sq); + max_pradius = std::max(max_pradius, p->radius); + p = p->next; + } + + emitter->cull_radius = std::sqrt(max_dist_sq) + max_pradius; + regs.eip = 0x00497E2E; }, }; @@ -81,6 +95,6 @@ void particle_do_patch() // Do not create not damaging particles on a dedicated server particle_create_hook.install(); - // Fix cull radius calculation for particle emitters attached to objects - particle_move_all_update_world_pos_fix.install(); + // Fix cull radius calculation for particle emitters + particle_emitter_update_cull_radius_injection.install(); }