diff --git a/server/gameserver/bullet.cc b/server/gameserver/bullet.cc index 03d940d2..d46c9a4e 100644 --- a/server/gameserver/bullet.cc +++ b/server/gameserver/bullet.cc @@ -775,28 +775,20 @@ void Bullet::ClearBuffList() void Bullet::ProcFlyHook(Entity* target) { - float distance = sender.Get()->GetPos().Distance(GetPos()); + ClearBuffList(); + float distance = born_pos.Distance(GetPos()); if (distance < 0.001f) { return; } - a8::Vec2 new_dir = GetPos() - sender.Get()->GetPos(); - new_dir.Normalize(); if (target->IsCreature(room)) { Creature* c = (Creature*)target; +#if 0 room->frame_event.AddPropChg(c->GetWeakPtrRef(), kPropBeHook, 0, sender.Get()->GetUniId()); - - a8::Vec2 old_dir = c->GetMoveDir(); - new_dir.x = -new_dir.x; - new_dir.y = -new_dir.y; - c->SetMoveDir(new_dir); - c->_UpdateMove(distance); - c->SetMoveDir(old_dir); +#endif + c->AutoNavigation(born_pos, gun_meta->i->bullet_speed() * 2); } else { - a8::Vec2 old_dir = sender.Get()->GetMoveDir(); - sender.Get()->SetMoveDir(new_dir); - sender.Get()->_UpdateMove(distance); - sender.Get()->SetMoveDir(old_dir); + sender.Get()->AutoNavigation(GetPos(), gun_meta->i->bullet_speed() * 2); } } diff --git a/server/gameserver/creature.cc b/server/gameserver/creature.cc index 412c0db2..7e1c7e7d 100644 --- a/server/gameserver/creature.cc +++ b/server/gameserver/creature.cc @@ -177,7 +177,7 @@ void InternalShot(Creature* c, return; } } - if (!skill_meta) { + if (!skill_meta || weapon_meta->i->equip_type() == EQUIP_TYPE_THROW) { c->room->frame_event.AddShot(c->GetWeakPtrRef()); } int invincible_buff_uniid = 0; @@ -3486,3 +3486,58 @@ void Creature::_UpdateSpecMove() } } } + +void Creature::AutoNavigation(a8::Vec2 target_pos, float speed) +{ + float distance = GetPos().Distance(target_pos); + if (distance < 0.001f) { + return; + } + if (speed < 0.001f) { + return; + } + + struct NavContext + { + CreatureWeakPtr c; + a8::Vec2 src_pos; + a8::Vec2 target_pos; + a8::Vec2 dir; + int exec_frameno = 0; + float speed = 0.0f; + float distance = 0.0f; + }; + NavContext* context = new NavContext(); + context->c = GetWeakPtrRef(); + context->src_pos = GetPos(); + context->target_pos = target_pos; + context->dir = (target_pos - GetPos()); + context->dir.Normalize(); + context->speed = speed; + context->distance = distance; + room->xtimer.AddRepeatTimerAndAttach + (1, + a8::XParams() + .SetSender(context), + [] (const a8::XParams& param) + { + NavContext* context = (NavContext*)param.sender.GetUserData(); + ++context->exec_frameno; + + Room* room = context->c.Get()->room; + Creature* c = context->c.Get(); + + a8::Vec2 old_pos = c->GetPos(); + float move_length = context->speed / (float)SERVER_FRAME_RATE; + float move_distance = std::min(move_length * context->exec_frameno, context->distance); + a8::Vec2 new_pos = context->src_pos + context->dir * move_distance; + c->SetPos(new_pos); + if (c->CheckCollision()) { + c->SetPos(old_pos); + room->xtimer.DeleteTimer(room->xtimer.GetRunningTimer()); + } else { + + } + }, + &xtimer_attacher.timer_list_); +} diff --git a/server/gameserver/creature.h b/server/gameserver/creature.h index f1f4ac87..49e12a94 100644 --- a/server/gameserver/creature.h +++ b/server/gameserver/creature.h @@ -275,6 +275,7 @@ class Creature : public MoveableEntity float GetAttrAbs(int attr_id); float GetAttrRate(int attr_id); void RecalcDtoAttr(); + void AutoNavigation(a8::Vec2 target_pos, float speed); protected: virtual void OnBuffRemove(Buff& buff);