// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv CHAIN LIGHTNING START vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv { m_timed_block("Chain lightning"); auto chain_lightnings = &game->chain_lightnings; for(int i = 0; i < chain_lightnings->count; i++) { s_chain_lightning* cl = arr_get(chain_lightnings, i); assert(cl->times_chained < cl->max_chains); b8 remove = false; int target = get_closest_non_hit_enemy(enemies, cells, cl->pos.xy, cl->already_hit.elements, cl->already_hit.count, cl->chain_range, frame_arena); if(target == invalid_entity) { remove = true; } else { assert(enemies->active[target]); assert(enemies->flags[target][e_entity_flag_hittable]); #if IS_CLIENT take_damage(game, enemies, map, target, cl->damage, cl->armor_pen, cl->source, cl->push_dir, network, false, cl->crit_count, game->towers.kill_count); s_visual_effect ve = zero; ve.type = e_visual_effect_lightning; ve.duration = 0.25f; ve.from = enemies->pos[target] + rand_v3(&game->client_rng) * 0.1f + v3(0, 0, enemies->size[target].z * 0.6f); ve.to = cl->pos + rand_v3(&game->client_rng) * 0.1f + v3(0, 0, enemies->size[target].z * 0.6f); ve.color = BLUE; add_visual_effect(&game->transient.visual_effects, &ve); #else // IS_CLIENT take_damage(game, enemies, map, target, cl->damage, cl->armor_pen, cl->source, cl->push_dir, frame_arena, network, false, cl->crit_count, game->towers.kill_count); #endif // NOT IS_CLIENT arr_add(&cl->already_hit, s_enemy_ref(enemies, target)); // @Note(tkap, 15/06/2022): This means there is a cap of 64 chains on chain lightning if(cl->already_hit.count >= cl->already_hit.max_elements) { remove = true; } cl->pos = enemies->pos[target]; cl->times_chained += 1; } if(cl->times_chained >= cl->max_chains) { remove = true; } if(remove) { arr_remove_and_swap(chain_lightnings, i); i -= 1; } } } // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ CHAIN LIGHTNING END ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^