1
This commit is contained in:
parent
1a9f70be47
commit
dab0a0d303
@ -2047,3 +2047,31 @@ void Creature::FindLocation()
|
|||||||
FindLocationWithTarget(target);
|
FindLocationWithTarget(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Creature::Attackable(Room* room)
|
||||||
|
{
|
||||||
|
if (dead) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (a8::HasBitFlag(status, CS_Disable)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (IsInvincible()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (HasBuffEffect(kBET_Hide)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (HasBuffEffect(kBET_Driver)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (HasBuffEffect(kBET_Passenger)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Creature::ReceiveExplosionDmg(Explosion* explosion)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -84,6 +84,8 @@ class Creature : public MoveableEntity
|
|||||||
virtual void RemoveObjects(Entity* entity) {};
|
virtual void RemoveObjects(Entity* entity) {};
|
||||||
virtual void AddOutObjects(Entity* entity) {};
|
virtual void AddOutObjects(Entity* entity) {};
|
||||||
virtual void RemoveOutObjects(Entity* entity) {};
|
virtual void RemoveOutObjects(Entity* entity) {};
|
||||||
|
virtual bool Attackable(Room* room) override;
|
||||||
|
virtual bool ReceiveExplosionDmg(Explosion* explosion) override;
|
||||||
bool HasBuffEffect(int buff_effect_id);
|
bool HasBuffEffect(int buff_effect_id);
|
||||||
Buff* GetBuffByEffectId(int effect_id);
|
Buff* GetBuffByEffectId(int effect_id);
|
||||||
Buff* GetBuffById(int buff_id);
|
Buff* GetBuffById(int buff_id);
|
||||||
|
@ -38,6 +38,8 @@ class Entity
|
|||||||
virtual void OnAddToTargetPartObject(Entity* target) {};
|
virtual void OnAddToTargetPartObject(Entity* target) {};
|
||||||
virtual void OnRemoveFromTargetPartObject(Entity* target) {};
|
virtual void OnRemoveFromTargetPartObject(Entity* target) {};
|
||||||
virtual bool CanSeeMe(Human* hum) { return true; };
|
virtual bool CanSeeMe(Human* hum) { return true; };
|
||||||
|
virtual bool Attackable(Room* room) { return false; };
|
||||||
|
virtual bool ReceiveExplosionDmg(Explosion* explosion) { return false; };
|
||||||
int GetUniId() const { return uniid_; }
|
int GetUniId() const { return uniid_; }
|
||||||
EntityType_e GetEntityType() const { return entity_type_; }
|
EntityType_e GetEntityType() const { return entity_type_; }
|
||||||
EntitySubType_e GetEntitySubType() const { return entity_subtype_; }
|
EntitySubType_e GetEntitySubType() const { return entity_subtype_; }
|
||||||
|
@ -1,110 +1,115 @@
|
|||||||
#include "precompile.h"
|
#include "precompile.h"
|
||||||
|
|
||||||
#include "explosion.h"
|
#include "explosion.h"
|
||||||
|
#include "creature.h"
|
||||||
|
#include "room.h"
|
||||||
|
|
||||||
|
enum ExplosionType_e
|
||||||
|
{
|
||||||
|
kExplosionIndifference = 1,
|
||||||
|
kExplosionEnemyAndObstacle = 2
|
||||||
|
};
|
||||||
|
|
||||||
void Explosion::IndifferenceAttack(Room* room,
|
void Explosion::IndifferenceAttack(Room* room,
|
||||||
const a8::Vec2& center,
|
const a8::Vec2& center,
|
||||||
float range,
|
float explosion_range,
|
||||||
int explosion_effect,
|
int explosion_effect,
|
||||||
float dmg)
|
float dmg,
|
||||||
|
long long special_damage_type)
|
||||||
{
|
{
|
||||||
#if 0
|
type_ = kExplosionIndifference;
|
||||||
if (meta->i->explosion_range() <= 0) {
|
room_ = room;
|
||||||
return;
|
explosion_range_ = explosion_range;
|
||||||
}
|
explosion_effect_ = explosion_effect;
|
||||||
std::set<Creature*> objects;
|
dmg_ = dmg;
|
||||||
TraverseProperTargetsNoTeammate
|
center_ = center;
|
||||||
(
|
special_damage_type_ = special_damage_type;
|
||||||
[this, &objects, team_id] (Creature* c, bool& stop)
|
InternalAttack();
|
||||||
{
|
|
||||||
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,
|
void Explosion::EnemyAndObstacleAttack(CreatureWeakPtr& sender,
|
||||||
const a8::Vec2& center,
|
const a8::Vec2& center,
|
||||||
float range,
|
float explosion_range,
|
||||||
int explosion_effect,
|
int explosion_effect,
|
||||||
float dmg)
|
float dmg,
|
||||||
|
long long special_damage_type)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
if (!sender.Get()) {
|
if (!sender.Get()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
type_ = kExplosionEnemyAndObstacle;
|
||||||
|
room_ = sender.Get()->room;
|
||||||
|
sender_ = sender;
|
||||||
|
explosion_range_ = explosion_range;
|
||||||
|
explosion_effect_ = explosion_effect;
|
||||||
|
dmg_ = dmg;
|
||||||
|
center_ = center;
|
||||||
|
special_damage_type_ = special_damage_type;
|
||||||
|
InternalAttack();
|
||||||
|
}
|
||||||
|
|
||||||
if (follow_target.Get()) {
|
void Explosion::InternalAttack()
|
||||||
bomb_pos = follow_target.Get()->GetPos();
|
{
|
||||||
|
if (explosion_range_ <= 0) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
room->frame_event.AddExplosionEx(sender,
|
sender_.Get()->room->frame_event.AddExplosionEx
|
||||||
meta->i->id(),
|
(sender_,
|
||||||
bomb_pos,
|
0,
|
||||||
gun_meta->i->explosion_effect());
|
center_,
|
||||||
|
explosion_effect_);
|
||||||
std::set<GridCell*> grid_list;
|
std::set<GridCell*> grid_list;
|
||||||
sender.Get()->room->grid_service->GetAllCellsByXy
|
sender_.Get()->room->grid_service->GetAllCellsByXy
|
||||||
(
|
(
|
||||||
sender.Get()->room,
|
room_,
|
||||||
bomb_pos.x,
|
center_.x,
|
||||||
bomb_pos.y,
|
center_.y,
|
||||||
grid_list
|
grid_list
|
||||||
);
|
);
|
||||||
std::set<Creature*> objects;
|
std::set<Entity*> objects;
|
||||||
sender.Get()->room->grid_service->TraverseCreatures
|
room_->grid_service->TraverseCreatures
|
||||||
(
|
(
|
||||||
sender.Get()->room->GetRoomIdx(),
|
room_->GetRoomIdx(),
|
||||||
grid_list,
|
grid_list,
|
||||||
[this, &objects] (Creature* c, bool& stop)
|
[this, &objects] (Creature* c, bool& stop)
|
||||||
{
|
{
|
||||||
if (sender.Get()->IsProperTarget(c)) {
|
if (!c->Attackable(room_)) {
|
||||||
if (bomb_pos.Distance(c->GetPos()) < meta->i->explosion_range()) {
|
return;
|
||||||
|
}
|
||||||
|
if (!c->ReceiveExplosionDmg(this)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (type_ == kExplosionEnemyAndObstacle) {
|
||||||
|
if (sender_.Get()->IsProperTarget(c)) {
|
||||||
|
if (center_.Distance(c->GetPos()) < explosion_range_) {
|
||||||
|
objects.insert(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (center_.Distance(c->GetPos()) < explosion_range_) {
|
||||||
objects.insert(c);
|
objects.insert(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
std::set<Entity*> entitys;
|
room_->grid_service->TraverseAllLayerEntityList
|
||||||
sender.Get()->room->grid_service->TraverseAllLayerEntityList
|
|
||||||
(
|
(
|
||||||
sender.Get()->room->GetRoomIdx(),
|
room_->GetRoomIdx(),
|
||||||
grid_list,
|
grid_list,
|
||||||
[this, &entitys] (Entity* entity, bool& stop)
|
[this, &objects] (Entity* entity, bool& stop)
|
||||||
{
|
{
|
||||||
|
if (!entity->Attackable(room_)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!entity->ReceiveExplosionDmg(this)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (center_.Distance(entity->GetPos()) < explosion_range_) {
|
||||||
|
objects.insert(entity);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
Explosion explosion;
|
|
||||||
for (auto& target : objects) {
|
for (auto& target : objects) {
|
||||||
target->OnExplosionHit(&explosion);
|
target->OnExplosionHit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& target : entitys) {
|
|
||||||
target->OnExplosionHit(&explosion);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
@ -6,14 +6,34 @@ class Room;
|
|||||||
class Explosion
|
class Explosion
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
Room* GetRoom() { return room_; };
|
||||||
|
CreatureWeakPtr GetSender() { return sender_; };
|
||||||
|
float GetDmg() { return dmg_; };
|
||||||
|
long long GetSpecialDamageType() { return special_damage_type_; };
|
||||||
|
|
||||||
void IndifferenceAttack(Room* room,
|
void IndifferenceAttack(Room* room,
|
||||||
const a8::Vec2& center,
|
const a8::Vec2& center,
|
||||||
float range,
|
float explosion_range,
|
||||||
int explosion_effect,
|
int explosion_effect,
|
||||||
float dmg);
|
float dmg,
|
||||||
|
long long special_damage_type = 0);
|
||||||
void EnemyAndObstacleAttack(CreatureWeakPtr& sender,
|
void EnemyAndObstacleAttack(CreatureWeakPtr& sender,
|
||||||
const a8::Vec2& center,
|
const a8::Vec2& center,
|
||||||
float range,
|
float explosion_range,
|
||||||
int explosion_effect,
|
int explosion_effect,
|
||||||
float dmg);
|
float dmg,
|
||||||
|
long long special_damage_type = 0);
|
||||||
|
private:
|
||||||
|
void InternalAttack();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int type_ = 0;
|
||||||
|
Room* room_ = nullptr;
|
||||||
|
CreatureWeakPtr sender_;
|
||||||
|
float explosion_range_ = 0;
|
||||||
|
int explosion_effect_ = 0;
|
||||||
|
float dmg_ = 0;
|
||||||
|
a8::Vec2 center_;
|
||||||
|
long long special_damage_type_ = 0;
|
||||||
};
|
};
|
||||||
|
@ -536,40 +536,28 @@ void Obstacle::OnBulletHit(Bullet* bullet)
|
|||||||
|
|
||||||
void Obstacle::OnExplosionHit(Explosion* e)
|
void Obstacle::OnExplosionHit(Explosion* e)
|
||||||
{
|
{
|
||||||
|
if (meta->i->explosion_hit() == kExplosionHitEatDmg) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
float dmg = e->GetDmg();
|
||||||
|
float def = 0;
|
||||||
|
float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K);
|
||||||
|
SetHealth(e->GetRoom(), std::max(0.0f, GetHealth(e->GetRoom()) - finaly_dmg));
|
||||||
|
if (GetHealth(e->GetRoom()) <= 0.01f) {
|
||||||
|
Die(e->GetRoom());
|
||||||
|
}
|
||||||
|
if (IsDead(e->GetRoom())) {
|
||||||
|
if (meta->i->damage_dia() > 0.01f &&
|
||||||
|
meta->i->damage() > 0.01f) {
|
||||||
#if 0
|
#if 0
|
||||||
if (!target->IsEntityType(Obstacle)) {
|
obstacle->Explosion(this);
|
||||||
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
|
#endif
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
sender.Get()->DropItems(obstacle);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
BroadcastFullState(e->GetRoom());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Obstacle::CanThroughable(Creature* c)
|
bool Obstacle::CanThroughable(Creature* c)
|
||||||
@ -784,3 +772,46 @@ bool Obstacle::IsHalfWallCollider()
|
|||||||
return meta->i->collision_hit() == kCollisionHitPass &&
|
return meta->i->collision_hit() == kCollisionHitPass &&
|
||||||
meta->i->bullet_hit() != kBulletHitPass;
|
meta->i->bullet_hit() != kBulletHitPass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Obstacle::Attackable(Room* room)
|
||||||
|
{
|
||||||
|
if (IsDead(room)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Obstacle::ReceiveExplosionDmg(Explosion* explosion)
|
||||||
|
{
|
||||||
|
switch (meta->i->explosion_hit()) {
|
||||||
|
case kExplosionHitPass:
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case kExplosionHitAnyDmg:
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case kExplosionHitOnlySpecDmg:
|
||||||
|
{
|
||||||
|
if (meta->receive_special_damage_type == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return (meta->receive_special_damage_type & explosion->GetSpecialDamageType()) != 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case kExplosionHitEatDmg:
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@ -43,12 +43,14 @@ class Obstacle : public Entity
|
|||||||
virtual void OnPreCollision(Room* room) override;
|
virtual void OnPreCollision(Room* room) override;
|
||||||
virtual void OnBulletHit(Bullet* bullet) override;
|
virtual void OnBulletHit(Bullet* bullet) override;
|
||||||
virtual void OnExplosionHit(Explosion* explosion) override;
|
virtual void OnExplosionHit(Explosion* explosion) override;
|
||||||
|
virtual bool Attackable(Room* room) override;
|
||||||
virtual bool IsTerminatorAirDropBox(Room* room) { return false; }
|
virtual bool IsTerminatorAirDropBox(Room* room) { return false; }
|
||||||
virtual bool CanThroughable(Creature* c);
|
virtual bool CanThroughable(Creature* c);
|
||||||
virtual bool CanThroughable(Bullet* bullet);
|
virtual bool CanThroughable(Bullet* bullet);
|
||||||
virtual bool DoInteraction(Human* sender);
|
virtual bool DoInteraction(Human* sender);
|
||||||
virtual void OnCollisionTrigger(Creature* c, OptResult& opt_result);
|
virtual void OnCollisionTrigger(Creature* c, OptResult& opt_result);
|
||||||
virtual bool CanSeeMe(Human* hum);
|
virtual bool CanSeeMe(Human* hum);
|
||||||
|
virtual bool ReceiveExplosionDmg(Explosion* explosion) override;
|
||||||
void SetDoorInfo(Building* building, int door_id_x);
|
void SetDoorInfo(Building* building, int door_id_x);
|
||||||
bool IsDoor();
|
bool IsDoor();
|
||||||
DoorState_e GetDoorState(Room* room);
|
DoorState_e GetDoorState(Room* room);
|
||||||
|
2
third_party/a8engine
vendored
2
third_party/a8engine
vendored
@ -1 +1 @@
|
|||||||
Subproject commit b16f9a6176bfac30c0e7d29ec6df37e750fd1c60
|
Subproject commit 8932713766a5c0289966f08a5a0153a1ae493a9d
|
Loading…
x
Reference in New Issue
Block a user