This commit is contained in:
aozhiwei 2021-03-31 20:38:21 +08:00
parent f627a1754b
commit a28e2870c2
18 changed files with 138 additions and 124 deletions

View File

@ -11,7 +11,11 @@
#include "app.h"
#include "perfmonitor.h"
#include "smoke_mitask.h"
#include "frag_mitask.h"
#include "posiongas_mitask.h"
#include "molotor_cocktail_mitask.h"
#include "creature.h"
#include "roomobstacle.h"
Bullet::Bullet():MoveableEntity()
{
@ -31,17 +35,7 @@ void Bullet::Initialize()
void Bullet::Update(int delta_time)
{
#ifdef DEBUG
#if 0
player->room->CheckPartObjects();
#endif
#endif
MapServiceUpdate();
#ifdef DEBUG
#if 0
player->room->CheckPartObjects();
#endif
#endif
++updated_times_;
}
@ -67,13 +61,13 @@ void Bullet::OnHit(std::set<Entity*>& objects)
hum->HasBuffEffect(kBET_AdPlaying)) {
continue;
}
if (sender->room->GetRoomMode() == kZombieMode &&
sender->GetRace() == hum->GetRace()) {
if (sender.Get()->room->GetRoomMode() == kZombieMode &&
sender.Get()->GetRace() == hum->GetRace()) {
continue;
}
if (!hum->dead && (IsBomb() || sender->team_id != hum->team_id)) {
float dmg = GetAtk() * (1 + sender->GetAttrRate(kHAT_Atk)) +
sender->GetAttrAbs(kHAT_Atk);
if (!hum->dead && (IsBomb() || sender.Get()->team_id != hum->team_id)) {
float dmg = GetAtk() * (1 + sender.Get()->GetAttrRate(kHAT_Atk)) +
sender.Get()->GetAttrAbs(kHAT_Atk);
float def = hum->ability.def * (1 + hum->GetAttrRate(kHAT_Def)) +
hum->GetAttrAbs(kHAT_Def);
float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K);
@ -81,9 +75,9 @@ void Bullet::OnHit(std::set<Entity*>& objects)
#if 0
sender->stats.damage_amount_out += finaly_dmg;
#endif
hum->DecHP(finaly_dmg, sender->GetEntityUniId(), sender->GetName(), gun_meta->i->id());
hum->DecHP(finaly_dmg, sender.Get()->GetEntityUniId(), sender.Get()->GetName(), gun_meta->i->id());
#ifdef DEBUG
sender->SendDebugMsg(a8::Format("bullet weapon_id:%d atk:%f",
sender.Get()->SendDebugMsg(a8::Format("bullet weapon_id:%d atk:%f",
{
gun_meta->i->id(),
GetAtk()
@ -99,8 +93,8 @@ void Bullet::OnHit(std::set<Entity*>& objects)
if (!obstacle->IsDead(room) &&
obstacle->Attackable() &&
!obstacle->IsTerminatorAirDropBox(room)) {
float dmg = GetAtk() * (1 + sender->GetAttrRate(kHAT_Atk)) +
sender->GetAttrAbs(kHAT_Atk);
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));
@ -112,11 +106,11 @@ void Bullet::OnHit(std::set<Entity*>& objects)
obstacle->meta->i->damage() > 0.01f) {
obstacle->Explosion(this);
}
sender->DropItems(obstacle);
sender.Get()->DropItems(obstacle);
}
obstacle->BroadcastFullState(room);
#ifdef DEBUG
sender->SendDebugMsg(a8::Format("bullet weapon_id:%d atk:%f",
sender.Get()->SendDebugMsg(a8::Format("bullet weapon_id:%d atk:%f",
{
gun_meta->i->id(),
GetAtk()
@ -140,11 +134,11 @@ void Bullet::ProcBomb()
(
[this, &objects] (Human* hum, bool& stop)
{
if (!is_tank_skin || sender->team_id != hum->team_id) {
if (!is_tank_skin || sender.Get()->team_id != hum->team_id) {
//友军火箭筒伤害取消
if ((meta->i->_inventory_slot() == 4 ||
meta->i->_inventory_slot() == 5) &&
sender->team_id == hum->team_id) {
sender.Get()->team_id == hum->team_id) {
return;
}
if (TestCollision(room, hum)) {
@ -277,6 +271,7 @@ bool Bullet::IsBomb()
void Bullet::MapServiceUpdate()
{
if (sender.Get()) {
SetPos(GetPos() + dir * gun_meta->i->bullet_speed() / (float)SERVER_FRAME_RATE);
float distance = (GetPos() - born_pos).Norm();
if (room->OverBorder(GetPos(), gun_meta->i->bullet_rad())) {
@ -292,14 +287,18 @@ void Bullet::MapServiceUpdate()
room->grid_service->MoveBullet(this);
Check(distance);
}
} else {
room->RemoveObjectLater(this);
later_removed_ = true;
}
}
float Bullet::GetAtk()
{
float atk = gun_meta->i->atk() +
(gun_upgrade_meta ? gun_upgrade_meta->GetAttrValue(gun_lv, kHAT_Atk) : 0);
if (sender->IsAndroid()) {
Android* android = (Android*)sender;
if (sender.Get()->IsAndroid()) {
Android* android = (Android*)sender.Get();
atk *= android->ai->GetAttackRate();
}
return atk;
@ -312,7 +311,7 @@ void Bullet::Check(float distance)
(
[this, &objects] (Human* hum, bool& stop)
{
if (hum != sender && !hum->dead && TestCollision(room, hum)) {
if (hum != sender.Get() && !hum->dead && TestCollision(room, hum)) {
objects.insert(hum);
}
});
@ -346,11 +345,36 @@ void Bullet::Check(float distance)
void Bullet::ProcFragBomb(float delay_time)
{
a8::Vec2 bomb_pos = GetPos();
room->frame_event.AddExplosion(this, meta->i->id(), bomb_pos);
#if 0
OnHit(objects);
#endif
if (sender.Get()) {
RoomObstacle* dummy_obstacle = nullptr;
if (delay_time > 0.0001) {
dummy_obstacle = room->CreateObstacle(0, 0, 0);
}
FragMiTask* task = new FragMiTask();
task->room = room;
task->sender.Attach(sender.Get());
task->bomb_pos = GetPos();
task->gun_meta = gun_meta;
task->meta = meta;
task->atk = GetAtk();
task->dummy_obstacle_uniid = dummy_obstacle ? dummy_obstacle->GetEntityUniId() : 0;
room->xtimer.AddDeadLineTimerAndAttach
(std::max(1, (int)(SERVER_FRAME_RATE * delay_time)),
a8::XParams()
.SetSender(task),
[] (const a8::XParams& param)
{
FragMiTask* task = (FragMiTask*)param.sender.GetUserData();
task->Done();
},
&task->timer_attacher.timer_list_,
[] (const a8::XParams& param)
{
FragMiTask* task = (FragMiTask*)param.sender.GetUserData();
delete task;
}
);
}
}
void Bullet::ProcPosionGasBomb(float delay_time)

View File

@ -1,6 +1,7 @@
#pragma once
#include "moveableentity.h"
#include "weakptr.h"
namespace MetaData
{
@ -21,7 +22,7 @@ class Bullet : public MoveableEntity
MetaData::Equip* gun_meta = nullptr;
MetaData::EquipUpgrade* gun_upgrade_meta = nullptr;
MetaData::Equip* meta = nullptr;
Creature* sender = nullptr;
CreatureWeakPtr sender;
a8::Vec2 dir;
a8::Vec2 born_pos;
a8::Vec2 born_dir;

View File

@ -397,7 +397,7 @@ const int DEFAULT_BORN_POINT_Y = 3000;
const int ADPLAY_BUFFID = 1006;
const int FIXED_OBJECT_MAXID = 2014;
const int FIXED_OBJECT_MAXID = 20140;
const int MAX_ROOM_IDX = 2018;

View File

@ -814,6 +814,11 @@ bool Creature::CanSee(const Creature* c) const
return room->grid_service->InView(GetGridId(), c->GetGridId());
}
bool Creature::CanSee(int grid_id) const
{
return room->grid_service->InView(GetGridId(), grid_id);
}
float Creature::GetAttrAbs(int attr_id)
{
float attr_abs_val = GetBuffAttrAbs(attr_id);

View File

@ -79,6 +79,7 @@ class Creature : public MoveableEntity
Skill* CurrentSkill();
MetaData::SkillPhase* GetCurrSkillPhase();
bool CanSee(const Creature* c) const;
bool CanSee(int grid_id) const;
virtual std::string GetName() { return "";};
virtual void SendDebugMsg(const std::string& debug_msg);

View File

@ -4,38 +4,14 @@
#include "room.h"
#include "player.h"
#include "metadata.h"
void FragMiTask::Check()
{
{
std::list<Player*> deleted_hums;
for (auto& hum : player_set) {
if (bomb_pos.Distance(hum->GetPos()) > gun_meta->i->bullet_rad() + hum->meta->i->radius()) {
hum->RemoveBuffByEffectId(kBET_HunLuan);
deleted_hums.push_back(hum);
}
}
for (auto& hum : deleted_hums) {
player_set.erase(hum);
}
}
room->TouchPlayerList
(a8::XParams(),
[this] (Player* hum, a8::XParams&) -> bool
{
if (bomb_pos.Distance(hum->GetPos()) < gun_meta->i->bullet_rad() + hum->meta->i->radius()) {
if (!hum->HasBuffEffect(kBET_HunLuan)) {
hum->AddBuff(nullptr, buff_meta, 1, nullptr);
player_set.insert(hum);
}
}
return true;
});
}
#include "metamgr.h"
void FragMiTask::Done()
{
for (auto& hum : player_set) {
hum->RemoveBuffByEffectId(kBET_HunLuan);
if (sender.Get()) {
room->frame_event.AddExplosionEx(sender,
meta->i->id(),
bomb_pos,
gun_meta->i->explosion_effect());
}
}

View File

@ -15,10 +15,12 @@ class FragMiTask : public MicroTask
public:
Room* room = nullptr;
a8::Vec2 bomb_pos;
std::set<Player*> player_set;
MetaData::Buff* buff_meta = nullptr;
CreatureWeakPtr sender;
MetaData::Equip* gun_meta = nullptr;
MetaData::Equip* meta = nullptr;
float atk = 0;
int dummy_obstacle_uniid = 0;
void Check();
void Done();
float GetAtk() { return atk; }
};

View File

@ -99,41 +99,27 @@ void FrameEvent::AddBullet(Creature* sender,
void FrameEvent::AddExplosion(Bullet* bullet, int item_id, a8::Vec2 bomb_pos)
{
{
auto& tuple = a8::FastAppend(explosions_);
std::get<0>(tuple) = bullet->sender;
auto& p = std::get<1>(tuple);
p.set_item_id(item_id);
TypeConvert::ToPb(bomb_pos, p.mutable_pos());
p.set_player_id(bullet->sender->GetEntityUniId());
}
{
int explosion_idx = explosions_.size() - 1;
bullet->sender->TouchAllLayerHumanList
(
[explosion_idx] (Human* hum, bool& stop)
{
hum->explosions_.push_back(explosion_idx);
});
}
AddExplosionEx(bullet->sender, item_id, bomb_pos, 0);
}
void FrameEvent::AddExplosionEx(Creature* sender, int item_id, a8::Vec2 bomb_pos, int effect)
void FrameEvent::AddExplosionEx(CreatureWeakPtr& sender, int item_id, a8::Vec2 bomb_pos, int effect)
{
if (!sender.Get()) {
return;
}
{
auto& tuple = a8::FastAppend(explosions_);
std::get<0>(tuple) = sender;
std::get<0>(tuple).Attach(sender.Get());
auto& p = std::get<1>(tuple);
p.set_item_id(item_id);
TypeConvert::ToPb(bomb_pos, p.mutable_pos());
p.set_player_id(sender->GetEntityUniId());
p.set_player_id(sender.Get()->GetEntityUniId());
p.set_effect(effect);
}
{
int explosion_idx = explosions_.size() - 1;
sender->TouchAllLayerHumanList
sender.Get()->TouchAllLayerHumanList
(
[explosion_idx] (Human* hum, bool& stop)
{
@ -151,18 +137,21 @@ void FrameEvent::AddBulletNumChg(Human* hum)
void FrameEvent::AddSmoke(Bullet* bullet, int item_id, a8::Vec2 pos)
{
if (!bullet->sender.Get()) {
return;
}
{
auto& tuple = a8::FastAppend(smokes_);
std::get<0>(tuple) = bullet->sender;
std::get<0>(tuple).Attach(bullet->sender.Get());
auto& p = std::get<1>(tuple);
p.set_item_id(item_id);
TypeConvert::ToPb(pos, p.mutable_pos());
p.set_player_id(bullet->sender->GetEntityUniId());
p.set_player_id(bullet->sender.Get()->GetEntityUniId());
}
{
int idx = smokes_.size() - 1;
bullet->sender->TouchAllLayerHumanList
bullet->sender.Get()->TouchAllLayerHumanList
(
[idx] (Human* hum, bool& stop)
{

View File

@ -1,6 +1,7 @@
#pragma once
#include "cs_proto.pb.h"
#include "weakptr.h"
class Bullet;
class Human;
@ -21,7 +22,7 @@ public:
float fly_distance);
void AddExplosion(Bullet* bullet, int item_id, a8::Vec2 bomb_pos);
void AddSmoke(Bullet* bullet, int item_id, a8::Vec2 pos);
void AddExplosionEx(Creature* sender, int item_id, a8::Vec2 bomb_pos, int effect);
void AddExplosionEx(CreatureWeakPtr& sender, int item_id, a8::Vec2 bomb_pos, int effect);
void AddBulletNumChg(Human* hum);
void AddHpChg(Human* hum);
void AddWeaponAmmoChg(Human* hum);
@ -39,8 +40,8 @@ private:
::google::protobuf::RepeatedPtrField<::cs::MFAirDrop> airdrops_;
std::vector<std::tuple<Creature*, ::cs::MFShot>> shots_;
std::vector<std::tuple<Creature*, ::cs::MFBullet>> bullets_;
std::vector<std::tuple<Creature*, ::cs::MFExplosion>> explosions_;
std::vector<std::tuple<Creature*, ::cs::MFSmoke>> smokes_;
std::vector<std::tuple<CreatureWeakPtr, ::cs::MFExplosion>> explosions_;
std::vector<std::tuple<CreatureWeakPtr, ::cs::MFSmoke>> smokes_;
std::vector<std::tuple<Creature*, ::cs::MFEmote>> emotes_;
std::vector<std::tuple<Creature*, ::cs::MFBuffChg>> chged_buffs_;
std::vector<std::tuple<Human*, int, int>> chged_items_;

View File

@ -83,7 +83,7 @@ cs::SMUpdate* FrameMaker::MakeUpdateMsg(Human* hum)
for (size_t idx : hum->explosions_) {
if (idx < room->frame_event.explosions_.size()) {
auto& tuple = room->frame_event.explosions_[idx];
if (hum->CanSee(std::get<0>(tuple))) {
if (std::get<0>(tuple).Get() && hum->CanSee(std::get<0>(tuple).Get())) {
*msg->add_explosions() = std::get<1>(tuple);
}
}
@ -91,7 +91,7 @@ cs::SMUpdate* FrameMaker::MakeUpdateMsg(Human* hum)
for (size_t idx : hum->smokes_) {
if (idx < room->frame_event.smokes_.size()) {
auto& tuple = room->frame_event.smokes_[idx];
if (hum->CanSee(std::get<0>(tuple))) {
if (std::get<0>(tuple).Get() && hum->CanSee(std::get<0>(tuple).Get())) {
*msg->add_smokes() = std::get<1>(tuple);
}
}

View File

@ -1757,6 +1757,7 @@ void Human::_UpdateMove(int speed)
_InternalUpdateMove(distance);
speed -= distance;
} while (speed > 0);
CheckSpecObject();
}
void Human::ChangeToRace(RaceType_e race, int level)
@ -1867,7 +1868,7 @@ RoomObstacle* Human::SummonObstacle(int id, const a8::Vec2& pos)
{
RoomObstacle* obstacle = room->CreateObstacle(id, pos.x, pos.y);
if (obstacle) {
obstacle->master = this;
obstacle->master.Attach(this);
room->xtimer.AddRepeatTimerAndAttach
(
SERVER_FRAME_RATE,

View File

@ -211,10 +211,14 @@ void MapInstance::CreateTerrain()
}
}
MetaData::MapThing* thing_meta = MetaMgr::Instance()->GetMapThing(0);
MetaData::MapThing* thing_meta = MetaMgr::Instance()->GetMapThing(80001);
#ifdef DEBUG
a8::XPrintf("%s %f %f\n", {map_tpl_name_, (float)first_layer->width(), (float)first_layer->height()});
#endif
if (thing_meta) {
for (int w = 0; w < first_layer->width(); ++w) {
for (int h = 0; h < first_layer->height(); ++h) {
assert(w < 300 && h < 300);
int grid_val = grids[w * first_layer->width() + h];
if (grid_val != 0) {
float x = w * thing_meta->i->width() + thing_meta->i->width() / 2.0f;
@ -228,10 +232,12 @@ void MapInstance::CreateTerrain()
a8::SetBitFlag(collider_tag, kColliderTag_Grass);
}
if (collider_tag != 0) {
assert(w < 300 && h < 300);
InternalCreateObstacle(thing_meta->i->thing_id(), x, y, collider_tag,
[] (Obstacle* entity)
{
});
},
true);
}
}
}
@ -310,7 +316,8 @@ void MapInstance::CreateBuilding(int thing_id, float building_x, float building_
}
Obstacle* MapInstance::InternalCreateObstacle(int id, float x, float y, int collider_tag,
std::function<void (Obstacle*)> on_precreate)
std::function<void (Obstacle*)> on_precreate,
bool no_grid_service)
{
MetaData::MapThing* thing = MetaMgr::Instance()->GetMapThing(id);
if (thing) {
@ -325,7 +332,9 @@ Obstacle* MapInstance::InternalCreateObstacle(int id, float x, float y, int coll
on_precreate(entity);
}
uniid_hash_[entity->GetEntityUniId()] = entity;
if (!no_grid_service) {
grid_service_->AddPermanentEntity(entity);
}
{
switch (thing->i->attack_type()) {
case 0:

View File

@ -30,7 +30,8 @@ class MapInstance
void CreateMapObject(MetaData::MapTplThing& thing_tpl);
void CreateBuilding(int thing_id, float building_x, float building_y);
Obstacle* InternalCreateObstacle(int id, float x, float y, int collider_tag,
std::function<void (Obstacle*)> on_precreate);
std::function<void (Obstacle*)> on_precreate,
bool no_grid_service = false);
Entity* GetEntityByUniId(int uniid);
int AllocUniid();

View File

@ -1,5 +1,7 @@
#pragma once
#include "weakptr.h"
class MicroTask
{
public:

View File

@ -319,7 +319,7 @@ void Obstacle::Explosion(Bullet* bullet)
obstacle->Die(room);
}
if (obstacle->IsDead(room)) {
bullet->sender->DropItems(obstacle);
bullet->sender.Get()->DropItems(obstacle);
}
obstacle->BroadcastFullState(room);
}
@ -458,3 +458,4 @@ bool Obstacle::Throughable()
{
return meta->i->attack_type() == 2;
}

View File

@ -531,7 +531,7 @@ void Room::CreateBullet(Creature* sender,
{
if (grid_service->CanAdd(pos.x, pos.y)) {
Bullet* bullet = EntityFactory::Instance()->MakeBullet(AllocUniid());
bullet->sender = sender;
bullet->sender.Attach(sender);
bullet->room = this;
bullet->gun_meta = weapon_meta;
bullet->gun_upgrade_meta = weapon_upgrade_meta;

View File

@ -88,8 +88,8 @@ void RoomObstacle::RecalcSelfCollider()
bool RoomObstacle::CanThroughable(Human* hum)
{
if (master) {
return master->team_id == hum->team_id && temp_through_;
if (master.Get()) {
return master.Get()->team_id == hum->team_id && temp_through_;
} else {
return temp_through_;
}
@ -97,7 +97,7 @@ bool RoomObstacle::CanThroughable(Human* hum)
void RoomObstacle::ActiveTimerFunc()
{
if (!master) {
if (!master.Get()) {
room->xtimer.DeleteTimer(room->xtimer.GetRunningTimer());
return;
}
@ -114,7 +114,7 @@ void RoomObstacle::ActiveTimerFunc()
{
bool old_temp_through = temp_through_;
temp_through_ = false;
if (master->team_id == hum->team_id) {
if (master.Get()->team_id == hum->team_id) {
if (TestCollision(room, hum)) {
has_hum = true;
stop = true;
@ -131,14 +131,14 @@ void RoomObstacle::ActiveTimerFunc()
void RoomObstacle::UpdateTimerFunc()
{
if (grid_list_ && master && !IsDead(room)) {
if (grid_list_ && master.Get() && !IsDead(room)) {
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)) {
if (master.Get()->team_id != hum->team_id && TestCollision(room, hum)) {
human_list.insert(hum);
}
}
@ -148,7 +148,7 @@ void RoomObstacle::UpdateTimerFunc()
for (int buff_id : meta->buff_list) {
MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff(buff_id);
if (buff_meta) {
hum->AddBuff(master,
hum->AddBuff(master.Get(),
buff_meta,
1);
}
@ -176,7 +176,7 @@ void RoomObstacle::Explosion()
*grid_list_,
[this, &objects] (Human* hum, bool& stop)
{
if (master->team_id != hum->team_id && TestCollision(room, hum)) {
if (master.Get()->team_id != hum->team_id && TestCollision(room, hum)) {
objects.insert(hum);
}
});

View File

@ -2,6 +2,7 @@
#include "gridservice.h"
#include "obstacle.h"
#include "weakptr.h"
class RoomObstacle : public Obstacle
{
@ -10,7 +11,7 @@ class RoomObstacle : public Obstacle
a8::XTimerAttacher xtimer_attacher;
bool is_treasure_box = false;
bool is_terminator_airdrop_box = false;
class Human* master = nullptr;
CreatureWeakPtr master;
virtual ~RoomObstacle() override;
virtual void Initialize() override;