完成obstacle改造

This commit is contained in:
aozhiwei 2020-05-20 11:47:27 +08:00
parent 41699f3b91
commit ee77e79d08
9 changed files with 152 additions and 93 deletions

View File

@ -90,7 +90,7 @@ void Bullet::OnHit(std::set<Entity*>& objects)
case ET_Obstacle:
{
Obstacle* obstacle = (Obstacle*)target;
if (!obstacle->dead && obstacle->meta->i->attack_type() == 1) {
if (!obstacle->IsDead() && obstacle->meta->i->attack_type() == 1) {
#if 1
float dmg = gun_meta->i->atk() * (1 + player->GetBuffAttrRate(kHAT_Atk)) +
player->GetBuffAttrAbs(kHAT_Atk);
@ -103,10 +103,11 @@ void Bullet::OnHit(std::set<Entity*>& objects)
player->stats.damage_amount_out += finaly_dmg;
#endif
obstacle->health = std::max(0.0f, obstacle->health - finaly_dmg);
obstacle->dead = obstacle->health <= 0.01f;
obstacle->dead_frameno = room->frame_no;
if (obstacle->dead) {
obstacle->SetHealth(std::max(0.0f, obstacle->GetHealth() - finaly_dmg));
if (obstacle->GetHealth() <= 0.01f) {
obstacle->Die();
}
if (obstacle->IsDead()) {
if (obstacle->meta->i->damage_dia() > 0.01f &&
obstacle->meta->i->damage() > 0.01f) {
obstacle->Explosion(this);

View File

@ -35,10 +35,20 @@ void Entity::GetCircleBox(CircleCollider& circle_box)
circle_box.rad = 1;
}
bool Entity::IsDead()
{
return false;
}
long long Entity::GetDeadFrameNo()
{
return 0;
}
bool Entity::TestCollision(Entity* b)
{
App::Instance()->perf.test_times++;
if (b->dead) {
if (b->IsDead()) {
return false;
}
for (auto& a_collider : colliders) {
@ -53,7 +63,7 @@ bool Entity::TestCollision(Entity* b)
bool Entity::TestCollision(ColliderComponent* b)
{
if (b->owner->dead) {
if (b->owner->IsDead()) {
return false;
}
for (auto& a_collider : colliders) {

View File

@ -25,8 +25,6 @@ class Entity
int updated_times = 0;
bool deleted = false;
a8::XTimerAttacher xtimer_attacher;
bool dead = false;
long long dead_frameno = 0;
bool is_permanent = false;
MapService* permanent_map_service = nullptr;
@ -44,6 +42,8 @@ class Entity
virtual float GetSpeed() { return 1.0f;};
virtual void GetAabbBox(AabbCollider& aabb_box);
virtual void GetCircleBox(CircleCollider& circle_box);
virtual bool IsDead();
virtual long long GetDeadFrameNo();
bool TestCollision(Entity* b);
bool TestCollision(ColliderComponent* b);
bool TestCollisionEx(const a8::Vec2& aabb_pos, AabbCollider& aabb_box);

View File

@ -30,7 +30,7 @@ cs::SMUpdate* FrameMaker::MakeUpdateMsg(const Human* hum)
}
for (auto& itr : hum->part_objects) {
Entity* entity = itr;
if (entity->dead && hum->room->frame_no - entity->dead_frameno > 10) {
if (entity->IsDead() && hum->room->frame_no - entity->GetDeadFrameNo() > 10) {
continue;
} else {
#if 0

View File

@ -248,6 +248,16 @@ void Human::GetAabbBox(AabbCollider& aabb_box)
aabb_box._max.y = meta->i->radius();
}
bool Human::IsDead()
{
return dead;
}
long long Human::GetDeadFrameNo()
{
return dead_frameno;
}
void Human::FillMFTeamData(cs::MFTeamData* team_data)
{
#if 1
@ -438,8 +448,9 @@ bool Human::IsCollisionInMapService()
switch (collider->owner->entity_type) {
case ET_Obstacle:
{
Obstacle* obstacle = (Obstacle*)collider->owner;
#if 1
if (!collider->owner->dead &&
if (!obstacle->IsDead() &&
(
(collider->type == CT_Aabb && aabb_box.Intersect((ColliderComponent*)collider)) ||
(collider->type == CT_Circle && self_collider_->Intersect((ColliderComponent*)collider))
@ -449,16 +460,13 @@ bool Human::IsCollisionInMapService()
if (!collider->owner->dead && TestCollision((ColliderComponent*)collider)) {
#endif
if (last_collision_door != collider->owner) {
Obstacle* obstacle = (Obstacle*)collider->owner;
if (!obstacle->dead &&
if (!obstacle->IsDead() &&
obstacle->meta->i->attack_type() == 1 &&
obstacle->meta->i->drop() != 0 &&
room->gas_data.gas_mode != GasInactive
) {
obstacle->health = 0;
obstacle->dead = obstacle->health <= 0.01f;
obstacle->dead_frameno = room->frame_no;
if (obstacle->dead) {
obstacle->Die();
if (obstacle->IsDead()) {
#if 0
if (obstacle->meta->i->damage_dia() > 0.01f &&
obstacle->meta->i->damage() > 0.01f) {
@ -479,7 +487,7 @@ bool Human::IsCollisionInMapService()
case ET_Building:
{
#if 1
if (!collider->owner->dead &&
if (
(
(collider->type == CT_Aabb && aabb_box.Intersect((ColliderComponent*)collider)) ||
(collider->type == CT_Circle && self_collider_->Intersect((ColliderComponent*)collider))
@ -2542,10 +2550,10 @@ void Human::TriggerOneObjectBuff(Entity* target, BuffTriggerType_e trigger_type)
if (target->entity_type != ET_Player) {
return;
}
if (target->dead) {
Human* hum = (Human*)target;
if (hum->dead) {
return;
}
Human* hum = (Human*)target;
auto itr = skill_meta_->trigger_type_buffs.find(trigger_type);
if (itr != skill_meta_->trigger_type_buffs.end()) {
for (MetaData::Buff* buff_meta : itr->second) {

View File

@ -83,6 +83,8 @@ class Human : public Entity
xtimer_list* revive_timer = nullptr;
int dead_times = 0;
bool aiming = false;
bool dead = false;
long long dead_frameno = 0;
Weapon default_weapon;
Weapon tank_weapon;
@ -139,6 +141,8 @@ class Human : public Entity
virtual void FillMFObjectFull(cs::MFObjectFull* full_data) override;
virtual void FillMFPlayerStats(cs::MFPlayerStats* stats);
virtual void GetAabbBox(AabbCollider& aabb_box);
virtual bool IsDead() override;
virtual long long GetDeadFrameNo() override;
void FillMFTeamData(cs::MFTeamData* team_data);
void Shot(a8::Vec2& target_dir);
void TankShot(a8::Vec2& target_dir);

View File

@ -23,13 +23,13 @@ Obstacle::~Obstacle()
void Obstacle::Initialize()
{
Entity::Initialize();
health = meta->i->hp();
health_ = meta->i->hp();
RecalcSelfCollider();
}
void Obstacle::RecalcSelfCollider()
{
if (is_door) {
if (is_door_) {
//门
if (!self_collider2_) {
self_collider2_ = new AabbCollider();
@ -37,33 +37,33 @@ void Obstacle::RecalcSelfCollider()
AddCollider(self_collider2_);
a8::Vec2 old_pos = GetPos();
{
SetPos(a8::Vec2(building->GetX() + door_state1->x() - building->meta->i->tilewidth() / 2.0,
building->GetY() + door_state1->y() - building->meta->i->tileheight() / 2.0)
SetPos(a8::Vec2(building_->GetX() + door_state1_->x() - building_->meta->i->tilewidth() / 2.0,
building_->GetY() + door_state1_->y() - building_->meta->i->tileheight() / 2.0)
);
self_collider2_->_min = a8::Vec2(0.0f - door_state0->width() / 2.0f,
0.0f - door_state0->height() / 2.0f);
self_collider2_->_max = a8::Vec2(door_state0->width() / 2.0f, door_state0->height() / 2.0f);
self_collider2_->_min = a8::Vec2(0.0f - door_state0_->width() / 2.0f,
0.0f - door_state0_->height() / 2.0f);
self_collider2_->_max = a8::Vec2(door_state0_->width() / 2.0f, door_state0_->height() / 2.0f);
room->map_service.AddCollider(self_collider2_);
}
{
SetPos(a8::Vec2(building->GetX() + door_state0->x() - building->meta->i->tilewidth() / 2.0,
building->GetY() + door_state0->y() - building->meta->i->tileheight() / 2.0)
SetPos(a8::Vec2(building_->GetX() + door_state0_->x() - building_->meta->i->tilewidth() / 2.0,
building_->GetY() + door_state0_->y() - building_->meta->i->tileheight() / 2.0)
);
self_collider2_->_min = a8::Vec2(0.0f - door_state1->width() / 2.0f,
0.0f - door_state1->height() / 2.0f);
self_collider2_->_max = a8::Vec2(door_state1->width() / 2.0f, door_state1->height() / 2.0f);
self_collider2_->_min = a8::Vec2(0.0f - door_state1_->width() / 2.0f,
0.0f - door_state1_->height() / 2.0f);
self_collider2_->_max = a8::Vec2(door_state1_->width() / 2.0f, door_state1_->height() / 2.0f);
room->map_service.AddCollider(self_collider2_);
}
SetPos(old_pos);
}
if (door_state == DoorStateClose) {
self_collider2_->_min = a8::Vec2(0.0f - door_state0->width() / 2.0f,
0.0f - door_state0->height() / 2.0f);
self_collider2_->_max = a8::Vec2(door_state0->width() / 2.0f, door_state0->height() / 2.0f);
if (door_state_ == DoorStateClose) {
self_collider2_->_min = a8::Vec2(0.0f - door_state0_->width() / 2.0f,
0.0f - door_state0_->height() / 2.0f);
self_collider2_->_max = a8::Vec2(door_state0_->width() / 2.0f, door_state0_->height() / 2.0f);
} else {
self_collider2_->_min = a8::Vec2(0.0f - door_state1->width() / 2.0f,
0.0f - door_state1->height() / 2.0f);
self_collider2_->_max = a8::Vec2(door_state1->width() / 2.0f, door_state1->height() / 2.0f);
self_collider2_->_min = a8::Vec2(0.0f - door_state1_->width() / 2.0f,
0.0f - door_state1_->height() / 2.0f);
self_collider2_->_max = a8::Vec2(door_state1_->width() / 2.0f, door_state1_->height() / 2.0f);
}
} else if (meta->i->attack_type() != 2){
switch (meta->i->type()) {
@ -113,24 +113,24 @@ void Obstacle::FillMFObjectFull(cs::MFObjectFull* full_data)
p->set_scale(1.0f);
p->set_obstacle_id(meta->i->thing_id());
p->set_health(health);
p->set_dead(dead);
p->set_dead_at_thisframe(dead ? dead_frameno <= room->frame_no : false);
p->set_health(health_);
p->set_dead(dead_);
p->set_dead_at_thisframe(IsDead() ? dead_frameno_ <= room->frame_no : false);
p->set_is_door(is_door);
if (is_door) {
p->set_door_id(door_id);
p->set_door_open_times(door_open_times);
p->set_door_old_state((int)door_state);
p->set_door_new_state((int)door_state);
p->set_door_house_uniid(door_house_uniid);
p->set_door_house_id(building->meta->i->mapid());
if (door_state == DoorStateClose) {
p->set_door_width(door_state0->width());
p->set_door_height(door_state0->height());
p->set_is_door(is_door_);
if (is_door_) {
p->set_door_id(door_id_);
p->set_door_open_times(door_open_times_);
p->set_door_old_state((int)door_state_);
p->set_door_new_state((int)door_state_);
p->set_door_house_uniid(door_house_uniid_);
p->set_door_house_id(building_->meta->i->mapid());
if (door_state_ == DoorStateClose) {
p->set_door_width(door_state0_->width());
p->set_door_height(door_state0_->height());
} else {
p->set_door_width(door_state1->width());
p->set_door_height(door_state1->height());
p->set_door_width(door_state1_->width());
p->set_door_height(door_state1_->height());
}
}
}
@ -159,6 +159,16 @@ void Obstacle::GetCircleBox(CircleCollider& circle_box)
}
bool Obstacle::IsDead()
{
return dead_;
}
long long Obstacle::GetDeadFrameNo()
{
return dead_frameno_;
}
void Obstacle::Explosion(Bullet* bullet)
{
float old_rad = self_collider_->rad;
@ -219,15 +229,16 @@ void Obstacle::Explosion(Bullet* bullet)
case ET_Obstacle:
{
Obstacle* obstacle = (Obstacle*)target;
if (!obstacle->dead && obstacle->meta->i->attack_type() == 1) {
if (!obstacle->IsDead() && obstacle->meta->i->attack_type() == 1) {
float dmg = meta->i->damage();
float def = 0;
float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K);
obstacle->health = std::max(0.0f, obstacle->health - finaly_dmg);
obstacle->dead = obstacle->health <= 0.01f;
obstacle->dead_frameno = room->frame_no;
if (obstacle->dead) {
obstacle->SetHealth(std::max(0.0f, obstacle->health_ - finaly_dmg));
if (obstacle->GetHealth() <= 0.01f) {
obstacle->Die();
}
if (obstacle->IsDead()) {
room->ScatterDrop(obstacle->GetPos(), obstacle->meta->i->drop());
}
obstacle->BroadcastFullState();
@ -245,50 +256,71 @@ void Obstacle::Explosion(Bullet* bullet)
}
}
void Obstacle::SetDoorInfo(Building* building, int door_idx)
void Obstacle::SetDoorInfo(Building* building, int door_id_x)
{
MetaData::Building::Door* door_meta = &building->meta->doors[door_idx];
building = building;
is_door = true;
door_id = door_meta->door_id;
door_state = DoorStateClose;
building = building;
door_house_uniid = building->entity_uniid;
door_state0 = door_meta->state0;
door_state1 = door_meta->state1;
MetaData::Building::Door* door_meta = &building->meta->doors[door_id_x];
is_door_ = true;
door_id_ = door_meta->door_id;
door_state_ = DoorStateClose;
building_ = building;
door_house_uniid_ = building_->entity_uniid;
door_state0_ = door_meta->state0;
door_state1_ = door_meta->state1;
}
bool Obstacle::IsDoor()
{
return is_door;
return is_door_;
}
DoorState_e Obstacle::GetDoorState()
{
return door_state;
return door_state_;
}
void Obstacle::SetDoorState(DoorState_e state)
{
door_state = state;
door_state_ = state;
}
void Obstacle::SetBuilding(Building* building)
{
building_ = building;
}
Building* Obstacle::GetBuilding()
{
return building;
return building_;
}
const metatable::DoorObjJson* Obstacle::GetDoorState0()
{
return door_state0;
return door_state0_;
}
const metatable::DoorObjJson* Obstacle::GetDoorState1()
{
return door_state1;
return door_state1_;
}
void Obstacle::IncDoorOpenTimes()
{
++door_open_times;
++door_open_times_;
}
float Obstacle::GetHealth()
{
return health_;
}
void Obstacle::SetHealth(float value)
{
health_ = value;
}
void Obstacle::Die()
{
health_ = 0;
dead_ = true;
dead_frameno_ = room->frame_no;
}

View File

@ -4,8 +4,6 @@
namespace MetaData
{
struct Player;
struct Equip;
struct MapThing;
struct Building;
}
@ -24,7 +22,6 @@ class Obstacle : public Entity
{
public:
MetaData::MapThing* meta = nullptr;
float health = 0.0f;
Obstacle();
virtual ~Obstacle() override;
@ -34,28 +31,37 @@ class Obstacle : public Entity
virtual void FillMFObjectFull(cs::MFObjectFull* full_data) override;
virtual void GetAabbBox(AabbCollider& aabb_box) override;
virtual void GetCircleBox(CircleCollider& circle_box) override;
virtual bool IsDead() override;
virtual long long GetDeadFrameNo() override;
void Explosion(Bullet* bullet);
void SetDoorInfo(Building* building, int door_idx);
void SetDoorInfo(Building* building, int door_id_x);
bool IsDoor();
DoorState_e GetDoorState();
void SetDoorState(DoorState_e state);
void SetBuilding(Building* building);
Building* GetBuilding();
const metatable::DoorObjJson* GetDoorState0();
const metatable::DoorObjJson* GetDoorState1();
void IncDoorOpenTimes();
float GetHealth();
void SetHealth(float value);
void Die();
private:
CircleCollider* self_collider_ = nullptr;
AabbCollider* self_collider2_ = nullptr;
bool is_door = false;
int door_id = 0;
int door_open_times = 0;
DoorState_e door_state = DoorStateClose;
Building* building = nullptr;
int door_house_uniid = 0;
const metatable::DoorObjJson* door_state0 = nullptr;
const metatable::DoorObjJson* door_state1 = nullptr;
float health_ = 0.0f;
bool dead_ = false;
long long dead_frameno_ = 0;
bool is_door_ = false;
int door_id_ = 0;
int door_open_times_ = 0;
DoorState_e door_state_ = DoorStateClose;
Building* building_ = nullptr;
int door_house_uniid_ = 0;
const metatable::DoorObjJson* door_state0_ = nullptr;
const metatable::DoorObjJson* door_state1_ = nullptr;
};

View File

@ -458,9 +458,7 @@ void RoomMgr::CreateBuilding(int thing_id, float building_x, float building_y)
InternalCreateObstacle(pair.key(), x, y,
[building] (Obstacle* entity)
{
#if 0
entity->building = building;
#endif
entity->SetBuilding(building);
});
break;
}