explosion
This commit is contained in:
parent
18a0c5eeb7
commit
1a9f70be47
@ -132,7 +132,9 @@ void Bullet::ProcBomb()
|
||||
{
|
||||
//榴弹炮
|
||||
a8::Vec2 bomb_pos = GetPos();
|
||||
room->frame_event.AddExplosionEx(sender, meta->i->id(), bomb_pos,
|
||||
room->frame_event.AddExplosionEx(sender,
|
||||
meta->i->id(),
|
||||
bomb_pos,
|
||||
gun_meta->i->explosion_effect());
|
||||
OnHit(objects);
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "perfmonitor.h"
|
||||
#include "typeconvert.h"
|
||||
#include "bullet.h"
|
||||
#include "explosion.h"
|
||||
|
||||
Car::Car():Creature()
|
||||
{
|
||||
@ -334,7 +335,13 @@ void Car::BeKill(int killer_id, const std::string& killer_name, int weapon_id)
|
||||
passenger->RemoveBuffByEffectId(kBET_Passenger);
|
||||
room->frame_event.AddCarChg(passenger->GetWeakPtrRef());
|
||||
}
|
||||
Explosion(team_id);
|
||||
Explosion explosion;
|
||||
explosion.IndifferenceAttack(
|
||||
room,
|
||||
GetPos(),
|
||||
meta->i->explosion_range(),
|
||||
meta->i->atk(),
|
||||
meta->i->explosion_effect());
|
||||
}
|
||||
|
||||
void Car::GetAabbBox(AabbCollider& aabb_box)
|
||||
@ -347,46 +354,6 @@ void Car::GetAabbBox(AabbCollider& aabb_box)
|
||||
aabb_box._max.y = hero_meta_->i->radius();
|
||||
}
|
||||
|
||||
void Car::Explosion(int team_id)
|
||||
{
|
||||
if (meta->i->explosion_range() <= 0) {
|
||||
return;
|
||||
}
|
||||
std::set<Creature*> objects;
|
||||
TraverseProperTargetsNoTeammate
|
||||
(
|
||||
[this, &objects, team_id] (Creature* c, bool& stop)
|
||||
{
|
||||
float distance = (c->GetPos() - GetPos()).Norm();
|
||||
if (distance < meta->i->explosion_range()) {
|
||||
objects.insert(c);
|
||||
}
|
||||
});
|
||||
room->frame_event.AddExplosionEx(GetWeakPtrRef(),
|
||||
0,
|
||||
GetPos(),
|
||||
meta->i->explosion_effect());
|
||||
for (auto& target : objects) {
|
||||
switch (target->GetEntityType()) {
|
||||
case ET_Player:
|
||||
{
|
||||
Human* hum = (Human*)target;
|
||||
if (!hum->dead) {
|
||||
float dmg = meta->i->atk();
|
||||
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;
|
||||
default:
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Car::SendDebugMsg(const std::string& debug_msg)
|
||||
{
|
||||
#if 1
|
||||
|
@ -47,7 +47,6 @@ class Car : public Creature
|
||||
private:
|
||||
int AllocSeat();
|
||||
void BeKill(int killer_id, const std::string& killer_name, int weapon_id);
|
||||
void Explosion(int team_id);
|
||||
bool IsPassenger(Human* hum);
|
||||
private:
|
||||
long long born_frameno_ = 0;
|
||||
|
@ -347,6 +347,30 @@ enum OptResult
|
||||
kOptBreak = 2
|
||||
};
|
||||
|
||||
enum BulletHit_e
|
||||
{
|
||||
kBulletHitPass = 1,
|
||||
kBulletHitAnyDmg = 2,
|
||||
kBulletHitOnlySpecDmg = 3,
|
||||
kBulletHitEatDmg = 4,
|
||||
};
|
||||
|
||||
enum CollisionHit_e
|
||||
{
|
||||
kCollisionHitPass = 1,
|
||||
kCollisionHitBlock = 2,
|
||||
kCollisionHitDeadAndDrop = 3,
|
||||
kCollisionHitSpecEvent = 4,
|
||||
};
|
||||
|
||||
enum ExplosionHit_e
|
||||
{
|
||||
kExplosionHitPass = 1,
|
||||
kExplosionHitAnyDmg = 2,
|
||||
kExplosionHitOnlySpecDmg = 3,
|
||||
kExplosionHitEatDmg = 4,
|
||||
};
|
||||
|
||||
const char* const PROJ_NAME_FMT = "game%d_gameserver";
|
||||
const char* const PROJ_ROOT_FMT = "/data/logs/%s";
|
||||
|
||||
|
@ -12,6 +12,7 @@ class AabbCollider;
|
||||
class CircleCollider;
|
||||
class Human;
|
||||
class Bullet;
|
||||
class Explosion;
|
||||
class Entity
|
||||
{
|
||||
public:
|
||||
@ -33,6 +34,7 @@ class Entity
|
||||
virtual void OnPreCollision(Room* room) {};
|
||||
virtual void RecalcSelfCollider() {};
|
||||
virtual void OnBulletHit(Bullet* bullet) {};
|
||||
virtual void OnExplosionHit(Explosion* explosion) {};
|
||||
virtual void OnAddToTargetPartObject(Entity* target) {};
|
||||
virtual void OnRemoveFromTargetPartObject(Entity* target) {};
|
||||
virtual bool CanSeeMe(Human* hum) { return true; };
|
||||
|
110
server/gameserver/explosion.cc
Normal file
110
server/gameserver/explosion.cc
Normal file
@ -0,0 +1,110 @@
|
||||
#include "precompile.h"
|
||||
|
||||
#include "explosion.h"
|
||||
|
||||
void Explosion::IndifferenceAttack(Room* room,
|
||||
const a8::Vec2& center,
|
||||
float range,
|
||||
int explosion_effect,
|
||||
float dmg)
|
||||
{
|
||||
#if 0
|
||||
if (meta->i->explosion_range() <= 0) {
|
||||
return;
|
||||
}
|
||||
std::set<Creature*> objects;
|
||||
TraverseProperTargetsNoTeammate
|
||||
(
|
||||
[this, &objects, team_id] (Creature* c, bool& stop)
|
||||
{
|
||||
float distance = (c->GetPos() - GetPos()).Norm();
|
||||
if (distance < meta->i->explosion_range()) {
|
||||
objects.insert(c);
|
||||
}
|
||||
});
|
||||
room->frame_event.AddExplosionEx(GetWeakPtrRef(),
|
||||
0,
|
||||
GetPos(),
|
||||
meta->i->explosion_effect());
|
||||
for (auto& target : objects) {
|
||||
switch (target->GetEntityType()) {
|
||||
case ET_Player:
|
||||
{
|
||||
Human* hum = (Human*)target;
|
||||
if (!hum->dead) {
|
||||
float dmg = meta->i->atk();
|
||||
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;
|
||||
default:
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Explosion::EnemyAndObstacleAttack(CreatureWeakPtr& sender,
|
||||
const a8::Vec2& center,
|
||||
float range,
|
||||
int explosion_effect,
|
||||
float dmg)
|
||||
{
|
||||
#if 0
|
||||
if (!sender.Get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (follow_target.Get()) {
|
||||
bomb_pos = follow_target.Get()->GetPos();
|
||||
}
|
||||
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->TraverseCreatures
|
||||
(
|
||||
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->TraverseAllLayerEntityList
|
||||
(
|
||||
sender.Get()->room->GetRoomIdx(),
|
||||
grid_list,
|
||||
[this, &entitys] (Entity* entity, bool& stop)
|
||||
{
|
||||
}
|
||||
);
|
||||
|
||||
Explosion explosion;
|
||||
for (auto& target : objects) {
|
||||
target->OnExplosionHit(&explosion);
|
||||
}
|
||||
|
||||
for (auto& target : entitys) {
|
||||
target->OnExplosionHit(&explosion);
|
||||
}
|
||||
#endif
|
||||
}
|
19
server/gameserver/explosion.h
Normal file
19
server/gameserver/explosion.h
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "weakptr.h"
|
||||
|
||||
class Room;
|
||||
class Explosion
|
||||
{
|
||||
public:
|
||||
void IndifferenceAttack(Room* room,
|
||||
const a8::Vec2& center,
|
||||
float range,
|
||||
int explosion_effect,
|
||||
float dmg);
|
||||
void EnemyAndObstacleAttack(CreatureWeakPtr& sender,
|
||||
const a8::Vec2& center,
|
||||
float range,
|
||||
int explosion_effect,
|
||||
float dmg);
|
||||
};
|
@ -8,100 +8,19 @@
|
||||
#include "gridservice.h"
|
||||
#include "creature.h"
|
||||
#include "obstacle.h"
|
||||
#include "explosion.h"
|
||||
|
||||
void FragMiTask::Done()
|
||||
{
|
||||
if (!sender.Get()) {
|
||||
return;
|
||||
}
|
||||
a8::Vec2 center = bomb_pos;
|
||||
if (follow_target.Get()) {
|
||||
bomb_pos = follow_target.Get()->GetPos();
|
||||
}
|
||||
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->TraverseCreatures
|
||||
(
|
||||
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->TraverseAllLayerEntityList
|
||||
(
|
||||
sender.Get()->room->GetRoomIdx(),
|
||||
grid_list,
|
||||
[this, &entitys] (Entity* entity, bool& stop)
|
||||
{
|
||||
}
|
||||
);
|
||||
|
||||
for (auto& target : objects) {
|
||||
if (target->IsInvincible()) {
|
||||
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()->GetUniId(),
|
||||
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(sender.Get()) &&
|
||||
!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);
|
||||
}
|
||||
}
|
||||
|
||||
Explosion explosion;
|
||||
explosion.EnemyAndObstacleAttack(sender,
|
||||
center,
|
||||
meta->i->explosion_range(),
|
||||
gun_meta->i->explosion_effect(),
|
||||
GetAtk());
|
||||
}
|
||||
|
@ -165,7 +165,9 @@ bool Hero::IsCollisionInMapService()
|
||||
return true;
|
||||
}
|
||||
if (!obstacle->IsDead(room) &&
|
||||
#if 0
|
||||
obstacle->Attackable(this) &&
|
||||
#endif
|
||||
obstacle->meta->i->drop() != 0 &&
|
||||
obstacle->IsTouchInteraction() &&
|
||||
room->GetGasData().gas_mode != GasInactive &&
|
||||
|
@ -525,7 +525,9 @@ bool Human::IsCollisionInMapService()
|
||||
return true;
|
||||
}
|
||||
if (!obstacle->IsDead(room) &&
|
||||
#if 0
|
||||
obstacle->Attackable(this) &&
|
||||
#endif
|
||||
obstacle->meta->i->drop() != 0 &&
|
||||
obstacle->IsTouchInteraction() &&
|
||||
room->GetGasData().gas_mode != GasInactive &&
|
||||
@ -3598,6 +3600,37 @@ void Human::OnBulletHit(Bullet* bullet)
|
||||
}
|
||||
}
|
||||
|
||||
void Human::OnExplosionHit(Explosion* explosion)
|
||||
{
|
||||
if (IsInvincible()) {
|
||||
return;
|
||||
}
|
||||
if (dead) {
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
if (target->IsInvincible()) {
|
||||
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()->GetUniId(),
|
||||
sender.Get()->GetName(),
|
||||
gun_meta->i->id());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Human::SendRollMsgEx(KillInfo& info,
|
||||
const char* fmt,
|
||||
std::initializer_list<a8::XValue> args
|
||||
|
@ -141,6 +141,7 @@ class Human : public Creature
|
||||
virtual bool IsDead(Room* room) override;
|
||||
virtual long long GetDeadFrameNo(Room* room) override;
|
||||
virtual void OnBulletHit(Bullet* bullet) override;
|
||||
virtual void OnExplosionHit(Explosion* explosion) override;
|
||||
void FillItemList(::google::protobuf::RepeatedPtrField<::cs::MFPair>* pb_item_list);
|
||||
long long GetRealDeadFrameNo(Room* room);
|
||||
void FillMFTeamData(cs::MFTeamData* team_data, bool is_game_over);
|
||||
|
@ -356,6 +356,7 @@ Obstacle* MapInstance::InternalCreateObstacle(int id, float x, float y, int coll
|
||||
grid_service_->AddPermanentEntity(entity);
|
||||
}
|
||||
{
|
||||
#if 0
|
||||
switch (thing->i->attack_type()) {
|
||||
case 0:
|
||||
{
|
||||
@ -377,6 +378,7 @@ Obstacle* MapInstance::InternalCreateObstacle(int id, float x, float y, int coll
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
++obstacle_num_;
|
||||
}
|
||||
return entity;
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "perfmonitor.h"
|
||||
#include "roomobstacle.h"
|
||||
#include "loot.h"
|
||||
#include "explosion.h"
|
||||
|
||||
enum ObstacleDataFlags_e
|
||||
{
|
||||
@ -108,7 +109,7 @@ void Obstacle::RecalcSelfCollider()
|
||||
collider->tag = collider_tag;
|
||||
collider->param1 = collider_param1;
|
||||
collider->param2 = collider_param2;
|
||||
if (meta->i->attack_type() == 3) {
|
||||
if (IsHalfWallCollider()) {
|
||||
a8::SetBitFlag(collider->tag, kHalfWallTag);
|
||||
}
|
||||
}
|
||||
@ -289,112 +290,6 @@ void Obstacle::OnPreCollision(Room* room)
|
||||
}
|
||||
}
|
||||
|
||||
void Obstacle::Explosion(Bullet* bullet)
|
||||
{
|
||||
Room* room = bullet->room;
|
||||
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;
|
||||
std::set<GridCell*> tmp_grids;
|
||||
room->grid_service->GetAllCellsByXy(room, GetX(), GetY(), tmp_grids);
|
||||
room->grid_service->TraverseAllLayerHumanList
|
||||
(
|
||||
room->GetRoomIdx(),
|
||||
tmp_grids,
|
||||
[this, room, &objects] (Human* hum, bool& stop)
|
||||
{
|
||||
if (TestCollision(room, hum)) {
|
||||
objects.insert(hum);
|
||||
}
|
||||
});
|
||||
room->grid_service->TraverseAllLayerEntityList
|
||||
(
|
||||
room->GetRoomIdx(),
|
||||
tmp_grids,
|
||||
[this, room, &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();
|
||||
#if 1
|
||||
room->frame_event.AddExplosionEx(bullet->sender,
|
||||
meta->i->thing_id(),
|
||||
bomb_pos,
|
||||
meta->i->explosion_effect());
|
||||
#else
|
||||
room->frame_event.AddExplosion(bullet, meta->i->thing_id(), bomb_pos);
|
||||
#endif
|
||||
for (auto& target : objects) {
|
||||
switch (target->GetEntityType()) {
|
||||
case ET_Player:
|
||||
{
|
||||
Human* hum = (Human*)target;
|
||||
if (!hum->dead && hum->team_id != team_id_) {
|
||||
float dmg = meta->i->damage();
|
||||
float def = hum->ability.def;
|
||||
float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K);
|
||||
if (GetMasterId(bullet->room)) {
|
||||
Human* master = bullet->room->GetHumanByUniId(GetMasterId(bullet->room));
|
||||
if (master) {
|
||||
hum->DecHP(finaly_dmg, master->GetUniId(), master->GetName(), VW_Mine);
|
||||
} else {
|
||||
hum->DecHP(finaly_dmg, VP_Mine, TEXT("battle_server_killer_mine", "地雷"), VW_Mine);
|
||||
}
|
||||
} else {
|
||||
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(this) &&
|
||||
!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->health_ - finaly_dmg));
|
||||
if (obstacle->GetHealth(room) <= 0.01f) {
|
||||
obstacle->Die(room);
|
||||
}
|
||||
if (obstacle->IsDead(room)) {
|
||||
bullet->sender.Get()->DropItems(obstacle);
|
||||
}
|
||||
obstacle->BroadcastFullState(room);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (self_collider_) {
|
||||
self_collider_->rad = old_rad;
|
||||
}
|
||||
}
|
||||
|
||||
void Obstacle::SetDoorInfo(Building* building, int door_id_x)
|
||||
{
|
||||
MetaData::Building::Door* door_meta = &building->meta->doors[door_id_x];
|
||||
@ -509,35 +404,11 @@ bool Obstacle::IsPermanent()
|
||||
return is_permanent;
|
||||
}
|
||||
|
||||
bool Obstacle::Attackable(Entity* sender)
|
||||
{
|
||||
switch (meta->i->attack_type()) {
|
||||
case 1:
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
//只有特定子弹
|
||||
if (sender->IsEntityType(ET_Bullet)) {
|
||||
Bullet* bullet = (Bullet*)sender;
|
||||
return ((bullet->gun_meta->special_damage_type & meta->receive_special_damage_type) != 0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Obstacle::Throughable()
|
||||
{
|
||||
#if 0
|
||||
return meta->i->attack_type() == 2;
|
||||
#endif
|
||||
}
|
||||
|
||||
int Obstacle::GetTeamId(Room* room)
|
||||
@ -599,7 +470,6 @@ void Obstacle::SetMasterId(Room* room, int master_id)
|
||||
void Obstacle::OnBulletHit(Bullet* bullet)
|
||||
{
|
||||
if (!IsDead(bullet->room) &&
|
||||
Attackable(bullet) &&
|
||||
!IsTerminatorAirDropBox(bullet->room)) {
|
||||
if (meta->receive_special_damage_type != 0 &&
|
||||
((bullet->gun_meta->special_damage_type & meta->receive_special_damage_type) == 0)) {
|
||||
@ -640,7 +510,13 @@ void Obstacle::OnBulletHit(Bullet* bullet)
|
||||
if (IsDead(bullet->room)) {
|
||||
if (meta->i->damage_dia() > 0.01f &&
|
||||
meta->i->damage() > 0.01f) {
|
||||
Explosion(bullet);
|
||||
Explosion explosion;
|
||||
explosion.IndifferenceAttack(
|
||||
bullet->room,
|
||||
GetPos(),
|
||||
meta->i->damage_dia(),
|
||||
meta->i->damage(),
|
||||
meta->i->explosion_effect());
|
||||
}
|
||||
bullet->sender.Get()->DropItems(this);
|
||||
}
|
||||
@ -658,20 +534,62 @@ void Obstacle::OnBulletHit(Bullet* bullet)
|
||||
}
|
||||
}
|
||||
|
||||
void Obstacle::OnExplosionHit(Explosion* e)
|
||||
{
|
||||
#if 0
|
||||
if (!target->IsEntityType(Obstacle)) {
|
||||
continue;
|
||||
}
|
||||
Obstacle* obstacle = (Obstacle*)target;
|
||||
if (obstacle->IsDead(room)) {
|
||||
continue;
|
||||
}
|
||||
if (obstacle->meta->i->explosion_hit() == kExplosionHitPass ||
|
||||
obstacle->meta->i->explosion_hit() == kExplosionHitEatDmg) {
|
||||
continue;
|
||||
}
|
||||
if (obstacle->Attackable(sender.Get()) &&
|
||||
!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);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Obstacle::CanThroughable(Creature* c)
|
||||
{
|
||||
#if 0
|
||||
if (meta->i->attack_type() == 4) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Obstacle::CanThroughable(Bullet* bullet)
|
||||
{
|
||||
#if 0
|
||||
if (meta->i->attack_type() == 4) {
|
||||
return !(meta->receive_special_damage_type != 0 &&
|
||||
((bullet->gun_meta->special_damage_type & meta->receive_special_damage_type) != 0));
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -744,7 +662,9 @@ void Obstacle::OnCollisionTrigger(Creature* c, OptResult& opt_result)
|
||||
{
|
||||
if (c->team_id != GetTeamId(c->room)) {
|
||||
AddObstacleBuff(c);
|
||||
#if 0
|
||||
Explosion();
|
||||
#endif
|
||||
Die(c->room);
|
||||
BroadcastFullState(c->room);
|
||||
}
|
||||
@ -858,3 +778,9 @@ bool Obstacle::CanSeeMe(Human* hum)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool Obstacle::IsHalfWallCollider()
|
||||
{
|
||||
return meta->i->collision_hit() == kCollisionHitPass &&
|
||||
meta->i->bullet_hit() != kBulletHitPass;
|
||||
}
|
||||
|
@ -42,14 +42,13 @@ class Obstacle : public Entity
|
||||
virtual long long GetDeadFrameNo(Room* room) override;
|
||||
virtual void OnPreCollision(Room* room) override;
|
||||
virtual void OnBulletHit(Bullet* bullet) override;
|
||||
virtual void OnExplosionHit(Explosion* explosion) override;
|
||||
virtual bool IsTerminatorAirDropBox(Room* room) { return false; }
|
||||
virtual bool CanThroughable(Creature* c);
|
||||
virtual bool CanThroughable(Bullet* bullet);
|
||||
virtual bool DoInteraction(Human* sender);
|
||||
virtual void OnCollisionTrigger(Creature* c, OptResult& opt_result);
|
||||
virtual void Explosion() {};
|
||||
virtual bool CanSeeMe(Human* hum);
|
||||
void Explosion(Bullet* bullet);
|
||||
void SetDoorInfo(Building* building, int door_id_x);
|
||||
bool IsDoor();
|
||||
DoorState_e GetDoorState(Room* room);
|
||||
@ -67,7 +66,6 @@ class Obstacle : public Entity
|
||||
int GetMasterId(Room* room);
|
||||
void SetMasterId(Room* room, int master_id);
|
||||
bool IsPermanent();
|
||||
bool Attackable(Entity* sender);
|
||||
bool Throughable();
|
||||
bool IsTouchInteraction();
|
||||
bool IsOpenInteraction();
|
||||
@ -80,6 +78,7 @@ protected:
|
||||
std::tuple<long long, a8::Vec2>* GetInteractionData(Human* sender);
|
||||
void AddObstacleBuff(Creature* c);
|
||||
void ClearObstacleBuff(Creature* c);
|
||||
bool IsHalfWallCollider();
|
||||
|
||||
protected:
|
||||
CircleCollider* self_collider_ = nullptr;
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "bullet.h"
|
||||
#include "mapservice.h"
|
||||
#include "roomobstacle.h"
|
||||
#include "explosion.h"
|
||||
|
||||
RoomObstacle::RoomObstacle():Obstacle()
|
||||
{
|
||||
@ -94,7 +95,7 @@ void RoomObstacle::RecalcSelfCollider()
|
||||
collider->tag = collider_tag;
|
||||
collider->param1 = collider_param1;
|
||||
collider->param2 = collider_param2;
|
||||
if (meta->i->attack_type() == 3) {
|
||||
if (IsHalfWallCollider()) {
|
||||
a8::SetBitFlag(collider->tag, kHalfWallTag);
|
||||
}
|
||||
}
|
||||
@ -163,8 +164,16 @@ void RoomObstacle::UpdateTimerFunc()
|
||||
}
|
||||
}
|
||||
}
|
||||
Explosion();
|
||||
Die(room);
|
||||
{
|
||||
Explosion explosion;
|
||||
explosion.IndifferenceAttack(
|
||||
room,
|
||||
GetPos(),
|
||||
meta->i->damage_dia(),
|
||||
meta->i->damage(),
|
||||
meta->i->explosion_effect());
|
||||
}
|
||||
BroadcastFullState(room);
|
||||
if (room->xtimer.GetRunningTimer()) {
|
||||
room->xtimer.DeleteTimer(room->xtimer.GetRunningTimer());
|
||||
@ -175,102 +184,6 @@ void RoomObstacle::UpdateTimerFunc()
|
||||
}
|
||||
}
|
||||
|
||||
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->TraverseAllLayerHumanList
|
||||
(
|
||||
room->GetRoomIdx(),
|
||||
*grid_list_,
|
||||
[this, &objects] (Human* hum, bool& stop)
|
||||
{
|
||||
if (master.Get()->team_id != hum->team_id && TestCollision(room, hum)) {
|
||||
objects.insert(hum);
|
||||
}
|
||||
});
|
||||
room->grid_service->TraverseAllLayerEntityList
|
||||
(
|
||||
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,
|
||||
meta->i->explosion_effect());
|
||||
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);
|
||||
if (master.Get()) {
|
||||
hum->DecHP(finaly_dmg, master.Get()->GetUniId(), master.Get()->GetName(), VW_Mine);
|
||||
} else {
|
||||
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(this) &&
|
||||
!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;
|
||||
}
|
||||
}
|
||||
|
||||
void RoomObstacle::SpecExplosion()
|
||||
{
|
||||
++explosion_times_;
|
||||
@ -284,58 +197,13 @@ void RoomObstacle::SpecExplosion()
|
||||
bomb_born_offset.Rotate(a8::RandAngle());
|
||||
bomb_born_offset = bomb_born_offset * a8::RandEx(1, std::max(2, meta->i->explosion_float()));
|
||||
a8::Vec2 bomb_pos = GetPos() + bomb_born_offset;
|
||||
std::set<Entity*> objects;
|
||||
Creature* dumy_c = nullptr;
|
||||
room->grid_service->TraverseAllLayerHumanList
|
||||
(
|
||||
room->GetRoomIdx(),
|
||||
*grid_list_,
|
||||
[this, &objects, &bomb_pos, &dumy_c] (Human* hum, bool& stop)
|
||||
{
|
||||
if (!dumy_c) {
|
||||
dumy_c = hum;
|
||||
}
|
||||
float distance = (hum->GetPos() - bomb_pos).Norm();
|
||||
if ((!master.Get() || master.Get()->team_id != hum->team_id) &&
|
||||
distance < meta->i->damage_dia()) {
|
||||
dumy_c = hum;
|
||||
objects.insert(hum);
|
||||
}
|
||||
});
|
||||
if (dumy_c) {
|
||||
room->frame_event.AddExplosionEx(dumy_c->GetWeakPtrRef(),
|
||||
meta->i->thing_id(),
|
||||
bomb_pos,
|
||||
meta->i->explosion_effect());
|
||||
}
|
||||
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);
|
||||
|
||||
for (int buff_id : meta->buff_list) {
|
||||
MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff(buff_id);
|
||||
if (buff_meta) {
|
||||
hum->AddBuff(master.Get(),
|
||||
buff_meta,
|
||||
1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
Explosion explosion;
|
||||
explosion.IndifferenceAttack(
|
||||
room,
|
||||
bomb_pos,
|
||||
meta->i->damage_dia(),
|
||||
meta->i->damage(),
|
||||
meta->i->explosion_effect());
|
||||
}
|
||||
if (explosion_times_ >= meta->i->explosion_times()) {
|
||||
room->xtimer.DeleteTimer(room->xtimer.GetRunningTimer());
|
||||
|
@ -25,7 +25,6 @@ class RoomObstacle : public Obstacle
|
||||
void Active();
|
||||
void DetachFromMaster();
|
||||
virtual void Die(Room* room) override;
|
||||
virtual void Explosion() override;
|
||||
Entity* GetRealObject(Room* room);
|
||||
|
||||
private:
|
||||
|
@ -52,7 +52,6 @@ message MapThing
|
||||
optional float damage = 6; //伤害
|
||||
optional float damage_dia = 7; //伤害半径
|
||||
optional int32 drop = 8; //掉落
|
||||
optional int32 attack_type = 9; //是否可攻击 0:不可破坏对象 1:可破坏对象 2:可穿透对象
|
||||
optional int32 is_door = 10; //是否门
|
||||
optional int32 is_house = 11; //是否房间
|
||||
optional int32 is_tree = 12; //是否树
|
||||
|
Loading…
x
Reference in New Issue
Block a user