From eaa8683959ee32d84d77edd3f1588a45305cb07e Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Thu, 29 Dec 2022 09:06:38 +0800 Subject: [PATCH] 1 --- server/gameserver/buff.cc | 855 +----------------- server/gameserver/buff.h | 45 +- server/gameserver/buff/autoshot.cc | 22 +- server/gameserver/buff/batch_add.cc | 55 +- server/gameserver/buff/batch_add.h | 2 +- server/gameserver/buff/beatback.cc | 23 +- server/gameserver/buff/become.cc | 46 +- server/gameserver/buff/berecycle.cc | 25 +- server/gameserver/buff/berecycle.h | 2 +- server/gameserver/buff/callfunc.cc | 47 +- server/gameserver/buff/delay_add.cc | 13 +- server/gameserver/buff/delay_add.h | 2 +- server/gameserver/buff/disperse.cc | 30 +- server/gameserver/buff/dive.cc | 49 +- server/gameserver/buff/driver.cc | 30 +- server/gameserver/buff/hide.cc | 42 +- server/gameserver/buff/hold_shield.cc | 63 +- server/gameserver/buff/immune.cc | 17 +- server/gameserver/buff/in_water.cc | 69 +- server/gameserver/buff/internal_add.cc | 13 +- server/gameserver/buff/internal_add.h | 2 +- server/gameserver/buff/machine_gun.cc | 149 ++- server/gameserver/buff/once_chg_attr.cc | 13 +- server/gameserver/buff/passener.cc | 17 +- server/gameserver/buff/pull_to_walkable.cc | 35 +- server/gameserver/buff/rescuer.cc | 19 +- server/gameserver/buff/reserve.cc | 39 +- server/gameserver/buff/reserve_move.cc | 13 +- .../buff/select_target_with_self_pos.cc | 72 +- server/gameserver/buff/sprint.cc | 150 ++- server/gameserver/buff/summon_hero.cc | 15 +- server/gameserver/buff/summon_hero.h | 2 +- server/gameserver/buff/turnover.cc | 114 ++- 33 files changed, 1168 insertions(+), 922 deletions(-) diff --git a/server/gameserver/buff.cc b/server/gameserver/buff.cc index 5340df18..998a02c7 100644 --- a/server/gameserver/buff.cc +++ b/server/gameserver/buff.cc @@ -30,6 +30,11 @@ Buff::Buff() } +Buff::~Buff() +{ + +} + void Buff::Init() { INIT_LIST_HEAD(&effect_entry); @@ -68,11 +73,6 @@ int Buff::GetLastingTime() return meta->duration_time() * 1000; } -void Buff::ProcDelayAddBuff() -{ - InternalTimerAddBuff(); -} - void Buff::ProcIntervalAddBuff() { InternalTimerAddBuff(); @@ -194,26 +194,11 @@ void Buff::InternalTimerAddBuff() void Buff::ProcSummonHero() { - if (!caster_.Get()->IsHuman()) { - return; - } + } void Buff::ProcBeRecycle() { - owner->room->xtimer.SetIntervalEx - ( - SERVER_FRAME_RATE * 2, - [this] (int event, const a8::Args* args) - { - if (a8::TIMER_EXEC_EVENT == event) { - if (owner->IsHuman()) { - owner->room->GetIncubator()->RecycleAndroid(owner->AsHuman()); - } - } - }, - &xtimer_attacher - ); } bool Buff::NeedSync(Human* hum) @@ -228,86 +213,26 @@ bool Buff::FreezeOperate() void Buff::ProcBecome() { - hold_curr_weapon_idx_ = caster_.Get()->GetCurrWeapon()->weapon_idx; - if (caster_.Get()->IsHuman() && meta->_param2 > 0.01) { - std::vector strings; - a8::Split(meta->buff_param2(), strings, ':'); - for (size_t i = 0; i < strings.size(); ++i) { - int weapon_id = a8::XValue(strings[i]); - const mt::Equip* weapon_meta = mt::Equip::GetById(weapon_id); - if (weapon_meta && i < caster_.Get()->weapons.size()) { - int weapon_idx = weapon_meta->GetWeaponIdx(); - if (weapon_idx >= 0 && weapon_idx < caster_.Get()->weapons.size()) { - Weapon* weapon = &caster_.Get()->weapons[weapon_idx]; - hold_weapons_.push_back(*weapon); - - weapon->weapon_id = weapon_meta->id(); - weapon->meta = weapon_meta; - weapon->skill_meta = skill_meta; - weapon->Recalc(); - weapon->ammo = weapon->GetClipVolume(owner); - if (i == 0) { - caster_.Get()->SetCurrWeapon(weapon); - } - } - } - } - caster_.Get()->MarkSyncActivePlayer(__FILE__, __LINE__, __func__); - caster_.Get()->SyncAroundPlayers(__FILE__, __LINE__, __func__); - } -#ifdef DEBUG1 - caster_.Get()->SendDebugMsg(a8::Format("ProcBecome buff:%d hold_curr_weapon_idx:%d", - { - meta->buff_id(), - hold_curr_weapon_idx_ - })); -#endif } void Buff::ProcRemoveBecome() { - RecoverHoldWeapons(); } void Buff::ProcDriver() { - hold_curr_weapon_idx_ = caster_.Get()->GetCurrWeapon()->weapon_idx; - if (caster_.Get()->IsHuman()) { - Human* hum = (Human*)caster_.Get(); - if (hum->GetCar() && hum->GetCar()->GetCurrWeapon()) { - hold_weapons_.push_back(hum->weapons[hum->GetCar()->GetCurrWeapon()->weapon_idx]); - hum->weapons[hum->GetCar()->GetCurrWeapon()->weapon_idx] = *hum->GetCar()->GetCurrWeapon(); - hum->SetCurrWeapon(&hum->weapons[hum->GetCar()->GetCurrWeapon()->weapon_idx]); - if (hum->GetCar()->meta && - hum->GetSeat() < hum->GetCar()->meta->_shoot_offsets.size() && - std::get<0>(hum->GetCar()->meta->_shoot_offsets[hum->GetSeat()]) - ) { - hum->shoot_offset = std::get<1>(hum->GetCar()->meta->_shoot_offsets[hum->GetSeat()]); - } - } - } - caster_.Get()->MarkSyncActivePlayer(__FILE__, __LINE__, __func__); - caster_.Get()->SyncAroundPlayers(__FILE__, __LINE__, __func__); } void Buff::ProcRemoveDriver() { - RecoverHoldWeapons(); - caster_.Get()->shoot_offset = GlmHelper::ZERO; } void Buff::ProcPassenger() { - hold_curr_weapon_idx_ = caster_.Get()->GetCurrWeapon()->weapon_idx; - CalcPassengerShotOffset(); - caster_.Get()->MarkSyncActivePlayer(__FILE__, __LINE__, __func__); - caster_.Get()->SyncAroundPlayers(__FILE__, __LINE__, __func__); } void Buff::ProcRemovePassenger() { - RecoverHoldWeapons(); - caster_.Get()->shoot_offset = GlmHelper::ZERO; } void Buff::RecoverHoldWeapons() @@ -354,309 +279,14 @@ void Buff::RecoverHoldWeapons() void Buff::ProcSprint() { - if (caster_.Get()->IsPlayer()) { - if (meta->_int_param5) { - owner->IncDisableMoveDirTimes(); - } - { - int old_times = owner->GetDisableMoveDirTimes(); - owner->SetDisableMoveDirTimes(0); - owner->SetMoveDir(owner->context_dir); - owner->SetAttackDir(owner->context_dir); - owner->SetDisableMoveDirTimes(old_times); -#ifdef DEBUG - { - owner->SendDebugMsg(a8::Format("xxxxxxxx move_dir:%d,%d attack_dir:%d,%d speed:%d", - { - owner->GetMoveDir().x, - owner->GetMoveDir().y, - owner->GetAttackDir().x, - owner->GetAttackDir().y, - owner->GetSpeed() - })); - owner->room->xtimer.SetIntervalEx - ( - 2, - [this] (int event, const a8::Args* args) - { - if (a8::TIMER_EXEC_EVENT == event) { - Human* hum = owner->AsHuman(); - hum->SendDebugMsg(a8::Format("xxxxxxxx move_dir:%d,%d attack_dir:%d,%d speed:%d", - { - hum->GetMoveDir().x, - hum->GetMoveDir().y, - hum->GetAttackDir().x, - hum->GetAttackDir().y, - hum->GetSpeed() - })); - } - }, - &xtimer_attacher - ); - } -#endif - } - Player* hum = (Player*)caster_.Get(); - std::map hited_objects = std::map(); - Position pre_pos; - pre_pos = owner->GetPos(); - owner->room->xtimer.SetIntervalEx - ( - 1, - [this, hited_objects, pre_pos] - (int event, const a8::Args* args) mutable - { - Buff* buff = this; - if (!buff->meta->_param3_int_list.empty() || buff->skill_meta) { - std::set enemys; - Position old_pos = buff->owner->GetPos(); - - if (pre_pos.ManhattanDistance2D(buff->owner->GetPos()) > 2) { - a8::Vec2 dir = buff->owner->GetPos().CalcDir2D(pre_pos); - dir.Normalize(); - float distance = buff->owner->GetPos().Distance2D2(pre_pos); - for (int i = 0; i < (distance + 6); i += 5) { - // 999 - #if 1 - #else - buff->owner->MutablePos.FromVec2((pre_pos) + (dir * i)); - #endif - buff->owner->GetHitEnemys(enemys, buff->meta->_param4); - for (auto& enemy : enemys) { - if (enemy->IsEntityType(ET_Car)) { - continue; - } - auto itr = hited_objects.find(enemy->GetUniId()); - if (itr != hited_objects.end()) { - if ((buff->owner->room->GetFrameNo() - itr->second) * FRAME_RATE_MS < - buff->meta->_int_param5) { - continue; - } - } - hited_objects[enemy->GetUniId()] = buff->owner->room->GetFrameNo(); - for (int buff_id : buff->meta->_param3_int_list) { - enemy->TryAddBuff(buff->owner, buff_id); - } - if (buff->skill_meta) { - switch (buff->skill_meta->GetMagicId()) { - case MAGIC_YMCZ: - { - float dmg = SkillHelper::GetYmczDmg(buff->owner, - enemy, - buff->skill_meta); - if (dmg > 0.0001f) { - enemy->DecHP( - dmg, - buff->owner->GetUniId(), - buff->owner->GetName(), - 0, - buff->owner->GetUniId(), - buff->owner->GetName() - ); - } - } - break; - default: - { - } - break; - } - } - } - } - } - - buff->owner->SetPos(old_pos); - pre_pos = buff->owner->GetPos(); - } - }, - &xtimer_attacher); - } - if (skill_meta) { - switch (skill_meta->GetMagicId()) { - case MAGIC_YMCZ: - { - owner->room->xtimer.ModifyTime - (remover_timer, - SkillHelper::GetYmczBuffTime(skill_meta) / FRAME_RATE_MS); - } - break; - default: - { - } - break; - } - } } void Buff::ProcSeletTargetWithSelfPos() { - std::vector targets; - owner->TraverseCreatures - ( - [this, &targets] (Creature* c, bool& stop) - { - if (owner->GetPos().Distance2D2(c->GetPos()) < meta->_int_param3) { - switch (meta->_int_param1) { - case kBST_All: - { - targets.push_back(c); - } - break; - case kBST_Self: - { - if (c == owner) { - targets.push_back(c); - } - } - break; - case kBST_FriendlyIncludeSelf: - { - if (c->team_id == owner->team_id) { - targets.push_back(c); - } - } - break; - case kBST_FriendlyExcludeSelf: - { - if (c->team_id == owner->team_id && c != owner) { - targets.push_back(c); - } - } - break; - case kBST_Enemy: - { - if (c->team_id != owner->team_id) { - targets.push_back(c); - } - } - break; - case kBST_EnemyAndSelf: - { - if (c->team_id != owner->team_id || c == owner) { - targets.push_back(c); - } - } - break; - default: - { - } - break; - } - } - } - ); - for (auto& target : targets) { - for (int buff_id : meta->_param2_int_list) { - target->TryAddBuff(caster_.Get(), buff_id); - } - } } void Buff::ProcTurnOver() { - Skill* skill = owner->CurrentSkill(); - if (!skill) { - return; - } - const mt::SkillPhase* phase = owner->GetCurrSkillPhase(); - if (!phase) { - return; - } - #if 0 - if (phase->time_offset < skill->GetPassedTime()) { - return; - } - #endif - glm::vec3 old_dir = owner->GetMoveDir(); - Position old_pos = owner->GetPos(); - float distance = - owner->HasBuffEffect(kBET_Car) ? phase->param1.GetDouble() * 1.5 : phase->param1.GetDouble(); -#ifdef DEBUG - caster_.Get()->SendDebugMsg(a8::Format("ProcBecome currTimes:%d last_pos:%d,%d curr_pos:%d,%d", - { - skill->GetCurrTimes(), - owner->last_turn_over_pos.x, - owner->last_turn_over_pos.y, - owner->GetPos().x, - owner->GetPos().y - })); -#endif - Global::Instance()->verify_set_pos = 1; - owner->ForwardMove(distance); - Global::Instance()->verify_set_pos = 0; - owner->SetMoveDir(old_dir); - if (phase->param2.GetInt() == 1) { - ++owner->turn_over_times; - owner->last_turn_over_pos = old_pos; - } - float moved_distance = owner->GetPos().Distance2D2(old_pos); - moved_distance = std::min(moved_distance, 200.0f); - if (!meta->_param1_int_list.empty() && moved_distance > 2.0f) { - std::set target_list; - owner->TraverseCreatures - ( - [this, &target_list] (Creature* c, bool& stop) - { - if (owner->IsProperTarget(c) && owner->GetPos().Distance2D2(c->GetPos()) < 300) { - target_list.insert(c); - } - }); - - Position curr_pos = owner->GetPos(); - glm::vec3 dir = old_pos.CalcDir(owner->GetPos()); - GlmHelper::Normalize(dir); - for (int i = 5; i < moved_distance; i += 5) { - owner->GetMutablePos().FromGlmVec3(old_pos.ToGlmVec3() + dir * (float)i); - std::list 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.SetTimeoutEx - ( - meta->_int_param4 / FRAME_RATE_MS * (i / moved_distance), - [this, target] (int event, const a8::Args* args) mutable - { - Creature* c = target; - const mt::Buff* buff_meta = meta; - Entity* caster = c->room->GetEntityByUniId(owner->GetUniId()); - if (caster && caster->IsCreature(c->room)) { - for (int buff_id : buff_meta->_param1_int_list) { - c->TryAddBuff((Creature*)caster, buff_id); - } - } - }, - &target->xtimer_attacher); - } - } - owner->SetPos(curr_pos); - } - if (!meta->_param2_int_list.empty()) { - owner->room->xtimer.SetTimeoutEx - ( - meta->_int_param4 / FRAME_RATE_MS, - [this] (int event, const a8::Args* args) mutable - { - Creature* c = owner; - const mt::Buff* buff_meta = meta; - c->TraverseCreatures - ( - [c, buff_meta] (Creature* target, bool& stop) - { - if (c->GetPos().Distance2D2(target->GetPos()) < buff_meta->_int_param3) { - for (int buff_id : buff_meta->_param2_int_list) { - target->TryAddBuffWithTarget(c, buff_id); - } - } - }); - }, - &owner->xtimer_attacher - ); - } } CreatureWeakPtr& Buff::GetCaster() @@ -675,91 +305,18 @@ void Buff::SetCaster(Creature* caster) void Buff::ProcPullToWalkable() { - if (!owner->CollisonDetection()) { - return; - } - glm::vec3 move_dir = owner->GetMoveDir(); - if (std::abs(move_dir.x) > FLT_EPSILON || - std::abs(move_dir.y) > FLT_EPSILON - ) { - Position old_pos = owner->GetPos(); - for (int i = 1; i < 2000; i += 5) { - // 999 - #if 1 - #else - owner->SetPos(old_pos + move_dir * i); - #endif - if (!owner->CollisonDetection()) { - owner->room->grid_service->MoveCreature(owner); - return; - } - } - owner->FindLocation(); - } else { - owner->FindLocation(); - } } void Buff::ProcAutoShot() { - owner->room->xtimer.SetIntervalEx - ( - 1, - [this] (int event, const a8::Args* args) - { - if (a8::TIMER_EXEC_EVENT == event) { - if (owner->IsHuman()) { -#if 0 - >owner->AsHuman()->shot_start = true; -#endif - owner->AsHuman()->shot_hold = true; - owner->AsHuman()->series_shot_frames = 0; - } - } else if (a8::TIMER_DELETE_EVENT == event) { - if (owner->IsHuman()) { - owner->AsHuman()->shot_hold = false; - owner->AsHuman()->series_shot_frames = 0; - } - } - }, - &xtimer_attacher); } 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) { - glm::vec3 old_move_dir = owner->GetMoveDir(); - owner->SetMoveDir(caster_.Get()->context_dir); - owner->ForwardMove(meta->_param1); - owner->SetMoveDir(old_move_dir); - } - } - } } void Buff::ProcDisperse() { - std::vector 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); - } - if (!del_buffs.empty()) { - owner->TryAddBuff(owner, meta->_int_param2); - } } void Buff::CalcPassengerShotOffset() @@ -786,291 +343,30 @@ void Buff::CalcPassengerShotOffset() void Buff::ProcDive() { - owner->room->xtimer.SetIntervalEx - ( - SERVER_FRAME_RATE, - [this] (int event, const a8::Args* args) - { - if (a8::TIMER_EXEC_EVENT == event) { - if (owner->dead || !owner->IsHuman()) { - owner->RemoveBuffByUniId(buff_uniid); - return; - } - Human* hum = owner->AsHuman(); - if (hum->GetOxygen() > 0) { - hum->DecOxygen(mt::Param::s().dive_oxygen_consume); - hum->room->frame_event.AddPropChg(hum->GetWeakPtrRef(), - kPropDive, - mt::Param::s().dive_oxygen_total, - hum->GetOxygen(), - true); - return; - } - hum->DecHP(mt::Param::s().dive_hp_consume, - VP_Water, - "water", - 0, - 0, - "water"); - } - }, - &xtimer_attacher - ); - if (owner->IsHuman()) { - ++owner->AsHuman()->stats.diving_times; - } } void Buff::ProcRemoveDive() { - if (owner->IsHuman()) { - #if 0 - owner->AsHuman()->SetOxygen(0); - #endif - } } void Buff::ProcInWater() { - if (owner->IsHuman()) { - owner->AsHuman()->room->frame_event.AddPropChg - (owner->AsHuman()->GetWeakPtrRef(), - kPropDive, - mt::Param::s().dive_oxygen_total, - owner->AsHuman()->GetOxygen(), - true); - - if (owner->IsPlayer()) { - owner->room->xtimer.SetIntervalEx - ( - SERVER_FRAME_RATE, - [this] (int event, const a8::Args* args) - { - if (a8::TIMER_EXEC_EVENT == event) { - if (owner->dead || !owner->IsHuman()) { - return; - } - Human* hum = owner->AsHuman(); - if (!hum->HasBuffEffect(kBET_Dive) && - hum->GetOxygen() < mt::Param::s().dive_oxygen_total) { - hum->AddOxygen(mt::Param::s().inwater_oxygen_recover); - hum->room->frame_event.AddPropChg - (hum->GetWeakPtrRef(), - kPropDive, - mt::Param::s().dive_oxygen_total, - hum->GetOxygen(), - true); - return; - } - } - }, - &xtimer_attacher - ); - } - } } void Buff::ProcRemoveInWater() { - if (owner->IsHuman()) { - if (owner->IsPlayer()) { - Human* hum = owner->AsHuman(); - owner->room->xtimer.SetIntervalEx - ( - SERVER_FRAME_RATE, - [hum] (int event, const a8::Args* args) - { - if (hum->HasBuffEffect(kBET_InWater) || hum->dead) { - hum->room->xtimer.DeleteCurrentTimer(); - return; - } - if (hum->GetOxygen() >= mt::Param::s().dive_oxygen_total) { - hum->room->xtimer.DeleteCurrentTimer(); - return; - } - hum->AddOxygen(mt::Param::s().inwater_oxygen_recover); - }, - &hum->xtimer_attacher - ); - } - } } void Buff::ProcReserve() { - if (caster_.Get()) { - glm::vec3 dir = caster_.Get()->GetPos().CalcDir(owner->GetPos()); - if ((std::isfinite(dir.x) && - std::isfinite(dir.y))) { - dir = dir * 1.0f; - GlmHelper::Normalize(dir); - owner->SetMoveDir(dir); - owner->SetAttackDir(dir); - if (skill_meta) { - switch (skill_meta->GetMagicId()) { - case MAGIC_YMCZ: - { - owner->ForwardMove(SkillHelper::GetYmczReserveDistance(skill_meta)); - } - break; - default: - { - } - break; - } - } else { - if (meta->_param1 > 0.001) { - owner->ForwardMove(meta->_param1); - } - } - } - } } void Buff::ProcMachineGun() { - hold_curr_weapon_idx_ = caster_.Get()->GetCurrWeapon()->weapon_idx; - { - std::vector strings; - a8::Split(meta->buff_param1(), strings, ':'); - for (size_t i = 0; i < strings.size(); ++i) { - int weapon_id = a8::XValue(strings[i]); - const mt::Equip* weapon_meta = mt::Equip::GetById(weapon_id); - if (weapon_meta && i < caster_.Get()->weapons.size()) { - int weapon_idx = weapon_meta->GetWeaponIdx(); - if (weapon_idx >= 0 && weapon_idx < caster_.Get()->weapons.size()) { - Weapon* weapon = &caster_.Get()->weapons[weapon_idx]; - hold_weapons_.push_back(*weapon); - - weapon->weapon_id = weapon_meta->id(); - weapon->meta = weapon_meta; - weapon->skill_meta = skill_meta; - weapon->Recalc(); - weapon->ammo = weapon->GetClipVolume(owner); - if (i == 0) { - caster_.Get()->SetCurrWeapon(weapon); - } - } - } - } - caster_.Get()->MarkSyncActivePlayer(__FILE__, __LINE__, __func__); - caster_.Get()->UpdateCharImage(__FILE__, __LINE__, __func__); - } - if (skill_meta && skill_meta->_number_meta) { - switch (skill_meta->GetMagicId()) { - case MAGIC_HLYZ: - { - owner->room->xtimer.ModifyTime - (remover_timer, - skill_meta->_number_meta->_float_time * 1000/ FRAME_RATE_MS); - } - break; - case MAGIC_HJHX: - { - owner->room->xtimer.ModifyTime - (remover_timer, - skill_meta->_number_meta->_float_time * 1000 / FRAME_RATE_MS); - owner->GetTrigger()->DispatchEvent(kStartSwitchWeaponBuffEvent, {this}); - } - break; - case MAGIC_FG: - { - bool shot_ok = false; - a8::Vec2 target_dir; - float fly_distance = 0; - int trace_target_uniid = 0; - owner->Shot(owner->context_dir, shot_ok, fly_distance, trace_target_uniid); - - owner->room->xtimer.ModifyTime - (remover_timer, - skill_meta->_number_meta->_float_time * 1000 / FRAME_RATE_MS); - event_handlers_.push_back - ( - owner->GetTrigger()->AddListener - ( - kSkillBulletPreCreateEvent, - [this] (const a8::Args& args) - { - int delay_time = args.Get(0); - const mt::Skill* bullet_skill_meta = args.Get(1); - int passed_frames = (owner->room->GetFrameNo() - add_frameno); - int raw_frames = skill_meta->_number_meta->_float_time * 1000 / FRAME_RATE_MS; - if (skill_meta == bullet_skill_meta && - delay_time >= (passed_frames - raw_frames - 2) * FRAME_RATE_MS) { - int remain_time = owner->room->xtimer.GetRemainTime(remover_timer); - owner->room->xtimer.ModifyTime - (remover_timer, delay_time / FRAME_RATE_MS + 2); - } -#ifdef DEBUG - a8::XPrintf("event1 %d %d %d\n", {passed_frames, raw_frames, delay_time}); -#endif - } - ) - ); - event_handlers_.push_back - ( - owner->GetTrigger()->AddListener - ( - kFlyHookCreateEvent, - [this] (const a8::Args& args) - { - Bullet* bullet = args.Get(0); - int passed_frames = (owner->room->GetFrameNo() - add_frameno); - int raw_frames = skill_meta->_number_meta->_float_time * 1000 / FRAME_RATE_MS; - owner->room->xtimer.ModifyTime - (remover_timer, - skill_meta->_number_meta->_float_time * 1000 / FRAME_RATE_MS); -#ifdef DEBUG - a8::XPrintf("event2 %d %d\n", {passed_frames, raw_frames}); -#endif - }) - ); - event_handlers_.push_back - ( - owner->GetTrigger()->AddListener - ( - kFlyHookDestoryEvent, - [this] (const a8::Args& args) - { - int passed_frames = (owner->room->GetFrameNo() - add_frameno); - int raw_frames = skill_meta->_number_meta->_float_time * 1000 / FRAME_RATE_MS; - if (passed_frames >= raw_frames) { - owner->RemoveBuffByUniId(buff_uniid); - } -#ifdef DEBUG - a8::XPrintf("event3 %d %d\n", {passed_frames, raw_frames}); -#endif - } - ) - ); -#ifdef DEBUG - { - std::string dbg_msg = a8::Format - ( - "skill_id:%d 飞钩 距离:%f 钩子持续时间:%f", - { - skill_meta->skill_id(), - skill_meta->_number_meta->_float_range, - skill_meta->_number_meta->_float_time, - }); - owner->SendDebugMsg(dbg_msg); - a8::XPrintf("%s\n", {dbg_msg}); - } -#endif - } - break; - default: - { - } - break; - } - } } void Buff::ProcRemoveMachineGun() { - owner->GetTrigger()->DispatchEvent(kEndSwitchWeaponBuffEvent, {this}); - RecoverHoldWeapons(); } void Buff::ProcReserveMove() @@ -1080,96 +376,14 @@ void Buff::ProcReserveMove() void Buff::ProcHoldShield() { - owner->IncDisableAttackDirTimes(); - owner->shield_max_hp_ = SkillHelper::GetLdfyHp(owner, skill_meta); - owner->shield_hp_ = owner->shield_max_hp_; - owner->room->frame_event.AddPropChg(owner->GetWeakPtrRef(), - kPropShieldHp, - owner->shield_max_hp_, - owner->shield_hp_); - if (skill_meta) { - switch (skill_meta->GetMagicId()) { - case MAGIC_LDFY: - { - owner->room->xtimer.ModifyTime - (remover_timer, - SkillHelper::GetLdfyBuffTime(owner, skill_meta) * 1000 / FRAME_RATE_MS); - if (owner->CurrentSkill() && owner->CurrentSkill()->meta == skill_meta) { - Creature* c = owner; - owner->CurrentSkill()->AddMinorMode - ( - SMT_BLINK, - SkillHelper::GetLdfyBuffTime(owner, skill_meta) * 1000, - [c] - { - c->RemoveBuffByEffectId(kBET_HoldShield); - } - ); - } -#ifdef DEBUG - { - std::string dbg_msg = a8::Format - ( - "skill_id:%d 立盾防御 hp:%f ratio:%f ratio:%f human.max_hp:%f time:%f", - { - skill_meta->skill_id(), - owner->shield_max_hp_, - skill_meta->_number_meta->_float_ratio, - skill_meta->_number_meta->_float_ratio2, - owner->GetMaxHP(), - skill_meta->_number_meta->_float_time, - }); - owner->SendDebugMsg(dbg_msg); - a8::XPrintf("%s\n", {dbg_msg}); - } -#endif - } - break; - default: - { - } - break; - } - } } void Buff::ProcRemoveHoldShield() { - owner->DecDisableAttackDirTimes(); } void Buff::ProcHide() { - if (skill_meta) { - switch (skill_meta->GetMagicId()) { - case MAGIC_YS: - { - owner->room->xtimer.ModifyTime - (remover_timer, - skill_meta->_number_meta->_float_time * 1000 / FRAME_RATE_MS); -#ifdef DEBUG - { - std::string dbg_msg = a8::Format - ( - "skill_id:%d 兔子隐身 time:%f 警告提示距离:%f 暴击率:%f", - { - skill_meta->skill_id(), - skill_meta->_number_meta->_float_time, - skill_meta->_number_meta->_float_range2, - skill_meta->_number_meta->_float_ratio2, - }); - owner->SendDebugMsg(dbg_msg); - a8::XPrintf("%s\n", {dbg_msg}); - } -#endif - } - break; - default: - { - } - break; - } - } } void Buff::ProcRemoveHide() @@ -1201,76 +415,26 @@ void Buff::ClearEventHandlers() void Buff::ProcRescuer() { - Human* target = owner->room->GetHumanByUniId(owner->AsHuman()->GetActionTargetId()); - if (target) { - owner->GetTrigger()->StartRescue(target); - } } void Buff::ProcRemoveRescuer() { - Human* target = owner->room->GetHumanByUniId(owner->AsHuman()->GetActionTargetId()); - if (target) { - owner->GetTrigger()->EndRescue(target); - } } void Buff::ProcImmune() { - for (int tag : meta->_param1_int_list) { - owner->GetAbility()->IncImmuneTimes(tag); - } } void Buff::ProcRemoveImmune() { - for (int tag : meta->_param1_int_list) { - owner->GetAbility()->DecImmuneTimes(tag); - } } void Buff::ProcCallFunc() { - switch (meta->_int_param1) { - case 1: - { - } - break; - case 2: - { - owner->GetAbility()->AddSpeedRuduce(meta->_param2); - } - break; - case 3: - { - ProcIntervalRangeAddBuffFunc(); - } - break; - default: - { - } - break; - } } void Buff::ProcRemoveCallFunc() { - switch (meta->_int_param1) { - case 1: - { - - } - break; - case 2: - { - owner->GetAbility()->DelSpeedRuduce(meta->_param2); - } - break; - default: - { - } - break; - } } void Buff::PreProcess() @@ -1390,7 +554,6 @@ void Buff::ProcIntervalRangeAddBuffFunc() void Buff::ProcOnceChgAttr() { - InternalProcOnceChgAttr(); } void Buff::ProcRemoveOnceChgAttr() @@ -1880,12 +1043,6 @@ void Buff::Deactivate() break; case kBET_Sprint: { - if (meta->_int_param5) { - owner->DecDisableMoveDirTimes(); - } - if (owner->AsHuman()) { - owner->AsHuman()->last_shot_frameno_ = owner->room->GetFrameNo() + SERVER_FRAME_RATE; - } } break; case kBET_HoldShield: diff --git a/server/gameserver/buff.h b/server/gameserver/buff.h index 42effc5c..fd06749d 100644 --- a/server/gameserver/buff.h +++ b/server/gameserver/buff.h @@ -34,6 +34,7 @@ class Buff a8::XTimerWp remover_timer; Buff(); + ~Buff(); void Init(); void UnInit(); int GetLeftTime(); @@ -51,47 +52,7 @@ class Buff virtual void Activate(); virtual void Deactivate(); -private: - void ProcDelayAddBuff(); - void ProcIntervalAddBuff(); - void ProcBatchAddBuff(); - void ProcSummonHero(); - void ProcBeRecycle(); - void ProcBecome(); - void ProcRemoveBecome(); - void ProcDriver(); - void ProcRemoveDriver(); - void ProcPassenger(); - void ProcRemovePassenger(); - void ProcSprint(); - void ProcSeletTargetWithSelfPos(); - void ProcTurnOver(); - void ProcPullToWalkable(); - void ProcAutoShot(); - void ProcBeatBack(); - void ProcDisperse(); - void ProcDive(); - void ProcRemoveDive(); - void ProcInWater(); - void ProcRemoveInWater(); - void ProcReserve(); - void ProcReserveMove(); - void ProcMachineGun(); - void ProcRemoveMachineGun(); - void ProcHoldShield(); - void ProcRemoveHoldShield(); - void ProcHide(); - void ProcRemoveHide(); - void ProcRescuer(); - void ProcRemoveRescuer(); - void ProcImmune(); - void ProcRemoveImmune(); - void ProcCallFunc(); - void ProcRemoveCallFunc(); - void ProcOnceChgAttr(); - void ProcRemoveOnceChgAttr(); - -private: +protected: void ClearEventHandlers(); void InternalTimerAddBuff(); void RecoverHoldWeapons(); @@ -100,7 +61,7 @@ private: void ProcIntervalRangeAddBuffFunc(); void InternalProcOnceChgAttr(); -private: +protected: int hold_curr_weapon_idx_ = 0; std::list hold_weapons_; std::list> event_handlers_; diff --git a/server/gameserver/buff/autoshot.cc b/server/gameserver/buff/autoshot.cc index 3d96ad36..53f81372 100644 --- a/server/gameserver/buff/autoshot.cc +++ b/server/gameserver/buff/autoshot.cc @@ -4,7 +4,27 @@ void AutoShotBuff::Activate() { - + owner->room->xtimer.SetIntervalEx + ( + 1, + [this] (int event, const a8::Args* args) + { + if (a8::TIMER_EXEC_EVENT == event) { + if (owner->IsHuman()) { +#if 0 + >owner->AsHuman()->shot_start = true; +#endif + owner->AsHuman()->shot_hold = true; + owner->AsHuman()->series_shot_frames = 0; + } + } else if (a8::TIMER_DELETE_EVENT == event) { + if (owner->IsHuman()) { + owner->AsHuman()->shot_hold = false; + owner->AsHuman()->series_shot_frames = 0; + } + } + }, + &xtimer_attacher); } void AutoShotBuff::Deactivate() diff --git a/server/gameserver/buff/batch_add.cc b/server/gameserver/buff/batch_add.cc index 2e8c69d2..0e119200 100644 --- a/server/gameserver/buff/batch_add.cc +++ b/server/gameserver/buff/batch_add.cc @@ -1,2 +1,55 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/batch_add.h" +#include "creature.h" + +#include "mt/Buff.h" + +void BatchAddBuff::Activate() +{ + std::shared_ptr old_context_ability = owner->context_ability; + glm::vec3 old_context_dir = owner->context_dir; + Position old_context_pos = owner->context_pos; + owner->context_dir = owner->GetAttackDir(); + owner->context_pos = owner->GetPos(); + + for (auto& tuple : meta->_batch_add_list) { + int rand_space = std::get<0>(tuple); + const auto& items = std::get<1>(tuple); + if (items.empty()) { + A8_ABORT(); + } + int rnd = rand(); + if (rand_space == -1) { + //概率 + rnd = rnd % 10000; + if (rnd < std::get<1>(items[0])){ + const mt::Buff* buff_meta = mt::Buff::GetById(std::get<0>(items[0])); + if (buff_meta) { + owner->AddBuff(caster_.Get(), buff_meta, nullptr); + } + } + } else { + //权重 + rnd = rnd % rand_space; + for (const auto& item : items) { + if (rnd <= std::get<1>(item)) { + const mt::Buff* buff_meta = mt::Buff::GetById(std::get<0>(item)); + if (buff_meta) { + owner->AddBuff(caster_.Get(), buff_meta, nullptr); + } + break; + } + } + } + } + + owner->context_dir = old_context_dir; + owner->context_pos = old_context_pos; + owner->context_ability = old_context_ability; +} + +void BatchAddBuff::Deactivate() +{ + +} diff --git a/server/gameserver/buff/batch_add.h b/server/gameserver/buff/batch_add.h index 15d08f1f..2723b903 100644 --- a/server/gameserver/buff/batch_add.h +++ b/server/gameserver/buff/batch_add.h @@ -4,7 +4,7 @@ class BatchAddBuff : Buff { - pubic: +public: virtual void Activate() override; virtual void Deactivate() override; diff --git a/server/gameserver/buff/beatback.cc b/server/gameserver/buff/beatback.cc index 2e8c69d2..0f076aad 100644 --- a/server/gameserver/buff/beatback.cc +++ b/server/gameserver/buff/beatback.cc @@ -1,2 +1,23 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/beatback.h" + +void BeatBackBuff::Activate() +{ + 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) { + glm::vec3 old_move_dir = owner->GetMoveDir(); + owner->SetMoveDir(caster_.Get()->context_dir); + owner->ForwardMove(meta->_param1); + owner->SetMoveDir(old_move_dir); + } + } + } +} + +void BeatBackBuff::Deactivate() +{ + +} diff --git a/server/gameserver/buff/become.cc b/server/gameserver/buff/become.cc index 2e8c69d2..8aa5b0b6 100644 --- a/server/gameserver/buff/become.cc +++ b/server/gameserver/buff/become.cc @@ -1,2 +1,46 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/become.h" + +void BecomeAdd::Activate() +{ + hold_curr_weapon_idx_ = caster_.Get()->GetCurrWeapon()->weapon_idx; + if (caster_.Get()->IsHuman() && meta->_param2 > 0.01) { + std::vector strings; + a8::Split(meta->buff_param2(), strings, ':'); + for (size_t i = 0; i < strings.size(); ++i) { + int weapon_id = a8::XValue(strings[i]); + const mt::Equip* weapon_meta = mt::Equip::GetById(weapon_id); + if (weapon_meta && i < caster_.Get()->weapons.size()) { + int weapon_idx = weapon_meta->GetWeaponIdx(); + if (weapon_idx >= 0 && weapon_idx < caster_.Get()->weapons.size()) { + Weapon* weapon = &caster_.Get()->weapons[weapon_idx]; + hold_weapons_.push_back(*weapon); + + weapon->weapon_id = weapon_meta->id(); + weapon->meta = weapon_meta; + weapon->skill_meta = skill_meta; + weapon->Recalc(); + weapon->ammo = weapon->GetClipVolume(owner); + if (i == 0) { + caster_.Get()->SetCurrWeapon(weapon); + } + } + } + } + caster_.Get()->MarkSyncActivePlayer(__FILE__, __LINE__, __func__); + caster_.Get()->SyncAroundPlayers(__FILE__, __LINE__, __func__); + } +#ifdef DEBUG1 + caster_.Get()->SendDebugMsg(a8::Format("ProcBecome buff:%d hold_curr_weapon_idx:%d", + { + meta->buff_id(), + hold_curr_weapon_idx_ + })); +#endif +} + +void BecomeAdd::Deactivate() +{ + RecoverHoldWeapons(); +} diff --git a/server/gameserver/buff/berecycle.cc b/server/gameserver/buff/berecycle.cc index 2e8c69d2..7268201e 100644 --- a/server/gameserver/buff/berecycle.cc +++ b/server/gameserver/buff/berecycle.cc @@ -1,2 +1,25 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/berecycle.h" + +void BeRecycleBuff::Activate() +{ + owner->room->xtimer.SetIntervalEx + ( + SERVER_FRAME_RATE * 2, + [this] (int event, const a8::Args* args) + { + if (a8::TIMER_EXEC_EVENT == event) { + if (owner->IsHuman()) { + owner->room->GetIncubator()->RecycleAndroid(owner->AsHuman()); + } + } + }, + &xtimer_attacher + ); +} + +void BeRecycleBuff::Deactivate() +{ + +} diff --git a/server/gameserver/buff/berecycle.h b/server/gameserver/buff/berecycle.h index 065ce3e7..176ca2f6 100644 --- a/server/gameserver/buff/berecycle.h +++ b/server/gameserver/buff/berecycle.h @@ -4,7 +4,7 @@ class BeRecyleBuff : Buff { - pubic: +public virtual void Activate() override; virtual void Deactivate() override; diff --git a/server/gameserver/buff/callfunc.cc b/server/gameserver/buff/callfunc.cc index 2e8c69d2..2a2a30b4 100644 --- a/server/gameserver/buff/callfunc.cc +++ b/server/gameserver/buff/callfunc.cc @@ -1,2 +1,47 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/callfunc.h" + +void CallFuncBuff::Activate() +{ + switch (meta->_int_param1) { + case 1: + { + } + break; + case 2: + { + owner->GetAbility()->AddSpeedRuduce(meta->_param2); + } + break; + case 3: + { + ProcIntervalRangeAddBuffFunc(); + } + break; + default: + { + } + break; + } +} + +void CallFuncBuff::Deactivate() +{ + switch (meta->_int_param1) { + case 1: + { + + } + break; + case 2: + { + owner->GetAbility()->DelSpeedRuduce(meta->_param2); + } + break; + default: + { + } + break; + } +} diff --git a/server/gameserver/buff/delay_add.cc b/server/gameserver/buff/delay_add.cc index 2e8c69d2..e6d619f7 100644 --- a/server/gameserver/buff/delay_add.cc +++ b/server/gameserver/buff/delay_add.cc @@ -1,2 +1,13 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/delay_add.h" + +void DelayAddBuff::Activate() +{ + InternalTimerAddBuff(); +} + +void DelayAddBuff::Deactivate() +{ + +} diff --git a/server/gameserver/buff/delay_add.h b/server/gameserver/buff/delay_add.h index bbac1dad..f712eb40 100644 --- a/server/gameserver/buff/delay_add.h +++ b/server/gameserver/buff/delay_add.h @@ -4,7 +4,7 @@ class DelayAddBuff : Buff { - pubic: + public: virtual void Activate() override; virtual void Deactivate() override; diff --git a/server/gameserver/buff/disperse.cc b/server/gameserver/buff/disperse.cc index 2e8c69d2..59ff2fac 100644 --- a/server/gameserver/buff/disperse.cc +++ b/server/gameserver/buff/disperse.cc @@ -1,2 +1,30 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/disperse.h" + +void DisperseBuff::Activate() +{ + std::vector 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); + } + if (!del_buffs.empty()) { + owner->TryAddBuff(owner, meta->_int_param2); + } +} + +void DisperseBuff::Deactivate() +{ + +} diff --git a/server/gameserver/buff/dive.cc b/server/gameserver/buff/dive.cc index 2e8c69d2..bfda6f63 100644 --- a/server/gameserver/buff/dive.cc +++ b/server/gameserver/buff/dive.cc @@ -1,2 +1,49 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/dive.h" + +void DiveBuff::Activate() +{ + owner->room->xtimer.SetIntervalEx + ( + SERVER_FRAME_RATE, + [this] (int event, const a8::Args* args) + { + if (a8::TIMER_EXEC_EVENT == event) { + if (owner->dead || !owner->IsHuman()) { + owner->RemoveBuffByUniId(buff_uniid); + return; + } + Human* hum = owner->AsHuman(); + if (hum->GetOxygen() > 0) { + hum->DecOxygen(mt::Param::s().dive_oxygen_consume); + hum->room->frame_event.AddPropChg(hum->GetWeakPtrRef(), + kPropDive, + mt::Param::s().dive_oxygen_total, + hum->GetOxygen(), + true); + return; + } + hum->DecHP(mt::Param::s().dive_hp_consume, + VP_Water, + "water", + 0, + 0, + "water"); + } + }, + &xtimer_attacher + ); + if (owner->IsHuman()) { + ++owner->AsHuman()->stats.diving_times; + } +} + +void DiveBuff::Deactivate() +{ + if (owner->IsHuman()) { + #if 0 + owner->AsHuman()->SetOxygen(0); + #endif + } +} diff --git a/server/gameserver/buff/driver.cc b/server/gameserver/buff/driver.cc index 2e8c69d2..871b7a3e 100644 --- a/server/gameserver/buff/driver.cc +++ b/server/gameserver/buff/driver.cc @@ -1,2 +1,30 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/driver.h" + +void DriverAdd::Activate() +{ + hold_curr_weapon_idx_ = caster_.Get()->GetCurrWeapon()->weapon_idx; + if (caster_.Get()->IsHuman()) { + Human* hum = (Human*)caster_.Get(); + if (hum->GetCar() && hum->GetCar()->GetCurrWeapon()) { + hold_weapons_.push_back(hum->weapons[hum->GetCar()->GetCurrWeapon()->weapon_idx]); + hum->weapons[hum->GetCar()->GetCurrWeapon()->weapon_idx] = *hum->GetCar()->GetCurrWeapon(); + hum->SetCurrWeapon(&hum->weapons[hum->GetCar()->GetCurrWeapon()->weapon_idx]); + if (hum->GetCar()->meta && + hum->GetSeat() < hum->GetCar()->meta->_shoot_offsets.size() && + std::get<0>(hum->GetCar()->meta->_shoot_offsets[hum->GetSeat()]) + ) { + hum->shoot_offset = std::get<1>(hum->GetCar()->meta->_shoot_offsets[hum->GetSeat()]); + } + } + } + caster_.Get()->MarkSyncActivePlayer(__FILE__, __LINE__, __func__); + caster_.Get()->SyncAroundPlayers(__FILE__, __LINE__, __func__); +} + +void DriverAdd::Deactivate() +{ + RecoverHoldWeapons(); + caster_.Get()->shoot_offset = GlmHelper::ZERO; +} diff --git a/server/gameserver/buff/hide.cc b/server/gameserver/buff/hide.cc index 2e8c69d2..506c3e7d 100644 --- a/server/gameserver/buff/hide.cc +++ b/server/gameserver/buff/hide.cc @@ -1,2 +1,42 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/hide.h" + +void HideBuff::Activate() +{ + if (skill_meta) { + switch (skill_meta->GetMagicId()) { + case MAGIC_YS: + { + owner->room->xtimer.ModifyTime + (remover_timer, + skill_meta->_number_meta->_float_time * 1000 / FRAME_RATE_MS); +#ifdef DEBUG + { + std::string dbg_msg = a8::Format + ( + "skill_id:%d 兔子隐身 time:%f 警告提示距离:%f 暴击率:%f", + { + skill_meta->skill_id(), + skill_meta->_number_meta->_float_time, + skill_meta->_number_meta->_float_range2, + skill_meta->_number_meta->_float_ratio2, + }); + owner->SendDebugMsg(dbg_msg); + a8::XPrintf("%s\n", {dbg_msg}); + } +#endif + } + break; + default: + { + } + break; + } + } +} + +void HideBuff::Deactivate() +{ + +} diff --git a/server/gameserver/buff/hold_shield.cc b/server/gameserver/buff/hold_shield.cc index 2e8c69d2..d211b60f 100644 --- a/server/gameserver/buff/hold_shield.cc +++ b/server/gameserver/buff/hold_shield.cc @@ -1,2 +1,63 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/hold_shield.h" + +void HoldShieldBuff::Activate() +{ + owner->IncDisableAttackDirTimes(); + owner->shield_max_hp_ = SkillHelper::GetLdfyHp(owner, skill_meta); + owner->shield_hp_ = owner->shield_max_hp_; + owner->room->frame_event.AddPropChg(owner->GetWeakPtrRef(), + kPropShieldHp, + owner->shield_max_hp_, + owner->shield_hp_); + if (skill_meta) { + switch (skill_meta->GetMagicId()) { + case MAGIC_LDFY: + { + owner->room->xtimer.ModifyTime + (remover_timer, + SkillHelper::GetLdfyBuffTime(owner, skill_meta) * 1000 / FRAME_RATE_MS); + if (owner->CurrentSkill() && owner->CurrentSkill()->meta == skill_meta) { + Creature* c = owner; + owner->CurrentSkill()->AddMinorMode + ( + SMT_BLINK, + SkillHelper::GetLdfyBuffTime(owner, skill_meta) * 1000, + [c] + { + c->RemoveBuffByEffectId(kBET_HoldShield); + } + ); + } +#ifdef DEBUG + { + std::string dbg_msg = a8::Format + ( + "skill_id:%d 立盾防御 hp:%f ratio:%f ratio:%f human.max_hp:%f time:%f", + { + skill_meta->skill_id(), + owner->shield_max_hp_, + skill_meta->_number_meta->_float_ratio, + skill_meta->_number_meta->_float_ratio2, + owner->GetMaxHP(), + skill_meta->_number_meta->_float_time, + }); + owner->SendDebugMsg(dbg_msg); + a8::XPrintf("%s\n", {dbg_msg}); + } +#endif + } + break; + default: + { + } + break; + } + } +} + +void HoldShieldBuff::Deactivate() +{ + owner->DecDisableAttackDirTimes(); +} diff --git a/server/gameserver/buff/immune.cc b/server/gameserver/buff/immune.cc index 2e8c69d2..d616fafc 100644 --- a/server/gameserver/buff/immune.cc +++ b/server/gameserver/buff/immune.cc @@ -1,2 +1,17 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/immune.h" + +void ImmuneBuff::Activate() +{ + for (int tag : meta->_param1_int_list) { + owner->GetAbility()->IncImmuneTimes(tag); + } +} + +void ImmuneBuff::Deactivate() +{ + for (int tag : meta->_param1_int_list) { + owner->GetAbility()->DecImmuneTimes(tag); + } +} diff --git a/server/gameserver/buff/in_water.cc b/server/gameserver/buff/in_water.cc index 2e8c69d2..c1b38e64 100644 --- a/server/gameserver/buff/in_water.cc +++ b/server/gameserver/buff/in_water.cc @@ -1,2 +1,69 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/in_water.h" + +void InWaterBuff::Activate() +{ + if (owner->IsHuman()) { + owner->AsHuman()->room->frame_event.AddPropChg + (owner->AsHuman()->GetWeakPtrRef(), + kPropDive, + mt::Param::s().dive_oxygen_total, + owner->AsHuman()->GetOxygen(), + true); + + if (owner->IsPlayer()) { + owner->room->xtimer.SetIntervalEx + ( + SERVER_FRAME_RATE, + [this] (int event, const a8::Args* args) + { + if (a8::TIMER_EXEC_EVENT == event) { + if (owner->dead || !owner->IsHuman()) { + return; + } + Human* hum = owner->AsHuman(); + if (!hum->HasBuffEffect(kBET_Dive) && + hum->GetOxygen() < mt::Param::s().dive_oxygen_total) { + hum->AddOxygen(mt::Param::s().inwater_oxygen_recover); + hum->room->frame_event.AddPropChg + (hum->GetWeakPtrRef(), + kPropDive, + mt::Param::s().dive_oxygen_total, + hum->GetOxygen(), + true); + return; + } + } + }, + &xtimer_attacher + ); + } + } +} + +void InWaterBuff::Deactivate() +{ + if (owner->IsHuman()) { + if (owner->IsPlayer()) { + Human* hum = owner->AsHuman(); + owner->room->xtimer.SetIntervalEx + ( + SERVER_FRAME_RATE, + [hum] (int event, const a8::Args* args) + { + if (hum->HasBuffEffect(kBET_InWater) || hum->dead) { + hum->room->xtimer.DeleteCurrentTimer(); + return; + } + if (hum->GetOxygen() >= mt::Param::s().dive_oxygen_total) { + hum->room->xtimer.DeleteCurrentTimer(); + return; + } + hum->AddOxygen(mt::Param::s().inwater_oxygen_recover); + }, + &hum->xtimer_attacher + ); + } + } +} diff --git a/server/gameserver/buff/internal_add.cc b/server/gameserver/buff/internal_add.cc index 2e8c69d2..bedea3d7 100644 --- a/server/gameserver/buff/internal_add.cc +++ b/server/gameserver/buff/internal_add.cc @@ -1,2 +1,13 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/internal_add.h" + +void InternalAddBuff::Activate() +{ + InternalTimerAddBuff(); +} + +void InternalAddBuff::Deactivate() +{ + +} diff --git a/server/gameserver/buff/internal_add.h b/server/gameserver/buff/internal_add.h index 0131692b..8c72479e 100644 --- a/server/gameserver/buff/internal_add.h +++ b/server/gameserver/buff/internal_add.h @@ -4,7 +4,7 @@ class InternalAddBuff : Buff { - pubic: + public: virtual void Activate() override; virtual void Deactivate() override; diff --git a/server/gameserver/buff/machine_gun.cc b/server/gameserver/buff/machine_gun.cc index 2e8c69d2..224f8aab 100644 --- a/server/gameserver/buff/machine_gun.cc +++ b/server/gameserver/buff/machine_gun.cc @@ -1,2 +1,149 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/machine_gun.h" + +void MachineGunBuff::Activate() +{ + hold_curr_weapon_idx_ = caster_.Get()->GetCurrWeapon()->weapon_idx; + { + std::vector strings; + a8::Split(meta->buff_param1(), strings, ':'); + for (size_t i = 0; i < strings.size(); ++i) { + int weapon_id = a8::XValue(strings[i]); + const mt::Equip* weapon_meta = mt::Equip::GetById(weapon_id); + if (weapon_meta && i < caster_.Get()->weapons.size()) { + int weapon_idx = weapon_meta->GetWeaponIdx(); + if (weapon_idx >= 0 && weapon_idx < caster_.Get()->weapons.size()) { + Weapon* weapon = &caster_.Get()->weapons[weapon_idx]; + hold_weapons_.push_back(*weapon); + + weapon->weapon_id = weapon_meta->id(); + weapon->meta = weapon_meta; + weapon->skill_meta = skill_meta; + weapon->Recalc(); + weapon->ammo = weapon->GetClipVolume(owner); + if (i == 0) { + caster_.Get()->SetCurrWeapon(weapon); + } + } + } + } + caster_.Get()->MarkSyncActivePlayer(__FILE__, __LINE__, __func__); + caster_.Get()->UpdateCharImage(__FILE__, __LINE__, __func__); + } + if (skill_meta && skill_meta->_number_meta) { + switch (skill_meta->GetMagicId()) { + case MAGIC_HLYZ: + { + owner->room->xtimer.ModifyTime + (remover_timer, + skill_meta->_number_meta->_float_time * 1000/ FRAME_RATE_MS); + } + break; + case MAGIC_HJHX: + { + owner->room->xtimer.ModifyTime + (remover_timer, + skill_meta->_number_meta->_float_time * 1000 / FRAME_RATE_MS); + owner->GetTrigger()->DispatchEvent(kStartSwitchWeaponBuffEvent, {this}); + } + break; + case MAGIC_FG: + { + bool shot_ok = false; + a8::Vec2 target_dir; + float fly_distance = 0; + int trace_target_uniid = 0; + owner->Shot(owner->context_dir, shot_ok, fly_distance, trace_target_uniid); + + owner->room->xtimer.ModifyTime + (remover_timer, + skill_meta->_number_meta->_float_time * 1000 / FRAME_RATE_MS); + event_handlers_.push_back + ( + owner->GetTrigger()->AddListener + ( + kSkillBulletPreCreateEvent, + [this] (const a8::Args& args) + { + int delay_time = args.Get(0); + const mt::Skill* bullet_skill_meta = args.Get(1); + int passed_frames = (owner->room->GetFrameNo() - add_frameno); + int raw_frames = skill_meta->_number_meta->_float_time * 1000 / FRAME_RATE_MS; + if (skill_meta == bullet_skill_meta && + delay_time >= (passed_frames - raw_frames - 2) * FRAME_RATE_MS) { + int remain_time = owner->room->xtimer.GetRemainTime(remover_timer); + owner->room->xtimer.ModifyTime + (remover_timer, delay_time / FRAME_RATE_MS + 2); + } +#ifdef DEBUG + a8::XPrintf("event1 %d %d %d\n", {passed_frames, raw_frames, delay_time}); +#endif + } + ) + ); + event_handlers_.push_back + ( + owner->GetTrigger()->AddListener + ( + kFlyHookCreateEvent, + [this] (const a8::Args& args) + { + Bullet* bullet = args.Get(0); + int passed_frames = (owner->room->GetFrameNo() - add_frameno); + int raw_frames = skill_meta->_number_meta->_float_time * 1000 / FRAME_RATE_MS; + owner->room->xtimer.ModifyTime + (remover_timer, + skill_meta->_number_meta->_float_time * 1000 / FRAME_RATE_MS); +#ifdef DEBUG + a8::XPrintf("event2 %d %d\n", {passed_frames, raw_frames}); +#endif + }) + ); + event_handlers_.push_back + ( + owner->GetTrigger()->AddListener + ( + kFlyHookDestoryEvent, + [this] (const a8::Args& args) + { + int passed_frames = (owner->room->GetFrameNo() - add_frameno); + int raw_frames = skill_meta->_number_meta->_float_time * 1000 / FRAME_RATE_MS; + if (passed_frames >= raw_frames) { + owner->RemoveBuffByUniId(buff_uniid); + } +#ifdef DEBUG + a8::XPrintf("event3 %d %d\n", {passed_frames, raw_frames}); +#endif + } + ) + ); +#ifdef DEBUG + { + std::string dbg_msg = a8::Format + ( + "skill_id:%d 飞钩 距离:%f 钩子持续时间:%f", + { + skill_meta->skill_id(), + skill_meta->_number_meta->_float_range, + skill_meta->_number_meta->_float_time, + }); + owner->SendDebugMsg(dbg_msg); + a8::XPrintf("%s\n", {dbg_msg}); + } +#endif + } + break; + default: + { + } + break; + } + } +} + +void MachineGunBuff::Deactivate() +{ + owner->GetTrigger()->DispatchEvent(kEndSwitchWeaponBuffEvent, {this}); + RecoverHoldWeapons(); +} diff --git a/server/gameserver/buff/once_chg_attr.cc b/server/gameserver/buff/once_chg_attr.cc index 2e8c69d2..85593e4d 100644 --- a/server/gameserver/buff/once_chg_attr.cc +++ b/server/gameserver/buff/once_chg_attr.cc @@ -1,2 +1,13 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/once_chg_attr.h" + +void OnceChgAttrBuff::Activate() +{ + InternalProcOnceChgAttr(); +} + +void OnceChgAttrBuff::Deactivate() +{ + +} diff --git a/server/gameserver/buff/passener.cc b/server/gameserver/buff/passener.cc index 2e8c69d2..d5e3a2d7 100644 --- a/server/gameserver/buff/passener.cc +++ b/server/gameserver/buff/passener.cc @@ -1,2 +1,17 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/passenger.h" + +void PassengerAdd::Activate() +{ + hold_curr_weapon_idx_ = caster_.Get()->GetCurrWeapon()->weapon_idx; + CalcPassengerShotOffset(); + caster_.Get()->MarkSyncActivePlayer(__FILE__, __LINE__, __func__); + caster_.Get()->SyncAroundPlayers(__FILE__, __LINE__, __func__); +} + +void PassenerAdd::Deactivate() +{ + RecoverHoldWeapons(); + caster_.Get()->shoot_offset = GlmHelper::ZERO; +} diff --git a/server/gameserver/buff/pull_to_walkable.cc b/server/gameserver/buff/pull_to_walkable.cc index 2e8c69d2..d404fbc7 100644 --- a/server/gameserver/buff/pull_to_walkable.cc +++ b/server/gameserver/buff/pull_to_walkable.cc @@ -1,2 +1,35 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/pull_to_walkable.h" + +void PullToWalkableBuff::Activate() +{ + if (!owner->CollisonDetection()) { + return; + } + glm::vec3 move_dir = owner->GetMoveDir(); + if (std::abs(move_dir.x) > FLT_EPSILON || + std::abs(move_dir.y) > FLT_EPSILON + ) { + Position old_pos = owner->GetPos(); + for (int i = 1; i < 2000; i += 5) { + // 999 + #if 1 + #else + owner->SetPos(old_pos + move_dir * i); + #endif + if (!owner->CollisonDetection()) { + owner->room->grid_service->MoveCreature(owner); + return; + } + } + owner->FindLocation(); + } else { + owner->FindLocation(); + } +} + +void PullToWalkableBuff::Deactivate() +{ + +} diff --git a/server/gameserver/buff/rescuer.cc b/server/gameserver/buff/rescuer.cc index 2e8c69d2..61332692 100644 --- a/server/gameserver/buff/rescuer.cc +++ b/server/gameserver/buff/rescuer.cc @@ -1,2 +1,19 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/rescuer.h" + +void RescuerBuff::Activate() +{ + Human* target = owner->room->GetHumanByUniId(owner->AsHuman()->GetActionTargetId()); + if (target) { + owner->GetTrigger()->StartRescue(target); + } +} + +void RescuerBuff::Deactivate() +{ + Human* target = owner->room->GetHumanByUniId(owner->AsHuman()->GetActionTargetId()); + if (target) { + owner->GetTrigger()->EndRescue(target); + } +} diff --git a/server/gameserver/buff/reserve.cc b/server/gameserver/buff/reserve.cc index 2e8c69d2..f4161646 100644 --- a/server/gameserver/buff/reserve.cc +++ b/server/gameserver/buff/reserve.cc @@ -1,2 +1,39 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/reserve.h" + +void ReserveBuff::Activate() +{ + if (caster_.Get()) { + glm::vec3 dir = caster_.Get()->GetPos().CalcDir(owner->GetPos()); + if ((std::isfinite(dir.x) && + std::isfinite(dir.y))) { + dir = dir * 1.0f; + GlmHelper::Normalize(dir); + owner->SetMoveDir(dir); + owner->SetAttackDir(dir); + if (skill_meta) { + switch (skill_meta->GetMagicId()) { + case MAGIC_YMCZ: + { + owner->ForwardMove(SkillHelper::GetYmczReserveDistance(skill_meta)); + } + break; + default: + { + } + break; + } + } else { + if (meta->_param1 > 0.001) { + owner->ForwardMove(meta->_param1); + } + } + } + } +} + +void ReserveBuff::Deactivate() +{ + +} diff --git a/server/gameserver/buff/reserve_move.cc b/server/gameserver/buff/reserve_move.cc index 2e8c69d2..afe09602 100644 --- a/server/gameserver/buff/reserve_move.cc +++ b/server/gameserver/buff/reserve_move.cc @@ -1,2 +1,13 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/reserve_move.h" + +void ReserveMoveBuff::Activate() +{ + +} + +void ReserveMoveBuff::Deactivate() +{ + +} diff --git a/server/gameserver/buff/select_target_with_self_pos.cc b/server/gameserver/buff/select_target_with_self_pos.cc index 2e8c69d2..7b2339db 100644 --- a/server/gameserver/buff/select_target_with_self_pos.cc +++ b/server/gameserver/buff/select_target_with_self_pos.cc @@ -1,2 +1,72 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/select_target_with_self_pos.h" + +void SelectTargetWithSelfPosBuff::Activate() +{ + std::vector targets; + owner->TraverseCreatures + ( + [this, &targets] (Creature* c, bool& stop) + { + if (owner->GetPos().Distance2D2(c->GetPos()) < meta->_int_param3) { + switch (meta->_int_param1) { + case kBST_All: + { + targets.push_back(c); + } + break; + case kBST_Self: + { + if (c == owner) { + targets.push_back(c); + } + } + break; + case kBST_FriendlyIncludeSelf: + { + if (c->team_id == owner->team_id) { + targets.push_back(c); + } + } + break; + case kBST_FriendlyExcludeSelf: + { + if (c->team_id == owner->team_id && c != owner) { + targets.push_back(c); + } + } + break; + case kBST_Enemy: + { + if (c->team_id != owner->team_id) { + targets.push_back(c); + } + } + break; + case kBST_EnemyAndSelf: + { + if (c->team_id != owner->team_id || c == owner) { + targets.push_back(c); + } + } + break; + default: + { + } + break; + } + } + } + ); + for (auto& target : targets) { + for (int buff_id : meta->_param2_int_list) { + target->TryAddBuff(caster_.Get(), buff_id); + } + } +} + +void SelectTargetWithSelfPosBuff::Deactivate() +{ + +} diff --git a/server/gameserver/buff/sprint.cc b/server/gameserver/buff/sprint.cc index 2e8c69d2..5a80f2be 100644 --- a/server/gameserver/buff/sprint.cc +++ b/server/gameserver/buff/sprint.cc @@ -1,2 +1,150 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/sprint.h" + +void SprintAdd::Activate() +{ + if (caster_.Get()->IsPlayer()) { + if (meta->_int_param5) { + owner->IncDisableMoveDirTimes(); + } + { + int old_times = owner->GetDisableMoveDirTimes(); + owner->SetDisableMoveDirTimes(0); + owner->SetMoveDir(owner->context_dir); + owner->SetAttackDir(owner->context_dir); + owner->SetDisableMoveDirTimes(old_times); +#ifdef DEBUG + { + owner->SendDebugMsg(a8::Format("xxxxxxxx move_dir:%d,%d attack_dir:%d,%d speed:%d", + { + owner->GetMoveDir().x, + owner->GetMoveDir().y, + owner->GetAttackDir().x, + owner->GetAttackDir().y, + owner->GetSpeed() + })); + owner->room->xtimer.SetIntervalEx + ( + 2, + [this] (int event, const a8::Args* args) + { + if (a8::TIMER_EXEC_EVENT == event) { + Human* hum = owner->AsHuman(); + hum->SendDebugMsg(a8::Format("xxxxxxxx move_dir:%d,%d attack_dir:%d,%d speed:%d", + { + hum->GetMoveDir().x, + hum->GetMoveDir().y, + hum->GetAttackDir().x, + hum->GetAttackDir().y, + hum->GetSpeed() + })); + } + }, + &xtimer_attacher + ); + } +#endif + } + Player* hum = (Player*)caster_.Get(); + std::map hited_objects = std::map(); + Position pre_pos; + pre_pos = owner->GetPos(); + owner->room->xtimer.SetIntervalEx + ( + 1, + [this, hited_objects, pre_pos] + (int event, const a8::Args* args) mutable + { + Buff* buff = this; + if (!buff->meta->_param3_int_list.empty() || buff->skill_meta) { + std::set enemys; + Position old_pos = buff->owner->GetPos(); + + if (pre_pos.ManhattanDistance2D(buff->owner->GetPos()) > 2) { + a8::Vec2 dir = buff->owner->GetPos().CalcDir2D(pre_pos); + dir.Normalize(); + float distance = buff->owner->GetPos().Distance2D2(pre_pos); + for (int i = 0; i < (distance + 6); i += 5) { + // 999 + #if 1 + #else + buff->owner->MutablePos.FromVec2((pre_pos) + (dir * i)); + #endif + buff->owner->GetHitEnemys(enemys, buff->meta->_param4); + for (auto& enemy : enemys) { + if (enemy->IsEntityType(ET_Car)) { + continue; + } + auto itr = hited_objects.find(enemy->GetUniId()); + if (itr != hited_objects.end()) { + if ((buff->owner->room->GetFrameNo() - itr->second) * FRAME_RATE_MS < + buff->meta->_int_param5) { + continue; + } + } + hited_objects[enemy->GetUniId()] = buff->owner->room->GetFrameNo(); + for (int buff_id : buff->meta->_param3_int_list) { + enemy->TryAddBuff(buff->owner, buff_id); + } + if (buff->skill_meta) { + switch (buff->skill_meta->GetMagicId()) { + case MAGIC_YMCZ: + { + float dmg = SkillHelper::GetYmczDmg(buff->owner, + enemy, + buff->skill_meta); + if (dmg > 0.0001f) { + enemy->DecHP( + dmg, + buff->owner->GetUniId(), + buff->owner->GetName(), + 0, + buff->owner->GetUniId(), + buff->owner->GetName() + ); + } + } + break; + default: + { + } + break; + } + } + } + } + } + + buff->owner->SetPos(old_pos); + pre_pos = buff->owner->GetPos(); + } + }, + &xtimer_attacher); + } + if (skill_meta) { + switch (skill_meta->GetMagicId()) { + case MAGIC_YMCZ: + { + owner->room->xtimer.ModifyTime + (remover_timer, + SkillHelper::GetYmczBuffTime(skill_meta) / FRAME_RATE_MS); + } + break; + default: + { + } + break; + } + } +} + +void SprintAdd::Deactivate() +{ + if (meta->_int_param5) { + owner->DecDisableMoveDirTimes(); + } + if (owner->AsHuman()) { + owner->AsHuman()->last_shot_frameno_ = owner->room->GetFrameNo() + SERVER_FRAME_RATE; + } +} diff --git a/server/gameserver/buff/summon_hero.cc b/server/gameserver/buff/summon_hero.cc index 2e8c69d2..5e589c10 100644 --- a/server/gameserver/buff/summon_hero.cc +++ b/server/gameserver/buff/summon_hero.cc @@ -1,2 +1,15 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/summon_hero.h" + +void SummonHeroBuff::Activate() +{ + if (!owner->dead || meta->dead_valid() != 0) { + owner->SummonHero(this, owner->GetPos(), owner->GetMoveDir()); + } +} + +void SummonHeroBuff::Deactivate() +{ + +} diff --git a/server/gameserver/buff/summon_hero.h b/server/gameserver/buff/summon_hero.h index b3f38722..f480a207 100644 --- a/server/gameserver/buff/summon_hero.h +++ b/server/gameserver/buff/summon_hero.h @@ -4,7 +4,7 @@ class SummonHeroBuff : Buff { - pubic: +public: virtual void Activate() override; virtual void Deactivate() override; diff --git a/server/gameserver/buff/turnover.cc b/server/gameserver/buff/turnover.cc index 2e8c69d2..ffe5934c 100644 --- a/server/gameserver/buff/turnover.cc +++ b/server/gameserver/buff/turnover.cc @@ -1,2 +1,114 @@ #include "precompile.h" -#include "buff.h" + +#include "buff/turnover.h" + +void TurnOverBuff::Activate() +{ + Skill* skill = owner->CurrentSkill(); + if (!skill) { + return; + } + const mt::SkillPhase* phase = owner->GetCurrSkillPhase(); + if (!phase) { + return; + } + #if 0 + if (phase->time_offset < skill->GetPassedTime()) { + return; + } + #endif + glm::vec3 old_dir = owner->GetMoveDir(); + Position old_pos = owner->GetPos(); + float distance = + owner->HasBuffEffect(kBET_Car) ? phase->param1.GetDouble() * 1.5 : phase->param1.GetDouble(); +#ifdef DEBUG + caster_.Get()->SendDebugMsg(a8::Format("ProcBecome currTimes:%d last_pos:%d,%d curr_pos:%d,%d", + { + skill->GetCurrTimes(), + owner->last_turn_over_pos.x, + owner->last_turn_over_pos.y, + owner->GetPos().x, + owner->GetPos().y + })); +#endif + Global::Instance()->verify_set_pos = 1; + owner->ForwardMove(distance); + Global::Instance()->verify_set_pos = 0; + owner->SetMoveDir(old_dir); + if (phase->param2.GetInt() == 1) { + ++owner->turn_over_times; + owner->last_turn_over_pos = old_pos; + } + float moved_distance = owner->GetPos().Distance2D2(old_pos); + moved_distance = std::min(moved_distance, 200.0f); + if (!meta->_param1_int_list.empty() && moved_distance > 2.0f) { + std::set target_list; + owner->TraverseCreatures + ( + [this, &target_list] (Creature* c, bool& stop) + { + if (owner->IsProperTarget(c) && owner->GetPos().Distance2D2(c->GetPos()) < 300) { + target_list.insert(c); + } + }); + + Position curr_pos = owner->GetPos(); + glm::vec3 dir = old_pos.CalcDir(owner->GetPos()); + GlmHelper::Normalize(dir); + for (int i = 5; i < moved_distance; i += 5) { + owner->GetMutablePos().FromGlmVec3(old_pos.ToGlmVec3() + dir * (float)i); + std::list 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.SetTimeoutEx + ( + meta->_int_param4 / FRAME_RATE_MS * (i / moved_distance), + [this, target] (int event, const a8::Args* args) mutable + { + Creature* c = target; + const mt::Buff* buff_meta = meta; + Entity* caster = c->room->GetEntityByUniId(owner->GetUniId()); + if (caster && caster->IsCreature(c->room)) { + for (int buff_id : buff_meta->_param1_int_list) { + c->TryAddBuff((Creature*)caster, buff_id); + } + } + }, + &target->xtimer_attacher); + } + } + owner->SetPos(curr_pos); + } + if (!meta->_param2_int_list.empty()) { + owner->room->xtimer.SetTimeoutEx + ( + meta->_int_param4 / FRAME_RATE_MS, + [this] (int event, const a8::Args* args) mutable + { + Creature* c = owner; + const mt::Buff* buff_meta = meta; + c->TraverseCreatures + ( + [c, buff_meta] (Creature* target, bool& stop) + { + if (c->GetPos().Distance2D2(target->GetPos()) < buff_meta->_int_param3) { + for (int buff_id : buff_meta->_param2_int_list) { + target->TryAddBuffWithTarget(c, buff_id); + } + } + }); + }, + &owner->xtimer_attacher + ); + } +} + +void TurnOverBuff::Deactivate() +{ + +}