完成散弹枪功能

This commit is contained in:
aozhiwei 2019-07-18 10:49:34 +08:00
parent afd4e8061a
commit 8388a658e5
2 changed files with 77 additions and 49 deletions

View File

@ -235,57 +235,27 @@ void Human::Shot()
void Human::DirectShot(MetaData::Equip* bullet_meta, int skill_id) void Human::DirectShot(MetaData::Equip* bullet_meta, int skill_id)
{ {
#if 0 for (size_t i = 0; i < bullet_meta->bullet_born_offset.size(); ++i) {
for (auto& tuple : bullet_meta->bullet_born_offset) { auto& tuple = bullet_meta->bullet_born_offset[i];
a8::Vec2 bullet_born_offset = a8::Vec2(std::get<0>(tuple), std::get<1>(tuple)); room->xtimer.AddDeadLineTimerAndAttach(std::get<0>(tuple) * FRAME_RATE_MS,
bullet_born_offset.Rotate(attack_dir.CalcAngle(a8::Vec2::UP)); a8::XParams()
a8::Vec2 bullet_born_pos = pos + bullet_born_offset; .SetSender(this)
if (room->OverBorder(bullet_born_pos, 0)) { .SetParam1(bullet_meta)
return; .SetParam2(skill_id)
} .SetParam3(i),
} [] (const a8::XParams& param)
room->frame_event.AddShot(this); {
for (auto& tuple : bullet_meta->bullet_born_offset) { Human* sender = (Human*)param.sender.GetUserData();
a8::Vec2 bullet_born_offset = a8::Vec2(std::get<0>(tuple), std::get<1>(tuple)); MetaData::Equip* bullet_meta = (MetaData::Equip*)param.param1.GetUserData();
bullet_born_offset.Rotate(attack_dir.CalcAngle(a8::Vec2::UP)); if (sender) {
a8::Vec2 bullet_born_pos = pos + bullet_born_offset; sender->InternalShot(bullet_meta,
a8::Vec2 bullet_dir = attack_dir; param.param2,
float bullet_angle = std::get<2>(tuple); param.param3);
if (bullet_meta->i->bullet_angle() >= 0.10f) {
int angle = (int)bullet_meta->i->bullet_angle() * 1000;
if (angle > 0) {
bullet_angle += (rand() % angle) / 1000.0f * (rand() % 2 == 0 ? 1 : -1);
}
}
bullet_dir.Rotate(bullet_angle / 180.0f);
int hit_time = 0;
if (bullet_meta->NeedTrace()) {
hit_time = bullet_meta->i->time() * 1000;
}
if (bullet_meta->NeedTrace()) {
if (skill_id != 0) {
room->frame_event.AddBullet(this, bullet_meta->i->id(),
curr_weapon->weapon_lv, bullet_born_pos, bullet_dir,
fly_distance, hit_time, skill_target_id, skill_id);
} else {
room->frame_event.AddBullet(this, bullet_meta->i->id(),
curr_weapon->weapon_lv, bullet_born_pos, bullet_dir,
fly_distance, hit_time, shot_target_id);
}
} else {
room->frame_event.AddBullet(this, bullet_meta->i->id(),
curr_weapon->weapon_lv,
bullet_born_pos, bullet_dir,
fly_distance, hit_time, 0, skill_id);
}
if (room->BattleStarted()) {
if (bullet_meta->i->equip_subtype() != BulletType_Missile) {
room->CreateBullet(this, bullet_meta, bullet_born_pos, bullet_dir, fly_distance);
}
} }
},
&xtimer_attacher.timer_list_);
} }
OnAttack(); OnAttack();
#endif
} }
void Human::RecalcSelfCollider() void Human::RecalcSelfCollider()
@ -2115,3 +2085,60 @@ void Human::ProcSkillPhase(MetaData::SkillPhase* phase)
break; break;
} }
} }
void Human::InternalShot(MetaData::Equip* bullet_meta, int skill_id, size_t offset_idx)
{
if (offset_idx >= bullet_meta->bullet_born_offset.size()) {
return;
}
const auto& born_points = std::get<1>(bullet_meta->bullet_born_offset[offset_idx]);
for (auto& born_point : born_points) {
a8::Vec2 bullet_born_offset = born_point.born_offset;
bullet_born_offset.Rotate(attack_dir.CalcAngle(a8::Vec2::UP));
a8::Vec2 bullet_born_pos = pos + bullet_born_offset;
if (room->OverBorder(bullet_born_pos, 0)) {
return;
}
}
room->frame_event.AddShot(this);
for (auto& born_point : born_points) {
a8::Vec2 bullet_born_offset = born_point.born_offset;
bullet_born_offset.Rotate(attack_dir.CalcAngle(a8::Vec2::UP));
a8::Vec2 bullet_born_pos = pos + bullet_born_offset;
a8::Vec2 bullet_dir = attack_dir;
float bullet_angle = born_point.angle;
if (bullet_meta->i->bullet_angle() >= 0.10f) {
int angle = (int)bullet_meta->i->bullet_angle() * 1000;
if (angle > 0) {
bullet_angle += (rand() % angle) / 1000.0f * (rand() % 2 == 0 ? 1 : -1);
}
}
bullet_dir.Rotate(bullet_angle / 180.0f);
int hit_time = 0;
if (bullet_meta->NeedTrace()) {
hit_time = bullet_meta->i->time() * 1000;
}
if (bullet_meta->NeedTrace()) {
if (skill_id != 0) {
room->frame_event.AddBullet(this, bullet_meta->i->id(),
curr_weapon->weapon_lv, bullet_born_pos, bullet_dir,
fly_distance, hit_time, skill_target_id, skill_id);
} else {
room->frame_event.AddBullet(this, bullet_meta->i->id(),
curr_weapon->weapon_lv, bullet_born_pos, bullet_dir,
fly_distance, hit_time, shot_target_id);
}
} else {
room->frame_event.AddBullet(this, bullet_meta->i->id(),
curr_weapon->weapon_lv,
bullet_born_pos, bullet_dir,
fly_distance, hit_time, 0, skill_id);
}
if (room->BattleStarted()) {
if (bullet_meta->i->equip_subtype() != BulletType_Missile) {
room->CreateBullet(this, bullet_meta, bullet_born_pos, bullet_dir, fly_distance);
}
}
}
OnAttack();
}

View File

@ -224,6 +224,7 @@ private:
void SelectSkillTargets(const a8::Vec2& target_pos, std::set<Entity*>& target_list); void SelectSkillTargets(const a8::Vec2& target_pos, std::set<Entity*>& target_list);
Buff* GetBuffById(int buff_id); Buff* GetBuffById(int buff_id);
void ProcSkillPhase(MetaData::SkillPhase* phase); void ProcSkillPhase(MetaData::SkillPhase* phase);
void InternalShot(MetaData::Equip* bullet_meta, int skill_id, size_t offset_idx);
protected: protected:
long long last_shot_frameno_ = 0; long long last_shot_frameno_ = 0;