1
This commit is contained in:
commit
10e04da61c
@ -78,7 +78,9 @@ void Buff::ProcIntervalAddBuff()
|
||||
void Buff::ProcBatchAddBuff()
|
||||
{
|
||||
std::shared_ptr<Ability> old_context_ability = owner->context_ability;
|
||||
a8::Vec2 old_context_dir = owner->context_dir;
|
||||
a8::Vec2 old_context_pos = owner->context_pos;
|
||||
owner->context_dir = owner->GetAttackDir();
|
||||
owner->context_pos = owner->GetPos();
|
||||
|
||||
for (auto& tuple : meta->batch_add_list) {
|
||||
@ -112,6 +114,7 @@ void Buff::ProcBatchAddBuff()
|
||||
}
|
||||
}
|
||||
|
||||
owner->context_dir = old_context_dir;
|
||||
owner->context_pos = old_context_pos;
|
||||
owner->context_ability = old_context_ability;
|
||||
}
|
||||
@ -128,7 +131,9 @@ void Buff::InternalTimerAddBuff()
|
||||
SkillCasterState* caster_state = (SkillCasterState*)param.param1.GetUserData();
|
||||
if (caster_state->caster.Get()) {
|
||||
std::shared_ptr<Ability> old_context_ability = receiver->context_ability;
|
||||
a8::Vec2 old_context_dir = receiver->context_dir;
|
||||
a8::Vec2 old_context_pos = receiver->context_pos;
|
||||
receiver->context_dir = receiver->GetAttackDir();
|
||||
receiver->context_pos = receiver->GetPos();
|
||||
|
||||
int buff_id = param.param2;
|
||||
@ -142,6 +147,7 @@ void Buff::InternalTimerAddBuff()
|
||||
caster_state->caster.Get()->RecoverSkillCasterState(&old_caster_state);
|
||||
}
|
||||
|
||||
receiver->context_dir = old_context_dir;
|
||||
receiver->context_pos = old_context_pos;
|
||||
receiver->context_ability = old_context_ability;
|
||||
}
|
||||
@ -458,20 +464,60 @@ void Buff::ProcTurnOver()
|
||||
a8::Vec2 old_pos = owner->GetPos();
|
||||
float distance =
|
||||
owner->HasBuffEffect(kBET_Car) ? phase->param1.GetDouble() * 1.5 : phase->param1.GetDouble();
|
||||
if (meta->int_param1 == 1) {
|
||||
//穿墙
|
||||
} else {
|
||||
owner->_UpdateMove(distance);
|
||||
owner->_UpdateMove(distance);
|
||||
int moved_distance = (int)owner->GetPos().Distance(old_pos);
|
||||
moved_distance = std::min(moved_distance, 200);
|
||||
if (!meta->param1_int_list.empty() && moved_distance > 2) {
|
||||
std::set<Creature*> target_list;
|
||||
owner->TraverseCreatures
|
||||
(
|
||||
[this, &target_list] (Creature* c, bool& stop)
|
||||
{
|
||||
if (owner->IsProperTarget(c) && owner->GetPos().Distance(c->GetPos()) < 300) {
|
||||
target_list.insert(c);
|
||||
}
|
||||
});
|
||||
|
||||
a8::Vec2 curr_pos = owner->GetPos();
|
||||
a8::Vec2 dir = owner->GetPos() - old_pos;
|
||||
dir.Normalize();
|
||||
for (int i = 5; i < moved_distance; i += 5) {
|
||||
owner->SetPos(old_pos + dir * i);
|
||||
std::list<Creature*> hit_objects;
|
||||
for (auto& target : target_list) {
|
||||
if (owner->TestCollision(owner->room, target)) {
|
||||
hit_objects.push_back(target);
|
||||
}
|
||||
}
|
||||
for (auto& target : hit_objects) {
|
||||
target_list.erase(target);
|
||||
target->room->xtimer.AddDeadLineTimerAndAttach
|
||||
(
|
||||
meta->int_param4 / FRAME_RATE_MS * (i / moved_distance),
|
||||
a8::XParams()
|
||||
.SetSender(target)
|
||||
.SetParam1(meta)
|
||||
.SetParam2(owner->GetUniId()),
|
||||
[] (const a8::XParams& param)
|
||||
{
|
||||
Creature* c = (Creature*)param.sender.GetUserData();
|
||||
MetaData::Buff* buff_meta = (MetaData::Buff*)param.param1.GetUserData();
|
||||
Entity* caster = c->room->GetEntityByUniId(param.param2);
|
||||
if (caster && caster->IsCreature(c->room)) {
|
||||
for (int buff_id : buff_meta->param1_int_list) {
|
||||
c->TryAddBuff((Creature*)caster, buff_id);
|
||||
}
|
||||
}
|
||||
},
|
||||
&target->xtimer_attacher.timer_list_);
|
||||
}
|
||||
}
|
||||
owner->SetPos(curr_pos);
|
||||
}
|
||||
if (!meta->param2_int_list.empty()) {
|
||||
int time = 0;
|
||||
float moved_distance = owner->GetPos().Distance(old_pos);
|
||||
if (std::abs(moved_distance) > 0.01f) {
|
||||
time = ((moved_distance / distance) * meta->param3) / FRAME_RATE_MS;
|
||||
}
|
||||
owner->room->xtimer.AddDeadLineTimerAndAttach
|
||||
(
|
||||
time,
|
||||
meta->int_param4 / FRAME_RATE_MS,
|
||||
a8::XParams()
|
||||
.SetSender(owner)
|
||||
.SetParam1(meta),
|
||||
@ -479,9 +525,16 @@ void Buff::ProcTurnOver()
|
||||
{
|
||||
Creature* c = (Creature*)param.sender.GetUserData();
|
||||
MetaData::Buff* buff_meta = (MetaData::Buff*)param.param1.GetUserData();
|
||||
for (int buff_id : buff_meta->param2_int_list) {
|
||||
c->TryAddBuff(c, buff_id);
|
||||
}
|
||||
c->TraverseCreatures
|
||||
(
|
||||
[c, buff_meta] (Creature* target, bool& stop)
|
||||
{
|
||||
if (c->GetPos().Distance(target->GetPos()) < buff_meta->int_param3) {
|
||||
for (int buff_id : buff_meta->param2_int_list) {
|
||||
target->TryAddBuffWithTarget(c, buff_id);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
&owner->xtimer_attacher.timer_list_
|
||||
);
|
||||
@ -529,3 +582,74 @@ void Buff::ProcOnceChgAttr()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Buff::ProcAutoShot()
|
||||
{
|
||||
owner->room->xtimer.AddRepeatTimerAndAttach
|
||||
(
|
||||
1,
|
||||
a8::XParams()
|
||||
.SetSender(this),
|
||||
[] (const a8::XParams& param)
|
||||
{
|
||||
Buff* buff = (Buff*)param.sender.GetUserData();
|
||||
if (buff->owner->IsHuman()) {
|
||||
#if 0
|
||||
buff->owner->AsHuman()->shot_start = true;
|
||||
#endif
|
||||
buff->owner->AsHuman()->shot_hold = true;
|
||||
buff->owner->AsHuman()->series_shot_frames = 0;
|
||||
}
|
||||
},
|
||||
&xtimer_attacher.timer_list_,
|
||||
[] (const a8::XParams& param)
|
||||
{
|
||||
Buff* buff = (Buff*)param.sender.GetUserData();
|
||||
if (buff->owner->IsHuman()) {
|
||||
#if 0
|
||||
buff->owner->AsHuman()->shot_start = false;
|
||||
#endif
|
||||
buff->owner->AsHuman()->shot_hold = false;
|
||||
buff->owner->AsHuman()->series_shot_frames = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void Buff::ProcBeatBack()
|
||||
{
|
||||
if (caster_.Get()) {
|
||||
if (std::abs(caster_.Get()->context_dir.x) > FLT_EPSILON ||
|
||||
std::abs(caster_.Get()->context_dir.x) > FLT_EPSILON) {
|
||||
if (std::abs(meta->int_param1) > 0) {
|
||||
a8::Vec2 old_move_dir = owner->GetMoveDir();
|
||||
owner->SetMoveDir(caster_.Get()->context_dir);
|
||||
owner->_UpdateMove(meta->param1);
|
||||
owner->SetMoveDir(old_move_dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Buff::ProcDisperse()
|
||||
{
|
||||
std::vector<int> del_buffs;
|
||||
owner->TraverseBuff
|
||||
(
|
||||
[this, &del_buffs] (Buff* buff, bool& stop)
|
||||
{
|
||||
for (int tag : meta->param1_int_set) {
|
||||
if (buff->meta->tags.find(tag) != buff->meta->tags.end()) {
|
||||
del_buffs.push_back(buff->buff_uniid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
for (int buff_uniid : del_buffs) {
|
||||
owner->RemoveBuffByUniId(buff_uniid);
|
||||
}
|
||||
}
|
||||
|
||||
void Buff::ProcAISeting()
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -69,6 +69,10 @@ class Buff
|
||||
void ProcSeletTargetWithSelfPos();
|
||||
void ProcTurnOver();
|
||||
void ProcPullToWalkable();
|
||||
void ProcAutoShot();
|
||||
void ProcBeatBack();
|
||||
void ProcDisperse();
|
||||
void ProcAISeting();
|
||||
|
||||
private:
|
||||
void InternalTimerAddBuff();
|
||||
|
@ -54,9 +54,19 @@ void Bullet::RecalcSelfCollider()
|
||||
|
||||
void Bullet::OnHit(std::set<Entity*>& objects)
|
||||
{
|
||||
std::shared_ptr<Ability> old_context_ability = sender.Get()->context_ability;
|
||||
a8::Vec2 old_context_dir = sender.Get()->context_dir;
|
||||
a8::Vec2 old_context_pos = sender.Get()->context_pos;
|
||||
sender.Get()->context_dir = dir;
|
||||
sender.Get()->context_pos = GetPos();
|
||||
|
||||
for (auto& target : objects) {
|
||||
target->OnBulletHit(this);
|
||||
}
|
||||
|
||||
sender.Get()->context_dir = old_context_dir;
|
||||
sender.Get()->context_pos = old_context_pos;
|
||||
sender.Get()->context_ability = old_context_ability;
|
||||
}
|
||||
|
||||
void Bullet::ProcBomb()
|
||||
@ -357,6 +367,9 @@ void Bullet::Check(float distance)
|
||||
//穿人
|
||||
return;
|
||||
}
|
||||
if (c->HasBuffEffect(kBET_BulletThrough)) {
|
||||
return;
|
||||
}
|
||||
AabbCollider aabb_box;
|
||||
c->GetHitAabbBox(aabb_box);
|
||||
if (c != sender.Get() && !c->dead && TestCollision(room, &aabb_box)) {
|
||||
@ -528,7 +541,9 @@ void Bullet::AddGunBuff()
|
||||
{
|
||||
if (sender.Get()) {
|
||||
std::shared_ptr<Ability> old_context_ability = sender.Get()->context_ability;
|
||||
a8::Vec2 old_context_dir = sender.Get()->context_dir;
|
||||
a8::Vec2 old_context_pos = sender.Get()->context_pos;
|
||||
sender.Get()->context_dir = dir;
|
||||
sender.Get()->context_pos = GetPos();
|
||||
if (IsCurrWeapon()) {
|
||||
sender.Get()->context_ability = ability_;
|
||||
@ -542,6 +557,7 @@ void Bullet::AddGunBuff()
|
||||
1
|
||||
);
|
||||
}
|
||||
sender.Get()->context_dir = old_context_dir;
|
||||
sender.Get()->context_pos = old_context_pos;
|
||||
sender.Get()->context_ability = old_context_ability;
|
||||
}
|
||||
|
@ -275,6 +275,9 @@ void Car::OnBulletHit(Bullet* bullet)
|
||||
GetAbility()->GetAttrAbs(kHAT_Def);
|
||||
float finaly_dmg = dmg * (1 - def/MetaMgr::Instance()->K);
|
||||
finaly_dmg = std::max(finaly_dmg, 0.0f);
|
||||
if (bullet->meta->buff_meta) {
|
||||
MustBeAddBuff(bullet->sender.Get(), bullet->meta->i->buffid());
|
||||
}
|
||||
DecHP(finaly_dmg,
|
||||
bullet->sender.Get()->GetUniId(),
|
||||
bullet->sender.Get()->GetName(),
|
||||
|
@ -359,6 +359,7 @@ enum ObstacleType_e
|
||||
kObstacleGully = 7,
|
||||
kObstacleAirDropBox = 8,
|
||||
kObstacleOilBucket = 9,
|
||||
kObstacleKeepRangeBuff = 10,
|
||||
};
|
||||
|
||||
enum BulletHit_e
|
||||
|
@ -67,6 +67,7 @@ enum BuffEffectType_e
|
||||
kBET_Rescue = 45, //救援
|
||||
kBET_AddCarBuff = 46, //给载具加buff
|
||||
kBET_RemoveCarBuff = 47, //移除载具身上的buff
|
||||
kBET_BulletThrough = 48, //穿透
|
||||
|
||||
kBET_FollowMaster = 49, //跟随主人
|
||||
kBET_ThroughWall = 50, //穿墙
|
||||
@ -85,6 +86,10 @@ enum BuffEffectType_e
|
||||
kBET_MountainTop = 63, //在山顶
|
||||
kBET_UseSkill = 64, //使用技能
|
||||
kBET_CamouflageAddition = 65, //对抗伪装
|
||||
kBET_AutoShot = 66, //自动射击
|
||||
kBET_BeatBack = 67, //击退
|
||||
kBET_Disperse = 68, //驱散
|
||||
kBET_AiSeting = 69, //设置ai参数
|
||||
|
||||
kBET_End
|
||||
};
|
||||
|
@ -102,7 +102,9 @@ void InternalShot(Creature* c,
|
||||
{
|
||||
if (weapon_meta->i->_inventory_slot() == IS_TRAP ||
|
||||
weapon_meta->i->_inventory_slot() == IS_MINE) {
|
||||
a8::Vec2 old_context_dir = c->context_dir;
|
||||
a8::Vec2 old_context_pos = c->context_pos;
|
||||
c->context_dir =c->GetAttackDir();
|
||||
c->context_pos = c->GetPos() + c->GetAttackDir() * fly_distance;
|
||||
MetaData::Buff * buff_meta = MetaMgr::Instance()->GetBuff(bullet_meta->i->buffid());
|
||||
if (buff_meta) {
|
||||
@ -111,6 +113,7 @@ void InternalShot(Creature* c,
|
||||
1
|
||||
);
|
||||
}
|
||||
c->context_dir = old_context_dir;
|
||||
c->context_pos = old_context_pos;
|
||||
return;
|
||||
}
|
||||
@ -363,7 +366,6 @@ int Creature::AddBuff(Creature* caster,
|
||||
}
|
||||
}
|
||||
}
|
||||
return new_buff_uniid;
|
||||
#ifdef DEBUG
|
||||
SendDebugMsg(a8::Format("添加buff_id:%d effect:%d %s params:%d,%d,%d,%d,%d",
|
||||
{
|
||||
@ -377,6 +379,7 @@ int Creature::AddBuff(Creature* caster,
|
||||
buff_meta->int_param5,
|
||||
}));
|
||||
#endif
|
||||
return new_buff_uniid;
|
||||
}
|
||||
|
||||
bool Creature::IsImmuneBuffEffect(int buff_effect)
|
||||
@ -407,12 +410,60 @@ int Creature::TryAddBuff(Creature* caster, int buff_id)
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Creature::TryAddBuffWithTarget(Creature* caster, int buff_id)
|
||||
{
|
||||
MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff(buff_id);
|
||||
if (buff_meta) {
|
||||
bool be_add = false;
|
||||
switch (buff_meta->i->buff_target()) {
|
||||
case kBuffTargetSelf:
|
||||
{
|
||||
be_add = caster == this;
|
||||
}
|
||||
break;
|
||||
case kBuffTargetFriendly:
|
||||
{
|
||||
team_id == caster->team_id;
|
||||
}
|
||||
break;
|
||||
case kBuffTargetEnemy:
|
||||
{
|
||||
team_id != caster->team_id;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
}
|
||||
break;
|
||||
}
|
||||
return TryAddBuff(caster, buff_id);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Creature::RemoveBuffById(int buff_id)
|
||||
{
|
||||
std::vector<std::tuple<MetaData::Buff*, Creature*>> removed_buffs;
|
||||
int buff_uniid = 0;
|
||||
for (auto itr = buff_list_.begin(); itr != buff_list_.end(); ++itr) {
|
||||
Buff& buff = *itr;
|
||||
if (buff.meta->i->buff_id() == buff_id) {
|
||||
buff_uniid = buff.buff_uniid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (buff_uniid != 0) {
|
||||
RemoveBuffByUniId(buff_uniid);
|
||||
}
|
||||
}
|
||||
|
||||
void Creature::RemoveBuffByUniId(int buff_uniid)
|
||||
{
|
||||
int buff_id = 0;
|
||||
std::vector<std::tuple<MetaData::Buff*, Creature*>> removed_buffs;
|
||||
for (auto itr = buff_list_.begin(); itr != buff_list_.end(); ++itr) {
|
||||
Buff& buff = *itr;
|
||||
if (buff.buff_uniid == buff_uniid) {
|
||||
buff_id = buff.meta->i->buff_id();
|
||||
removed_buffs.push_back(std::make_tuple(buff.meta, buff.GetCaster().Get()));
|
||||
OnBuffRemove(buff);
|
||||
buff.UnInit();
|
||||
@ -472,7 +523,7 @@ void Creature::RemoveBuffById(int buff_id)
|
||||
SendDebugMsg(a8::Format("移除buff_id:%d",
|
||||
{
|
||||
buff_id
|
||||
}));
|
||||
}));
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -730,6 +781,7 @@ void Creature::DoSkill(int skill_id,
|
||||
skill_distance_ = skill_distance;
|
||||
curr_skill_ = skill;
|
||||
playing_skill = true;
|
||||
context_dir = skill_dir_;
|
||||
context_pos = GetPos() + skill_dir_ * skill_distance_;
|
||||
CurrentSkill()->last_use_frameno = room->GetFrameNo();
|
||||
if (CurrentSkill()->meta->i->skill_target() == kST_Self
|
||||
@ -912,6 +964,7 @@ Skill* Creature::CurrentSkill()
|
||||
|
||||
void Creature::ProcBuffEffect(Creature* caster, Buff* buff)
|
||||
{
|
||||
MetaData::Buff* buff_meta = buff->meta;
|
||||
switch (buff->meta->i->buff_effect()) {
|
||||
case kBET_ChgAttr:
|
||||
case kBET_Car:
|
||||
@ -1209,6 +1262,26 @@ void Creature::ProcBuffEffect(Creature* caster, Buff* buff)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kBET_AutoShot:
|
||||
{
|
||||
buff->ProcAutoShot();
|
||||
}
|
||||
break;
|
||||
case kBET_BeatBack:
|
||||
{
|
||||
buff->ProcBeatBack();
|
||||
}
|
||||
break;
|
||||
case kBET_Disperse:
|
||||
{
|
||||
buff->ProcDisperse();
|
||||
}
|
||||
break;
|
||||
case kBET_AiSeting:
|
||||
{
|
||||
buff->ProcAISeting();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
}
|
||||
@ -1830,6 +1903,9 @@ void Creature::SummonObstacle(Buff* buff, int id, const a8::Vec2& pos)
|
||||
obstacle->Active();
|
||||
obstacle->context_ability = context_ability;
|
||||
slave_things_.push_back(std::make_tuple(buff->meta->i->buff_id(), obstacle));
|
||||
#ifdef DEBUG
|
||||
SendDebugMsg(a8::Format("召唤物件 buff_id:%d thing_id:%d", {buff->meta->i->buff_id(), id}));
|
||||
#endif
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
@ -2418,3 +2494,14 @@ void Creature::ProcOnceChgAttrBuff(MetaData::Buff* buff_meta)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Creature::TraverseBuff(std::function<void (Buff*, bool&)> func)
|
||||
{
|
||||
bool stop = false;
|
||||
for (auto& buff : buff_list_) {
|
||||
func(&buff, stop);
|
||||
if (stop) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,6 +69,7 @@ class Creature : public MoveableEntity
|
||||
|
||||
Weapon second_weapon;
|
||||
a8::Vec2 context_pos;
|
||||
a8::Vec2 context_dir;
|
||||
std::shared_ptr<Ability> context_ability;
|
||||
|
||||
bool need_sync_active_player = false;
|
||||
@ -89,6 +90,7 @@ class Creature : public MoveableEntity
|
||||
virtual void RemoveOutObjects(Entity* entity) {};
|
||||
virtual bool Attackable(Room* room) override;
|
||||
virtual bool ReceiveExplosionDmg(Explosion* explosion) override;
|
||||
virtual bool IsCreature(Room* room) override { return true;};
|
||||
bool HasBuffEffect(int buff_effect_id);
|
||||
Buff* GetBuffByEffectId(int effect_id);
|
||||
Buff* GetBuffById(int buff_id);
|
||||
@ -101,7 +103,9 @@ class Creature : public MoveableEntity
|
||||
bool IsImmuneBuffEffect(int buff_effect);
|
||||
int MustBeAddBuff(Creature* caster, int buff_id);
|
||||
int TryAddBuff(Creature* caster, int buff_id);
|
||||
int TryAddBuffWithTarget(Creature* caster, int buff_id);
|
||||
void RemoveBuffById(int buff_id);
|
||||
void RemoveBuffByUniId(int buff_uniid);
|
||||
void ClearBuffById(int buff_id);
|
||||
void RecalcBuffAttr();
|
||||
void RemoveBuffByEffectId(int buff_effect_id);
|
||||
@ -206,6 +210,7 @@ class Creature : public MoveableEntity
|
||||
Trigger* GetTrigger() { return trigger_; };
|
||||
std::shared_ptr<Ability>& GetAbility() { return ability_; };
|
||||
void RefreshHP();
|
||||
void TraverseBuff(std::function<void (Buff*, bool&)> func);
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -14,6 +14,19 @@ void DummyEntity::Initialize()
|
||||
for (auto& obj : *blocks) {
|
||||
switch (obj.shape()) {
|
||||
case 1:
|
||||
{
|
||||
CircleCollider* collider = new CircleCollider();
|
||||
collider->owner = this;
|
||||
collider->pos = a8::Vec2(obj.x(), obj.y());
|
||||
collider->rad = obj.rad();
|
||||
if (obj.bullet_penetrate()) {
|
||||
a8::SetBitFlag(collider->tag, kHalfWallTag);
|
||||
}
|
||||
AddEntityCollider(collider);
|
||||
permanent_map_service->AddCollider(collider);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
AabbCollider* collider = new AabbCollider();
|
||||
collider->owner = this;
|
||||
@ -21,21 +34,14 @@ void DummyEntity::Initialize()
|
||||
obj.y() - obj.height()/2.0);
|
||||
collider->_max = a8::Vec2(obj.x() + obj.width()/2.0,
|
||||
obj.y() + obj.height()/2.0);
|
||||
if (obj.bullet_penetrate()) {
|
||||
a8::SetBitFlag(collider->tag, kHalfWallTag);
|
||||
}
|
||||
AddEntityCollider(collider);
|
||||
collider_list.push_back(collider);
|
||||
permanent_map_service->AddCollider(collider);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
CircleCollider* collider = new CircleCollider();
|
||||
collider->owner = this;
|
||||
collider->pos = a8::Vec2(obj.x(), obj.y());
|
||||
collider->rad = obj.rad();
|
||||
AddEntityCollider(collider);
|
||||
permanent_map_service->AddCollider(collider);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ class Entity
|
||||
virtual float GetHitRadius() { return GetRadius();};
|
||||
virtual void GetCircleBox(CircleCollider& circle_box);
|
||||
virtual bool IsDead(Room* room) { return false;};
|
||||
virtual bool IsCreature(Room* room) { return false;};
|
||||
virtual long long GetDeadFrameNo(Room* room) { return 0;};
|
||||
virtual void OnPreCollision(Room* room) {};
|
||||
virtual void RecalcSelfCollider() {};
|
||||
|
@ -116,6 +116,9 @@ void Explosion::InternalAttack()
|
||||
}
|
||||
);
|
||||
for (auto& target : objects) {
|
||||
if (target->IsCreature(room_) && ((Creature*)target)->HasBuffEffect(kBET_BulletThrough)) {
|
||||
continue;
|
||||
}
|
||||
target->OnExplosionHit(this);
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ void Hero::OnBulletHit(Bullet* bullet)
|
||||
sender->stats.damage_amount_out += finaly_dmg;
|
||||
#endif
|
||||
if (bullet->meta->buff_meta) {
|
||||
MustBeAddBuff(this, bullet->meta->i->buffid());
|
||||
MustBeAddBuff(bullet->sender.Get(), bullet->meta->i->buffid());
|
||||
}
|
||||
DecHP(finaly_dmg,
|
||||
bullet->sender.Get()->GetUniId(),
|
||||
|
@ -1141,6 +1141,7 @@ void Human::RefreshView()
|
||||
case ET_Building:
|
||||
case ET_Obstacle:
|
||||
case ET_Loot:
|
||||
case ET_MapBlock:
|
||||
{
|
||||
AddToNewObjects(entity);
|
||||
}
|
||||
@ -2715,6 +2716,7 @@ void Human::GetViewObjects(std::set<Entity*>& view_objects)
|
||||
case ET_Building:
|
||||
case ET_Obstacle:
|
||||
case ET_Loot:
|
||||
case ET_MapBlock:
|
||||
{
|
||||
view_objects.insert(entity);
|
||||
}
|
||||
@ -2799,6 +2801,7 @@ void Human::ProcIncGridList(std::set<GridCell*>& old_grids,
|
||||
case ET_Building:
|
||||
case ET_Obstacle:
|
||||
case ET_Loot:
|
||||
case ET_MapBlock:
|
||||
{
|
||||
AddToNewObjects(entity);
|
||||
RemoveOutObjects(entity);
|
||||
@ -2847,6 +2850,7 @@ void Human::ProcDecGridList(std::set<GridCell*>& old_grids,
|
||||
case ET_Building:
|
||||
case ET_Obstacle:
|
||||
case ET_Loot:
|
||||
case ET_MapBlock:
|
||||
{
|
||||
AddOutObjects(entity);
|
||||
}
|
||||
@ -3541,7 +3545,7 @@ void Human::OnBulletHit(Bullet* bullet)
|
||||
sender->stats.damage_amount_out += finaly_dmg;
|
||||
#endif
|
||||
if (bullet->meta->buff_meta) {
|
||||
MustBeAddBuff(this, bullet->meta->i->buffid());
|
||||
MustBeAddBuff(bullet->sender.Get(), bullet->meta->i->buffid());
|
||||
}
|
||||
if (bullet->sender.Get() && bullet->sender.Get()->IsCar() && bullet->passenger.Get()) {
|
||||
DecHP(finaly_dmg,
|
||||
|
@ -1,6 +1,10 @@
|
||||
#include "precompile.h"
|
||||
|
||||
#include "mapblock.h"
|
||||
#include "collider.h"
|
||||
#include "cs_proto.pb.h"
|
||||
#include "typeconvert.h"
|
||||
#include "metamgr.h"
|
||||
|
||||
MapBlock::MapBlock()
|
||||
{
|
||||
@ -24,22 +28,67 @@ void MapBlock::RecalcSelfCollider()
|
||||
|
||||
void MapBlock::FillMFObjectPart(Room* room, Human* hum, cs::MFObjectPart* part_data)
|
||||
{
|
||||
|
||||
part_data->set_object_type(ET_Obstacle);
|
||||
cs::MFObstaclePart* p = part_data->mutable_union_obj_2();
|
||||
p->set_obj_uniid(GetUniId());
|
||||
TypeConvert::ToPb(GetPos(), p->mutable_pos());
|
||||
p->set_scale(1.0f);
|
||||
}
|
||||
|
||||
void MapBlock::FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data)
|
||||
{
|
||||
full_data->set_object_type(ET_Obstacle);
|
||||
if (IsClientCached(hum)) {
|
||||
int object_flags = 0;
|
||||
a8::SetBitFlag(object_flags, kOfReadCache);
|
||||
full_data->set_obj_uniid(GetUniId());
|
||||
full_data->set_object_flags(object_flags);
|
||||
return;
|
||||
}
|
||||
|
||||
cs::MFObstacleFull* p = full_data->mutable_union_obj_2();
|
||||
if (CanClientCache(hum)) {
|
||||
int object_flags = 0;
|
||||
a8::SetBitFlag(object_flags, kOfWriteCache);
|
||||
#if 0
|
||||
full_data->set_obj_uniid(GetUniId());
|
||||
#endif
|
||||
full_data->set_object_flags(object_flags);
|
||||
AddClientCache(hum);
|
||||
}
|
||||
p->set_obj_uniid(GetUniId());
|
||||
TypeConvert::ToPb(GetPos(), p->mutable_pos());
|
||||
p->set_scale(1.0f);
|
||||
|
||||
p->set_obstacle_id(meta->i->thing_id());
|
||||
p->set_health(0);
|
||||
p->set_dead(false);
|
||||
p->set_dead_at_thisframe(false);
|
||||
|
||||
p->set_is_door(false);
|
||||
{
|
||||
cs::MFCollider* collider = full_data->mutable_union_obj_2()->mutable_collider();
|
||||
collider->set_shape(shape);
|
||||
if (shape == 1) {
|
||||
collider->set_width(rad);
|
||||
collider->set_height(rad);
|
||||
} else {
|
||||
collider->set_width(width);
|
||||
collider->set_height(height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MapBlock::GetAabbBox(AabbCollider& aabb_box)
|
||||
{
|
||||
|
||||
aabb_box.active = false;
|
||||
aabb_box.owner = this;
|
||||
}
|
||||
|
||||
void MapBlock::GetCircleBox(CircleCollider& circle_box)
|
||||
{
|
||||
|
||||
circle_box.active = false;
|
||||
circle_box.owner = this;
|
||||
}
|
||||
|
||||
bool MapBlock::IsDead(Room* room)
|
||||
|
@ -45,8 +45,6 @@ protected:
|
||||
MapBlock();
|
||||
|
||||
protected:
|
||||
CircleCollider* self_collider_ = nullptr;
|
||||
AabbCollider* self_collider2_ = nullptr;
|
||||
|
||||
friend class EntityFactory;
|
||||
};
|
||||
|
@ -280,11 +280,27 @@ void MapInstance::CreateBlock()
|
||||
for (auto& obj : *blocks) {
|
||||
switch (obj.shape()) {
|
||||
case 1:
|
||||
{
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
if (!obj.bullet_penetrate()) {
|
||||
MapBlock* block = EntityFactory::Instance()->MakeBlock(++current_map_block_uniid_);
|
||||
block->meta = MetaMgr::Instance()->GetMapThing
|
||||
(obj.bullet_penetrate() ? 40002 : 40001);
|
||||
block->shape = obj.shape();
|
||||
block->width = obj.width();
|
||||
block->height = obj.height();
|
||||
block->rad = obj.rad();
|
||||
block->permanent_map_service = map_service_;
|
||||
block->SetPos(a8::Vec2(obj.x(), obj.y()));
|
||||
block->Initialize();
|
||||
uniid_hash_[block->GetUniId()] = block;
|
||||
grid_service_->AddPermanentEntity(block);
|
||||
if (!block->meta) {
|
||||
abort();
|
||||
}
|
||||
} else {
|
||||
int i = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -822,6 +822,7 @@ namespace MetaData
|
||||
a8::Split(i->buff_param1(), strings, '|');
|
||||
for (auto& str : strings) {
|
||||
param1_int_list.push_back(a8::XValue(str).GetInt());
|
||||
param1_int_set.insert(a8::XValue(str).GetInt());
|
||||
}
|
||||
}
|
||||
{
|
||||
@ -849,6 +850,13 @@ namespace MetaData
|
||||
param4_int_list.push_back(a8::XValue(str).GetInt());
|
||||
}
|
||||
}
|
||||
{
|
||||
std::vector<std::string> strings;
|
||||
a8::Split(i->tag(), strings, '|');
|
||||
for (auto& str : strings) {
|
||||
tags.insert(a8::XValue(str).GetInt());
|
||||
}
|
||||
}
|
||||
{
|
||||
std::vector<std::string> strings;
|
||||
a8::Split(i->post_remove_action(), strings, '|');
|
||||
|
@ -213,6 +213,7 @@ namespace MetaData
|
||||
int int_param5 = 0;
|
||||
std::vector<int> param1_int_list;
|
||||
std::vector<int> param2_int_list;
|
||||
std::set<int> param1_int_set;
|
||||
std::set<int> param2_int_set;
|
||||
std::vector<int> param3_int_list;
|
||||
std::vector<int> param4_int_list;
|
||||
@ -220,6 +221,7 @@ namespace MetaData
|
||||
std::vector<std::tuple<int, std::vector<int>>> post_remove_action;
|
||||
std::set<int> immune_buffeffect;
|
||||
std::vector<std::tuple<int, float, float, int, int>> hero_infos;
|
||||
std::set<int> tags;
|
||||
|
||||
std::vector<int> child_buff_list;
|
||||
};
|
||||
|
@ -764,12 +764,15 @@ std::tuple<long long, a8::Vec2>* Obstacle::GetInteractionData(Human* sender)
|
||||
|
||||
void Obstacle::AddObstacleBuff(Creature* c)
|
||||
{
|
||||
a8::Vec2 old_context_dir = c->context_dir;
|
||||
a8::Vec2 old_context_pos = c->context_pos;
|
||||
c->context_dir = c->GetAttackDir();
|
||||
c->context_pos = c->GetPos();
|
||||
for (int buff_id : meta->buff_list) {
|
||||
c->TryAddBuff(c, buff_id);
|
||||
}
|
||||
c->context_pos = old_context_pos;
|
||||
c->context_dir = old_context_dir;
|
||||
}
|
||||
|
||||
void Obstacle::ClearObstacleBuff(Creature* c)
|
||||
|
@ -210,7 +210,7 @@ void Player::UpdateShot()
|
||||
series_shot_frames = 0;
|
||||
return;
|
||||
}
|
||||
if (HasBuffEffect(kBET_Vertigo)) {
|
||||
if (HasBuffEffect(kBET_Vertigo) && !HasBuffEffect(kBET_AutoShot)) {
|
||||
return;
|
||||
}
|
||||
if (GetCar()) {
|
||||
@ -1056,8 +1056,19 @@ void Player::_CMMove(f8::MsgHdr& hdr, const cs::CMMove& msg)
|
||||
std::abs(msg.attack_dir().y()) > 0.00001f
|
||||
)
|
||||
){
|
||||
if (!HasBuffEffect(kBET_Vertigo) &&
|
||||
!(GetCar() && (GetCar()->HasBuffEffect(kBET_Vertigo) || !GetCar()->HasOil()))) {
|
||||
bool can_set = true;
|
||||
if (HasBuffEffect(kBET_Vertigo)) {
|
||||
can_set = HasBuffEffect(kBET_AutoShot);
|
||||
} else if (GetCar()) {
|
||||
if (GetCar()->HasOil()) {
|
||||
if (GetCar()->HasBuffEffect(kBET_Vertigo)) {
|
||||
can_set = GetCar()->HasBuffEffect(kBET_AutoShot);
|
||||
}
|
||||
} else {
|
||||
can_set = false;
|
||||
}
|
||||
}
|
||||
if (can_set) {
|
||||
a8::Vec2 attack_dir;
|
||||
TypeConvert::FromPb(attack_dir, &msg.attack_dir());
|
||||
attack_dir.Normalize();
|
||||
@ -1065,8 +1076,6 @@ void Player::_CMMove(f8::MsgHdr& hdr, const cs::CMMove& msg)
|
||||
if (GetCar() && GetCar()->IsDriver(this)) {
|
||||
GetCar()->SetAttackDir(GetAttackDir());
|
||||
}
|
||||
} else {
|
||||
int i = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1084,8 +1093,10 @@ void Player::_CMMove(f8::MsgHdr& hdr, const cs::CMMove& msg)
|
||||
if (shot_start && !shot_hold) {
|
||||
|
||||
} else {
|
||||
shot_start = msg.shot_start();
|
||||
shot_hold = msg.shot_hold();
|
||||
if (!HasBuffEffect(kBET_AutoShot)) {
|
||||
shot_start = msg.shot_start();
|
||||
shot_hold = msg.shot_hold();
|
||||
}
|
||||
}
|
||||
fly_distance = std::min(200.0f, msg.fly_distance());
|
||||
if (!shot_hold) {
|
||||
|
@ -41,6 +41,9 @@ RoomObstacle::~RoomObstacle()
|
||||
if (!grid_list_) {
|
||||
A8_SAFE_DELETE(grid_list_);
|
||||
}
|
||||
if (!hit_objects_) {
|
||||
A8_SAFE_DELETE(hit_objects_);
|
||||
}
|
||||
}
|
||||
|
||||
void RoomObstacle::Initialize()
|
||||
@ -277,6 +280,11 @@ void RoomObstacle::Active()
|
||||
ActiveAirDrop();
|
||||
}
|
||||
break;
|
||||
case kObstacleKeepRangeBuff:
|
||||
{
|
||||
ActiveKeepRangeBuff();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
}
|
||||
@ -465,3 +473,79 @@ Entity* RoomObstacle::GetRealObject(Room* room)
|
||||
{
|
||||
return room->GetEntityByUniId(real_object_uniid);
|
||||
}
|
||||
|
||||
void RoomObstacle::ActiveKeepRangeBuff()
|
||||
{
|
||||
auto check_cb =
|
||||
[] (const a8::XParams& param)
|
||||
{
|
||||
RoomObstacle* obstacle = (RoomObstacle*)param.sender.GetUserData();
|
||||
obstacle->ProcKeepRangeBuff();
|
||||
};
|
||||
room->xtimer.AddRepeatTimerAndAttach
|
||||
(
|
||||
1,
|
||||
a8::XParams()
|
||||
.SetSender(this),
|
||||
check_cb,
|
||||
&xtimer_attacher.timer_list_
|
||||
);
|
||||
room->xtimer.AddDeadLineTimerAndAttach
|
||||
(
|
||||
meta->i->time() / FRAME_RATE_MS,
|
||||
a8::XParams()
|
||||
.SetSender(this),
|
||||
[] (const a8::XParams& param)
|
||||
{
|
||||
RoomObstacle* obstacle = (RoomObstacle*)param.sender.GetUserData();
|
||||
obstacle->DetachFromMaster();
|
||||
},
|
||||
&xtimer_attacher.timer_list_
|
||||
);
|
||||
}
|
||||
|
||||
void RoomObstacle::ProcKeepRangeBuff()
|
||||
{
|
||||
if (!grid_list_) {
|
||||
grid_list_ = new std::set<GridCell*>();
|
||||
room->grid_service->GetAllCellsByXy(room, GetPos().x, GetPos().y, *grid_list_);
|
||||
}
|
||||
if (!hit_objects_) {
|
||||
hit_objects_ = new std::map<int, CreatureWeakPtr>();
|
||||
}
|
||||
if (grid_list_ && master.Get() && !IsDead(room)) {
|
||||
std::set<Creature*> target_list;
|
||||
room->grid_service->TraverseCreatures
|
||||
(room->GetRoomIdx(),
|
||||
*grid_list_,
|
||||
[this, &target_list] (Creature* hum, bool& stop)
|
||||
{
|
||||
if (master.Get()->team_id != hum->team_id && TestCollision(room, hum)) {
|
||||
target_list.insert(hum);
|
||||
}
|
||||
}
|
||||
);
|
||||
for (Creature* hum : target_list) {
|
||||
for (int buff_id : meta->buff_list) {
|
||||
MetaData::Buff* buff_meta = MetaMgr::Instance()->GetBuff(buff_id);
|
||||
if (buff_meta && hum->GetBuffById(buff_id)) {
|
||||
hum->AddBuff(master.Get(),
|
||||
buff_meta,
|
||||
1);
|
||||
}
|
||||
}
|
||||
if (hit_objects_->find(hum->GetUniId()) == hit_objects_->end()) {
|
||||
(*hit_objects_)[hum->GetUniId()] = hum->GetWeakPtrRef();
|
||||
}
|
||||
}
|
||||
for (auto& pair : *hit_objects_) {
|
||||
for (int buff_id : meta->buff_list) {
|
||||
if (pair.second.Get() && target_list.find(pair.second.Get()) == target_list.end()) {
|
||||
pair.second.Get()->RemoveBuffById(buff_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
room->xtimer.DeleteTimer(room->xtimer.GetRunningTimer());
|
||||
}
|
||||
}
|
||||
|
@ -38,13 +38,16 @@ private:
|
||||
void ActiveHideHouse();
|
||||
void ActiveGully();
|
||||
void ActiveAirDrop();
|
||||
void ActiveKeepRangeBuff();
|
||||
|
||||
void SummonAirDropBox(int box_id);
|
||||
void ProcKeepRangeBuff();
|
||||
|
||||
protected:
|
||||
std::set<GridCell*>* grid_list_ = nullptr;
|
||||
int explosion_times_ = 0;
|
||||
bool detached_ = false;
|
||||
std::map<int, CreatureWeakPtr>* hit_objects_ = nullptr;
|
||||
|
||||
RoomObstacle();
|
||||
|
||||
|
@ -219,7 +219,9 @@ void Trigger::TraverseCondBuffs(int cond, std::function<void (Buff*, bool&)> fun
|
||||
void Trigger::TriggeCondBuffAll(int cond)
|
||||
{
|
||||
std::shared_ptr<Ability> old_context_ability = owner_->context_ability;
|
||||
a8::Vec2 old_context_dir = owner_->context_dir;
|
||||
a8::Vec2 old_context_pos = owner_->context_pos;
|
||||
owner_->context_dir = owner_->GetAttackDir();
|
||||
owner_->context_pos = owner_->GetPos();
|
||||
TraverseCondBuffs
|
||||
(cond,
|
||||
@ -227,6 +229,7 @@ void Trigger::TriggeCondBuffAll(int cond)
|
||||
{
|
||||
AddBuffs(cond, buff->meta->param4_int_list);
|
||||
});
|
||||
owner_->context_dir = old_context_dir;
|
||||
owner_->context_pos = old_context_pos;
|
||||
owner_->context_ability = old_context_ability;
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ message MFPropertyChg
|
||||
//碰撞体
|
||||
message MFCollider
|
||||
{
|
||||
optional int32 shape = 1; //形状 1:矩形 2:圆形(当是圆形的时候width=eight)
|
||||
optional int32 shape = 1; //形状 1:矩形 2:圆形(当是圆形的时候width=height)
|
||||
optional int32 width = 2; //宽度
|
||||
optional int32 height = 3; //高度
|
||||
}
|
||||
|
@ -258,6 +258,7 @@ message Buff
|
||||
optional int32 coexist_num = 18;
|
||||
optional int32 dead_valid = 23;
|
||||
optional int32 buff_interval = 24;
|
||||
optional string tag = 25;
|
||||
}
|
||||
|
||||
message Drop
|
||||
@ -448,4 +449,5 @@ message MapBlockJson
|
||||
optional float height = 7;
|
||||
optional float width = 8;
|
||||
optional float rad = 9;
|
||||
optional int32 bullet_penetrate = 10;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user