1
This commit is contained in:
parent
d3d6e91a1a
commit
e6f1defa54
@ -2155,9 +2155,9 @@ bool Human::IsEnemy(Human* hum)
|
||||
}
|
||||
}
|
||||
|
||||
RoomObstacle* Human::SummonObstacle(int equip_id, const a8::Vec2& pos)
|
||||
RoomObstacle* Human::SummonObstacle(int id, const a8::Vec2& pos)
|
||||
{
|
||||
RoomObstacle* obstacle = room->CreateObstacle(equip_id, pos.x, pos.y);
|
||||
RoomObstacle* obstacle = room->CreateObstacle(id, pos.x, pos.y);
|
||||
if (obstacle) {
|
||||
obstacle->master = this;
|
||||
room->xtimer.AddRepeatTimerAndAttach
|
||||
@ -2172,6 +2172,20 @@ RoomObstacle* Human::SummonObstacle(int equip_id, const a8::Vec2& pos)
|
||||
},
|
||||
&obstacle->xtimer_attacher.timer_list_
|
||||
);
|
||||
|
||||
room->xtimer.AddRepeatTimerAndAttach
|
||||
(
|
||||
SERVER_FRAME_RATE,
|
||||
a8::XParams()
|
||||
.SetSender(obstacle),
|
||||
[] (const a8::XParams& param)
|
||||
{
|
||||
RoomObstacle* obstacle = (RoomObstacle*)param.sender.GetUserData();
|
||||
obstacle->UpdateTimerFunc();
|
||||
},
|
||||
&obstacle->xtimer_attacher.timer_list_
|
||||
);
|
||||
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
|
@ -303,7 +303,7 @@ class Human : public MoveableEntity
|
||||
HumanCar& GetCar() { return car_; }
|
||||
void DeadDrop();
|
||||
bool IsEnemy(Human* hum);
|
||||
RoomObstacle* SummonObstacle(int equip_id, const a8::Vec2& pos);
|
||||
RoomObstacle* SummonObstacle(int id, const a8::Vec2& pos);
|
||||
|
||||
protected:
|
||||
void _InternalUpdateMove(float speed);
|
||||
|
@ -102,6 +102,7 @@ void RoomObstacle::ActiveTimerFunc()
|
||||
return;
|
||||
}
|
||||
if (!grid_list_) {
|
||||
temp_through_ = true;
|
||||
grid_list_ = new std::set<GridCell*>();
|
||||
room->grid_service->GetAllCellsByXy(room, GetPos().x, GetPos().y, *grid_list_);
|
||||
}
|
||||
@ -123,6 +124,119 @@ void RoomObstacle::ActiveTimerFunc()
|
||||
}
|
||||
);
|
||||
if (!has_hum) {
|
||||
temp_through_ = false;
|
||||
room->xtimer.DeleteTimer(room->xtimer.GetRunningTimer());
|
||||
}
|
||||
}
|
||||
|
||||
void RoomObstacle::UpdateTimerFunc()
|
||||
{
|
||||
if (grid_list_ && master) {
|
||||
std::set<Human*> human_list;
|
||||
room->grid_service->TouchAllLayerHumanList
|
||||
(room->GetRoomIdx(),
|
||||
*grid_list_,
|
||||
[this, &human_list] (Human* hum, bool& stop)
|
||||
{
|
||||
if (master->team_id != hum->team_id && TestCollision(room, hum)) {
|
||||
human_list.insert(hum);
|
||||
}
|
||||
}
|
||||
);
|
||||
for (Human* hum : human_list) {
|
||||
|
||||
}
|
||||
if (!human_list.empty()) {
|
||||
Explosion();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RoomObstacle::Explosion()
|
||||
{
|
||||
float old_rad = self_collider_->rad;
|
||||
if (self_collider_) {
|
||||
self_collider_->rad = meta->i->damage_dia();
|
||||
}
|
||||
if (meta->i->damage_dia() > 0.01f &&
|
||||
meta->i->damage() > 0.01f) {
|
||||
std::set<Entity*> objects;
|
||||
room->grid_service->TouchAllLayerHumanList
|
||||
(
|
||||
room->GetRoomIdx(),
|
||||
*grid_list_,
|
||||
[this, &objects] (Human* hum, bool& stop)
|
||||
{
|
||||
if (master->team_id != hum->team_id && TestCollision(room, hum)) {
|
||||
objects.insert(hum);
|
||||
}
|
||||
});
|
||||
room->grid_service->TouchAllLayerEntityList
|
||||
(
|
||||
room->GetRoomIdx(),
|
||||
*grid_list_,
|
||||
[this, &objects] (Entity* entity, bool& stop)
|
||||
{
|
||||
switch (entity->GetEntityType()) {
|
||||
case ET_Obstacle:
|
||||
case ET_Building:
|
||||
{
|
||||
if (entity != this && TestCollision(room, entity)) {
|
||||
objects.insert(entity);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
a8::Vec2 bomb_pos = GetPos();
|
||||
room->frame_event.AddExplosionEx(master, meta->i->thing_id(), bomb_pos, 0);
|
||||
for (auto& target : objects) {
|
||||
switch (target->GetEntityType()) {
|
||||
case ET_Player:
|
||||
{
|
||||
Human* hum = (Human*)target;
|
||||
if (!hum->dead) {
|
||||
float dmg = meta->i->damage();
|
||||
float def = hum->ability.def;
|
||||
float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K);
|
||||
hum->DecHP(finaly_dmg, VP_Mine, TEXT("battle_server_killer_mine", "地雷"), VW_Mine);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ET_Obstacle:
|
||||
{
|
||||
Obstacle* obstacle = (Obstacle*)target;
|
||||
if (!obstacle->IsDead(room) &&
|
||||
obstacle->Attackable() &&
|
||||
!obstacle->IsTerminatorAirDropBox(room)) {
|
||||
float dmg = meta->i->damage();
|
||||
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 0
|
||||
bullet->player->DropItems(obstacle);
|
||||
#endif
|
||||
}
|
||||
obstacle->BroadcastFullState(room);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (self_collider_) {
|
||||
self_collider_->rad = old_rad;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,10 @@ class RoomObstacle : public Obstacle
|
||||
virtual bool IsTerminatorAirDropBox(Room* room) override { return is_terminator_airdrop_box; }
|
||||
virtual bool CanThroughable(Human* hum) override;
|
||||
void ActiveTimerFunc();
|
||||
void UpdateTimerFunc();
|
||||
|
||||
private:
|
||||
void Explosion();
|
||||
|
||||
protected:
|
||||
bool temp_through_ = false;
|
||||
|
@ -50,6 +50,7 @@ message MapThing
|
||||
optional int32 is_house = 11; //是否房间
|
||||
optional int32 is_tree = 12; //是否树
|
||||
optional int32 house_id = 13; //房间id
|
||||
repeated int32 buff_list = 14;
|
||||
}
|
||||
|
||||
message SafeArea
|
||||
|
Loading…
x
Reference in New Issue
Block a user