106 lines
3.4 KiB
C++
106 lines
3.4 KiB
C++
#include "precompile.h"
|
|
|
|
#include "frag_mitask.h"
|
|
#include "room.h"
|
|
#include "player.h"
|
|
#include "metadata.h"
|
|
#include "metamgr.h"
|
|
#include "gridservice.h"
|
|
#include "creature.h"
|
|
#include "obstacle.h"
|
|
|
|
void FragMiTask::Done()
|
|
{
|
|
if (!sender.Get()) {
|
|
return;
|
|
}
|
|
room->frame_event.AddExplosionEx(sender,
|
|
meta->i->id(),
|
|
bomb_pos,
|
|
gun_meta->i->explosion_effect());
|
|
std::set<GridCell*> grid_list;
|
|
sender.Get()->room->grid_service->GetAllCellsByXy
|
|
(
|
|
sender.Get()->room,
|
|
bomb_pos.x,
|
|
bomb_pos.y,
|
|
grid_list
|
|
);
|
|
std::set<Creature*> objects;
|
|
sender.Get()->room->grid_service->TouchCreatures
|
|
(
|
|
sender.Get()->room->GetRoomIdx(),
|
|
grid_list,
|
|
[this, &objects] (Creature* c, bool& stop)
|
|
{
|
|
if (sender.Get()->IsProperTarget(c)) {
|
|
if (bomb_pos.Distance(c->GetPos()) < meta->i->explosion_range()) {
|
|
objects.insert(c);
|
|
}
|
|
}
|
|
}
|
|
);
|
|
std::set<Entity*> entitys;
|
|
sender.Get()->room->grid_service->TouchAllLayerEntityList
|
|
(
|
|
sender.Get()->room->GetRoomIdx(),
|
|
grid_list,
|
|
[this, &entitys] (Entity* entity, bool& stop)
|
|
{
|
|
}
|
|
);
|
|
|
|
for (auto& target : objects) {
|
|
if (target->HasBuffEffect(kBET_Invincible) ||
|
|
target->HasBuffEffect(kBET_AdPlaying)) {
|
|
continue;
|
|
}
|
|
if (sender.Get()->room->GetRoomMode() == kZombieMode &&
|
|
sender.Get()->GetRace() == target->GetRace()) {
|
|
continue;
|
|
}
|
|
if (!target->dead) {
|
|
float dmg = GetAtk() * (1 + sender.Get()->GetAttrRate(kHAT_Atk)) +
|
|
sender.Get()->GetAttrAbs(kHAT_Atk);
|
|
float def = target->ability.def * (1 + target->GetAttrRate(kHAT_Def)) +
|
|
target->GetAttrAbs(kHAT_Def);
|
|
float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K);
|
|
finaly_dmg = std::max(finaly_dmg, 0.0f);
|
|
target->DecHP(finaly_dmg,
|
|
sender.Get()->GetEntityUniId(),
|
|
sender.Get()->GetName(),
|
|
gun_meta->i->id());
|
|
}
|
|
}
|
|
|
|
for (auto& target : entitys) {
|
|
if (target->GetEntityType() != ET_Obstacle) {
|
|
continue;
|
|
}
|
|
Obstacle* obstacle = (Obstacle*)target;
|
|
if (!obstacle->IsDead(room) &&
|
|
obstacle->Attackable() &&
|
|
!obstacle->IsTerminatorAirDropBox(room)) {
|
|
float dmg = GetAtk() * (1 + sender.Get()->GetAttrRate(kHAT_Atk)) +
|
|
sender.Get()->GetAttrAbs(kHAT_Atk);
|
|
float def = 0;
|
|
float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K);
|
|
obstacle->SetHealth(room, std::max(0.0f, obstacle->GetHealth(room) - finaly_dmg));
|
|
if (obstacle->GetHealth(room) <= 0.01f) {
|
|
obstacle->Die(room);
|
|
}
|
|
if (obstacle->IsDead(room)) {
|
|
if (obstacle->meta->i->damage_dia() > 0.01f &&
|
|
obstacle->meta->i->damage() > 0.01f) {
|
|
#if 0
|
|
obstacle->Explosion(this);
|
|
#endif
|
|
}
|
|
sender.Get()->DropItems(obstacle);
|
|
}
|
|
obstacle->BroadcastFullState(room);
|
|
}
|
|
}
|
|
|
|
}
|