#include "expl.hpp"
namespace expl_bank {
void dir_small(CP(Enity) master) {
  if (auto p = add_prt(PRT_WALL_EXPL_1); p) {
    p->phys = Phys(master->phys.pos, master->phys.deg, 3, master->phys.spd);
    p->flags |= EF_NO_SCATTER;
    p->frame_timer = TFC(6);
    p->light = Light(1, TFC(6), 12.0f + a83::frand() * 15.0f);
  }
  scatter_all(master->phys.pos, 750, 17);
}
void mid(CP(Enity) master) {
  if (auto p = add_prt(PRT_WALL_EXPL_2); p) {
    p->phys = Phys(master->phys.pos, master->phys.deg, 1, master->phys.spd),
    p->flags |= EF_R_DEG | EF_NO_SCATTER;
    p->frame_timer = 2.f/30.f;
    p->light = Light(0.3f, 2.0f, 80.0f + a83::frand() * 60.0f);
  }
  scatter_all(master->phys.pos, 180, 50);
}
void dir_big(CP(Enity) master) {
  if (auto p = add_prt(PRT_EXPL_2); p) {
    p->phys = Phys(master->phys.pos, master->phys.deg, 3, master->phys.spd),
    p->frame_timer = 5.f/60.f;
    p->light = Light(1.25f, TFC(10), 105.0f + a83::frand() * 40.0f);
  }
  scatter_all(master->phys.pos, 450, 50);
}
void player_side(CP(Enity) master) {
  if (auto p = add_prt(PRT_EXPL_2); p) {
    p->phys = Phys(master->phys.pos, master->phys.deg),
    p->flags |= EF_NO_MOVE | EF_NO_SCATTER;
    p->frame_timer = TFC(5);
    p->light = Light(1.25f, TFC(10), 105.0f + a83::frand() * 40.0f);
  }
  if (auto p = add_blt(BLT_CIRCLE_17); p) {
    p->phys = master->phys;
    p->flags |= EF_NO_MOVE | EF_DMG_ENEMY | EF_DMG_BULLET
      | EF_NO_KILL | EF_KILL_TIMER | EF_NO_SCATTER;
    p->frame_timer = TFC(3);
  }
  scatter_all(master->phys.pos, 450, 80);
} // player_side
void sphere(CP(Enity) master) {
  if (auto p = add_prt(PRT_SPHERE); p) {
    p->phys = Phys(master->phys.pos);
    p->flags |= EF_R_DEG_ANY;
    p->frame_timer = TFC(1);
    p->light = Light(0.454545f, 0, 180, LF_STAR | LF_INFINITY | LF_RAND);
  }
  if (auto p = add_blt(BLT_CIRCLE_17); p) {
    auto ignore_master = master->flags & EF_IGNORE_MASTER;
    p->phys = master->phys;
    p->flags |= EF_NO_MOVE | EF_DMG_ENEMY | EF_DMG_BULLET
      | EF_NO_KILL | EF_KILL_TIMER | EF_NO_SCATTER | ignore_master;
    p->frame_timer = 0.2f;
    p->master = master->master; 
  }
  scatter_all(master->phys.pos, 120, 60);
} // sphere
void bullet_crush(CP(Enity) master) {
  if (auto p = add_prt(PRT_BULLET_CRUSH); p) {
    p->phys = Phys(master->phys.pos);
    p->flags |= EF_R_DEG | EF_NO_SCATTER;
    p->frame_timer = 1.f/30.f;
    p->blend_mode = BM::diff;
    p->light = Light(0.3f, TFC(2), 15, 0);
  }
  scatter_all(master->phys.pos, 120, 15);
}
void shard_crush(CP(Enity) master) {
  if (auto p = add_prt(PRT_SHARD_CRUSH); p) {
    p->phys = Phys(master->phys.pos);
    p->flags |= EF_NO_SCATTER;
    p->frame_timer = TFC(1);
  }
  scatter_all(master->phys.pos, 600, 15);
}
void small_expl(CP(Enity) master) {
  if (auto p = add_prt(PRT_SMALL_EXPL); p) {
    p->phys = Phys(master->phys.pos, master->phys.deg + a83::sfrand() * 45.0f);
    p->flags |= EF_NO_SCATTER;
    p->frame_timer = TFC(4);
    p->light = Light(0.25f, 0.25f / 5.0f, 30, LF_STAR);
  }
}
void spike_expl(CP(Enity) master) {
  if (auto p = add_prt(PRT_SPIKE_EXPL); p) {
    p->phys = Phys(master->phys.pos, master->phys.deg + a83::sfrand() * 11.125f);
    p->frame_timer = TFC(4);
    p->light = Light(0.6666f, 12, 30);
  }
  scatter_all(master->phys.pos, 800, 26);
}
void spike_expl_plr(CP(Enity) master) {
  if (auto p = add_prt(PRT_SMALL_EXPL); p) {
    p->phys = Phys(master->phys.pos,
      master->phys.deg + a83::sfrand() * 45.0f, 1, master->phys.spd);
    p->frame_timer = 0.05f;
    p->flags |= EF_NO_SCATTER;
    p->light = Light(0.25f, 3, 30, LF_STAR);
  }
  scatter_all(master->phys.pos, 400, 30);
}
void wave(CP(Enity) master) {
  if (auto p = add_prt(ENI_NONE); p) {
    p->phys = master->phys;
    p->frame_timer = TFC(60);
    p->flags |= EF_KILL_TIMER | EF_NO_MOVE | EF_NO_SCATTER;
    p->light = Light(1, TFC(20), 256, 0);
    p->haze = Haze(TFC(40), 30, 6, 64, 256, HF_LENDOWN);
  }
}
void plr(CP(Enity) master) {
  //! дым
  FOR (i, 24) {
    if (auto p = add_blt(BLT_FLAME); p) {
      p->phys = Phys(Vec::make_rand_by_radius(master->phys.pos, 7),
        rand_deg(), 1, a83::frand() * 450.0f);
      p->phys.add_vec(master->phys);
      p->flags |= EF_DMG_ENEMY | EF_DMG_BULLET | EF_IGNORE_SELF_ID
        | EF_KILL_TIMER | EF_NO_SCATTER;
      p->frame_timer = TFC(5) + a83::frand() * TFC(10);
      p->smoke = smoke_bank::flame;
      p->expl = expl_bank::bullet_crush;
      p->light = Light(1, 0, 7, LF_INFINITY | LF_RAND);
    }
  }
  // закручивающийся след
  FOR (i, 6) {
    if (auto p = add_blt(BLT_FLAME); p) {
      p->phys = Phys(Vec::make_rand_by_radius(master->phys.pos, 14),
        rand_deg(), 1, a83::frand() * 600.0f);
      p->phys.add_vec(master->phys);
      p->flags |= EF_DMG_ENEMY | EF_DMG_BULLET | EF_IGNORE_SELF_ID | EF_R_DEG
        | EF_KILL_TIMER | EF_NO_SCATTER;
      p->smoke = smoke_bank::small;
      p->expl = expl_bank::bullet_crush;
      p->frame_timer = TFC(15) + a83::frand() * TFC(10);
      p->light = Light(1, 0, 7, LF_INFINITY | LF_NOSTAR | LF_RAND);
    }
  }
  //! дамажащий радиус
  if (auto p = add_blt(BLT_CIRCLE_37); p) {
    p->phys = master->phys;
    p->flags |= EF_DMG_ENEMY | EF_DMG_BULLET | EF_NO_SCATTER | EF_NO_MOVE;
    p->frame_timer = TFC(5);
  }
  scatter_all(master->phys.pos, 1500, 135);
  expl_bank::wave(master);
} // plr
void airbomb_frag(CP(Enity) master) {
  constexpr auto count = 7; // число осколков
  if (auto p = add_prt(PRT_EXPL_2); p) {
    p->phys = master->phys;
    p->frame_timer = TFC(2.5f);
    FOR (i, count)
      if (auto blt = add_blt(BLT_FRAG); blt) {
        blt->phys = Phys(master->phys.pos, rand_deg(), 0.5f,
          a83::frand() * 260.f);
        blt->phys.add_vec(master->phys);
        blt->frame_timer = TFC(6);
        blt->flags |= EF_DMG_ENEMY | EF_DMG_PLAYER | EF_DMG_BULLET
          | EF_IGNORE_SELF_ID;
        blt->smoke = smoke_bank::small;
        blt->expl = expl_bank::plr;
        blt->pf1 = &Enity::rand_spin;
        blt->data0.f1 = 2000; // скорость вращения rand_spin
        blt->pf0 = &Enity::kill_by_timer;
        blt->data0.f0 = 1.0f + a83::frand() * 0.66666f; // время до взрыва
      } // if add_blt
  }
  scatter_all(master->phys.pos, 300, 32);
} // airbomb_frag
} // <---- expl_bank ns