#include "stdafx.h" #include "SkillManager.h" #include // #include "SkillFactory.h" #include "Skill.h" //================================================================================================== SkillManager::SkillManager(Character* owner) { owner_ = owner; } SkillManager::~SkillManager() { Release(); } void SkillManager::Init() { active_skills_.resize(0); #ifdef _NA_007667_20141001_WITCHBLADE_SKILL autocast_skills_.clear(); #endif //_NA_007667_20141001_WITCHBLADE_SKILL } void SkillManager::Release() { // (WAVERIX) (080603) (CHANGES) - decrease instance count SkillFactory* const factory = SkillFactory::Instance(); FOREACH_CONTAINER(const SKILL_LIST::value_type& node, active_skills_, SKILL_LIST) { Skill* skill = node.skill_; skill->Release(); factory->FreeSkill(skill); } active_skills_.resize(0); #ifdef _NA_007667_20141001_WITCHBLADE_SKILL autocast_skills_.clear(); #endif //_NA_007667_20141001_WITCHBLADE_SKILL } void SkillManager::ReleaseDead() { // (SOURCE)(NOTE) // - Owner°¡ »ç¸ÁÇßÀ» ½Ã Áï½Ã Release() ½ÃÄѹö¸®¸é Update() ÁßÀÌ´ø ½ºÅ³¿¡ ¹®Á¦°¡ ¹ß»ýÇÒ ¼ö ÀÖ´Ù. // µû¶ó¼­ STLÀ» »ç¿ëÇÏ´Â ¸ðµç ÀÚ·áÇüÀº Áï½Ã »èÁ¦¸¦ ±ÝÇÑ´Ù. // // (WAVERIX) (080603) (NOTE) - ¹æ¾È Áß¿¡ ÇÑ °¡ÁöÀÏ »ÓÀÌ´Ù. // - ¾ÈµÉ °ÍÀº ¾ø°í, ¹ß¸íÇÏ´Â °Íµµ ¾Æ´Ï´Ù. ¹ß°ßÇÏ´Â °Í »ÓÀÌ´Ù. // - Ãʱ⠼³°è½Ã ¸ðµâÈ­ ¹× °´Ã¼¶ó´Â °Í¿¡ Á»´õ °í¹ÎÇÏ°í ¼³°è ¹× ÇÁ·ÎÅäŸÀÔ ¸ðµ¨À» ÀÛ¼ºÇÏ´Â °ÍÀÌ Ã¹Â°... // - ÀÌ¹Ì ÀÛ¼ºµÈ °Í¿¡ ´ëÇÑ º¸¿ÏÃ¥Àº Çö ½ÃÁ¡°ú °°Àº ¹æ¾ÈÀ¸·Î ¿ìȸÇÏ´Â °Í ¿ª½Ã ¹æ¾È Áß Çϳª... // - »óÅ º¯°æ ¹æ¹ýÀº ÀüÅëÀûÀÎ ¾Ë°í¸®Áò¿¡¼­ ¾ð±ÞÇÏ´Â Coloring ¹æ¹ý Áß¿¡ ÇϳªÀÌ´Ù. ´Ü ¾Æ·¡¿Í °°ÀÌ // ƯÁ¤ »óÅ¿¡ ´ëÇÑ ¸¶Å· ¹æ¹ýÀÌ ¿ÜºÎÀÇ Áö¿øÀ» ¹Þ¾Æ¾ß ÇÑ´Ù´Â Á¡Àº ±×´ÙÁö ±ÇÀåµÇ´Â ÇüŶó°í º¸±â´Â Èûµé´Ù. // À¯»ç ·ÎÁ÷ÀÌ »ý°Ü³ª°Å³ª ±âŸ µîµî¿¡¼­ ÁÖ±âÀûÀ¸·Î ¹Ì½º ¹ß»ý È®·üÀÌ »ý±â±â ¶§¹®ÀÌ´Ù. // - ÇÏÁö¸¸ ³ªµµ ÀÌÁ¦ ÀÌ·± ¹æ½ÄÀ¸·Î ÀüȯÇÑ °ü°è·Î Åõ´ú°Å¸± ¿©Áö ¾ø´Ù. ¹ß»ýÇÏ¸é ¼öÁ¤ÇÏ¸é µÇÁö ¹¹... // // (WAVERIX) (080603) (THINKING) // - È®½ÇÈ÷ ±¸ÇöÇÏ´Â ¹æ¹ýÀûÀÎ ¸é¿¡¼­ ºÃÀ» ¶§, ±âº» ¸¶ÀεåÀÇ Â÷ÀÌÁ¡À» ´À³¤´Ù. // ³ªÀÇ °æ¿ì ±âÁ¸ ÀÎÅÍÆäÀ̽ºÀÇ º¯È­´Â ÃÖ¼ÒÈ­ ÇÏ°í ¸ðµâ ³»ºÎ¿¡¼­ ÇØ°áÇÒ ¼ö ÀÖ´Â ÂÊ, // ¶Ç´Â Àü/ÈÄ ´Ü°è¿¡¼­ÀÇ Wrapper Layer¸¦ µÎ´Â ÂÊ(ÀÌ °æ¿ì´Â ¼öÁ¤ ºÒ°¡ ¶óÀ̺귯¸®¿¡ ´ëÇÑ Ãß»óÈ­ÃþÀÌ ´ëÇ¥Àû)À» ¿ì¼±½ÃÇÏÁö¸¸, // Áö±Ý±îÁö ºÁ¿Â ´ëºÎºÐÀÇ °æ¿ì Àü¹æÀ§ ¼öÁ¤À» °¡ÇÏ´Â ÇüŸ¦ ÃëÇÑ´Ù. ¾Æ¸¶µµ ´ëºÎºÐÀÇ ¶óÀ̺귯¸®¿¡ Á¢±ÙÀÌ // °¡´ÉÇÏ´Ù´Â Á¡¿¡¼­ ¸ðµâÈ­°¡ ¸¹ÀÌ ¹«³ÊÁö´Â ¹æ½ÄÀ¸·Î ÀÛ¾÷µÇÁö ¾Ê³ª ÃßÃøµÈ´Ù. // - Example) SyncIterator <-> SetSkillRemove // // - ³ª¸§´ë·Î Àå´ÜÁ¡ÀÌ¾ß ÀÖ°ÚÁö¸¸, ¿ì¸® ÂÊÀº ÈÄÀÚÂÊÀÌ ´ë¼¼À̹ǷΠ¿©±â¿¡ µû¸£±â·Î ÇÏÀÚ. // Code Complete¿¡¼­µµ ¾ð±ÞÇÒ Á¤µµ·Î ÀϹÝÈ­µÈ Á¢±Ù ¹æ¹ý·ÐÀÌ´õ¶óµµ ¿ì¸®ÆÀ¿¡´Â ¸ÂÁö ¾Ê´Â ¹æ½ÄÀÏ ¼ö ÀÖ´Ù. // È®½ÇÈ÷ À¯Áöº¸¼ö Ãø¸éÀº ³Ñ¾î°¡´õ¶óµµ ÈÄÀÚ°¡ ´õ °³¹ßÇÏ±â ÆíÇÏ°í ´õ º¸±â ÆíÇÒ °¡´É¼ºµµ ³ô´Ù. // ¶ÇÇÑ ÀÚÀßÇÑ ÁõºÐ °³¹ß ¹æ½Äº¸´Ù È­²öÇÑ ¸®ÆÑÅ丵ÀÌ ´õ ³ªÀ» ¼öµµ ÀÖ´Ù. // (¿¹¿Ü: ³ªÁß¿¡ ±Ô¸ð°¡ Ä¿Áö¸é °ñÄ¡... ½ºÆÄ°ÔƼ¸é °ñÄ¡...) // ¹«¾ùº¸´Ù °³¹ßÀÚµµ ¸î¸í µÇÁö ¾Ê°í ÇÁ·Î±×·¥ ±Ô¸ðµµ Áß°£ Á¤µµÀ̹ǷΠ¾Õ¼± ¹æ½ÄÀÌ ÈξÀ ³ªÀ» °Å¶ó º¸ÀδÙ. FOREACH_CONTAINER(const SKILL_LIST::value_type& node, active_skills_, SKILL_LIST) { Skill* skill = node.skill_; skill->SetSkillRemove(true); } } void SkillManager::Update() { #ifdef _NA_007667_20141001_WITCHBLADE_SKILL _ExecuteAutoCastSkill(); #endif //_NA_007667_20141001_WITCHBLADE_SKILL if (active_skills_.empty()) { return; } // DWORD cur_tick = GetTickCount(); SkillFactory* const factory = SkillFactory::Instance(); // SKILL_LIST::iterator it = active_skills_.begin(); const SKILL_LIST::const_iterator end = active_skills_.end(); while (it != end) { Skill* skill = it->skill_; bool need_delete = false; if (skill->IsSkillCancel()) { skill->CancelExcute(); need_delete = true; } else if (cur_tick >= skill->GetExecuteTick() || skill->IsSkillRemove()) { skill->EndExecute(); if (owner_->IsEqualObjectKind(PLAYER_OBJECT) && skill->GetSkillClassCode() != eSKILL_HIDE) { Player* owner_player = static_cast(owner_) ; owner_player->Player_TransOff(); } need_delete = true; } // if (need_delete) { //skill->Release(); factory->FreeSkill(skill); it = active_skills_.erase(it); continue; }; // last point ++it; } } void SkillManager::AddActiveSkill(Skill* skill) { // depth 1 interface, you should be call on front level logic if (skill == NULL) { return; } // const SLOTCODE skill_code = skill->GetSkillCode(); ;{ SKILL_LIST::iterator found = FindActiveSkill(skill_code); if (found != active_skills_.end()) { RemoveActiveSkill(found); // need reconsideration } }; skill->StartExecute(); SkillNode node = { 0, }; node.code_ = skill_code; node.skill_ = skill; active_skills_.push_back(node); } SkillManager::SKILL_LIST::iterator SkillManager::RemoveActiveSkill(SKILL_LIST::iterator del_iterator) { assert(del_iterator != active_skills_.end()); Skill* skill = del_iterator->skill_; skill->Release(); SkillFactory::Instance()->FreeSkill(skill); return active_skills_.erase(del_iterator); } void SkillManager::CancelActiveSkill(SLOTCODE skill_code) const { SKILL_LIST::const_iterator found = FindActiveSkill(skill_code); if (found == active_skills_.end()) { return; } Skill* skill = found->skill_; skill->SetSkillCancel(true); } void SkillManager::CancelAllSkill() const { FOREACH_CONTAINER(const SKILL_LIST::value_type& node, active_skills_, SKILL_LIST) { Skill* skill = node.skill_; skill->SetSkillCancel(true); } } bool SkillManager::RegisterSkill(eSKILL_TYPE skill_type, const SkillInfo* skill_info) { if (skill_type == SKILL_TYPE_PASSIVE) { return false; } // resolved, (WAVERIX) (090709) (THINKING NOTE) Áß°£¿¡ ½ºÅ³À» ¹Ù²ÙÁö´Â ¾Ê´Â´Ù. ¾Æ´Ô ¹Ù²î±æ ¹Ù¶ó´Â °Ç°¡? // »ó¼öÈ­ µÇ´Â °è¿­¿¡ ´ëÇØ ¾ÕÀ¸·Î Á»´õ È®Á¤ ·ÎÁ÷À¸·Î ÀüȯÇϸ鼭 ´ëüÇϵµ·Ï ÇÏÀÚ. if (skill_info->root_skill_info_ == NULL) { SUNLOG(eCRITICAL_LOG, _T("|[%s]|ÐÅÏ¢=null reference about a root_skill_info|SkillType=%u, SkillCode=%u|"), __FUNCTION__, skill_type, skill_info->skill_code_); return false; } SkillFactory* factory = SkillFactory::Instance(); Skill* new_skill = factory->AllocSkill(skill_type, skill_info->root_skill_info_, skill_info->skill_delay_); new_skill->Init(owner_, skill_info, skill_info->root_skill_info_); // register a new skill in an owner skill container. AddActiveSkill(new_skill); return true; } #ifdef _NA_007667_20141001_WITCHBLADE_SKILL bool SkillManager::SetAutoCastSkill( SLOTCODE skill_code, bool is_connected, Character* target /*= NULL*/ ) { if (autocast_skills_.find(skill_code) != autocast_skills_.end() ) { // ¿ÀÅäij½ºÆ® ½ºÅ³Àº ½ºÅ³´ç 1°³¾¿¸¸ ¿¹¾àÇϱâ·Î // ¶óÀÌ¡Æ÷½º °°Àº °æ¿ì¿¡ ÁßøÀ¸·Î ¸¹À̰ɸ®´Â °æ¿ì°¡ ÀÖ´Ù return false; } AutoSkillNode node; node.skill_code = skill_code; node.is_connected_skill = is_connected; if (target == NULL) { node.target = owner_; } else { node.target = target; } autocast_skills_[skill_code] = node; return true; } void SkillManager::_ExecuteAutoCastSkill() { if (autocast_skills_.empty()) { return; } if(owner_ == NULL) { SUNLOG(eCRITICAL_LOG, "["__FUNCTION__"] SkillManager's Owner is Empty!!"); return; } if (owner_->IsDead() == TRUE || owner_->IsDeleted() == true) { _ClearAutoCastSkills(); return; } STLX_MAP::iterator node = autocast_skills_.begin(); SkillScriptInfo* skill_info = SkillInfoParser::Instance()->GetSkillInfo(node->first); // Ÿ°Ù °Ë»ç Character* skill_target = node->second.target; if (obj_util::IsValid(skill_target) == false) { autocast_skills_.erase(node); return; } if (skill_target->IsDead() == TRUE) { autocast_skills_.erase(node); return; } SkillOption skill_option; skill_option.Clear(); skill_option.AddOption(skill_option.eOption_HoldupBuffPostDead); const WzVector* cur_pos = owner_->GetPosPtr(); SkillInfo skill_info_data(owner_, node->first, 0); skill_info_data.SetArgsObjectInfo(node->second.target->GetObjectKey(), cur_pos, cur_pos, skill_target->GetPosPtr()); skill_info_data.SetArgsSkillExt(skill_info_data.kDefaultSequence, skill_info_data.kDefaultSkillEffect, skill_info_data.kDefaultSkillDelay, SKILL_FACTOR_NOMAL, static_cast(ATTACK_PROPENSITY_NORMAL), 0); skill_info_data.skill_option_.ApplyOption(skill_option); //¿¬°á½ºÅ³°ú ±×·¸Áö ¾ÊÀº ½ºÅ³ÀÌ »ç¿ëÇÏ´Â ÇÔ¼ö¸¦ ±¸ºÐÇÑ´Ù if (node->second.is_connected_skill == false && owner_->IsEqualObjectKind(PLAYER_OBJECT) == true) { Player* player = reinterpret_cast(owner_); player->UseSkill(&skill_info_data,ATTACK_PROPENSITY_NORMAL); } else { RegisterSkill(SKILL_TYPE_ACTIVE, &skill_info_data); } autocast_skills_.erase(node); return; } void SkillManager::_ClearAutoCastSkills() { autocast_skills_.clear(); } #endif //_NA_007667_20141001_WITCHBLADE_SKILL