#include "stdafx.h" #include "stdafx.h" #include "Arena\\ArenaSystem.h" #include "SUIArenaGAmeWnd.h" #include "ArenaBingoBoard.h" #include "BattleArenaBase.h" #include "SGameSystem.h" //#include "SUIWnd.h" extern SGameSystem* g_pCurrentGameSystem; float sBingoManOccupationEffect::ALPHA_V = 2.0f; float sBingoEffectState::ALPHA_V = 2.0f; void sBingoMan::readyEffect() { m_wndNew->SetAniName(getTeamAniName(m_status)); m_wndNew->ChangeAlpha(0.0f); m_wndNew->SetShow(true); } void sBingoMan::reset() { m_isBingo = false; /// oldStatus를 체크 하기 때문에 m_status에 값을 미리 넣고 setStatus를 호출한다 m_status = _PROP_STATE::PS_NOT_EXIST; setStatus(m_status); } void sBingoMan::procEffect(float offset, bool& end) { changeAlpha(offset, end); if (end) endProcEffect(); } void sBingoMan::getWndInfo(SUIWnd* parent, int bingoManIndex) { string id; XStringUtil::Format(id, "panel_bingo_default_%02d", bingoManIndex); m_wndCur = parent->GetChild(id.c_str()); XStringUtil::Format(id, "panel_bingo_alliance_gain_%02d", bingoManIndex); m_wndNew = parent->GetChild(id.c_str()); } void sBingoMan::setStatus(int bingoManStatus) { int oldStatus = m_status; m_status = bingoManStatus; if (_PROP_STATE::PS_NOT_EXIST == m_status) { /// 기존 상태가 점령 상태명 클라 자체의 연출 효과가 진행되도록 한다.(서버에서는 빙고가 되고 바로 not exist를 날려주기 때문에) if (_PROP_STATE::PS_OWNED_BY_TEAM_0 != oldStatus && _PROP_STATE::PS_OWNED_BY_TEAM_1 != oldStatus) { m_wndCur->SetShow(false); m_wndNew->SetShow(false); } } else { if (oldStatus == m_status) return ; m_wndCur->SetAniName(getTeamAniName(_PROP_STATE::PS_NEUTRAL)); m_wndCur->ChangeAlpha(1.0f); m_wndCur->SetShow(true); if (_PROP_STATE::PS_NEUTRAL == m_status) { m_wndNew->SetShow(false); } else if (_PROP_STATE::PS_OWNED_BY_TEAM_0 == m_status) { readyEffect(); } else if (_PROP_STATE::PS_OWNED_BY_TEAM_1 == m_status) { readyEffect(); } } } void sBingoMan::changeAlpha(float offset, bool& end) { /// cur, 1.0 -> 0.0 float curAlpha = m_wndCur->GetAlpha() - offset; curAlpha = max(0.0f, curAlpha); m_wndCur->ChangeAlpha(curAlpha); /// new, 0.0 -> 1.0 float newAlpha = m_wndNew->GetAlpha() + offset; newAlpha = min(1.0f, newAlpha); m_wndNew->ChangeAlpha(newAlpha); if (0.0f >= curAlpha && 1.0f <= newAlpha) end = true; else end = false; } void sBingoMan::endProcEffect() { m_wndCur->SetAniName(getTeamAniName(m_status)); m_wndCur->ChangeAlpha(1.0f); m_wndCur->SetShow(true); m_wndNew->SetShow(false); } char const* sBingoMan::getTeamAniName(int team) const { switch (team) { case _PROP_STATE::PS_NOT_EXIST: return ""; case _PROP_STATE::PS_NEUTRAL: return "game_effect_arena_prop_default"; case _PROP_STATE::PS_OWNED_BY_TEAM_0: return "game_effect_arena_prop_alliance_gain"; case _PROP_STATE::PS_OWNED_BY_TEAM_1: return "game_effect_arena_prop_witch_gain"; } assert(0 && "failed getTeamAniName, invalid team"); return ""; } void sBingoManTable::getWndInfo(SUIWnd* parent) { for (int m = 0; m < sBingoManTable::MAX_BINGOMAN_NUM; ++m) { m_bingoMan[m].getWndInfo(parent, m); } } void sBingoManTable::reset() { for (int m = 0; m < sBingoManTable::MAX_BINGOMAN_NUM; ++m) { m_bingoMan[m].reset(); } } void sBingoManTable::setStatus(int bingoManStatus, int bingoManIndex) { m_bingoMan[bingoManIndex].setStatus(bingoManStatus); } int sBingoManTable::getStatus(int bingoManIndex) const { return m_bingoMan[bingoManIndex].getStatus(); } bool sBingoManTable::isValidIndex(int bingoManIndex) const { if (0 <= bingoManIndex && MAX_BINGOMAN_NUM > bingoManIndex) return true; return false; } bool sBingoManTable::isBingo(int bingoManIndex) const { return m_bingoMan[bingoManIndex].isBingo(); } bool sBingoManTable::checkBingo(sBingo const* bingo, int& bingoManStatus) const { bingoManStatus = -1; for (int i = 0; i < sBingo::MAX_BINGOMAN_NUM; ++i) { int bingoManIndex = bingo->getBingoManIndex(i); int curBingoManStatus = m_bingoMan[bingoManIndex].getStatus(); //if (m_bingoMan[bingoManIndex].isBingo()) // return false; if (_PROP_STATE::PS_NOT_EXIST == curBingoManStatus) return false; if (_PROP_STATE::PS_NEUTRAL == curBingoManStatus) return false; else if (-1 == bingoManStatus) bingoManStatus = curBingoManStatus; else if (curBingoManStatus != bingoManStatus) return false; } return true; } void sBingoManTable::setBingo(sBingo const* bingo, bool isBingo) { for (int i = 0; i < sBingo::MAX_BINGOMAN_NUM; ++i) { int bingoManIndex = bingo->getBingoManIndex(i); m_bingoMan[bingoManIndex].setBingo(isBingo); } } void sBingoManTable::reset(int bingoManIndex) { m_bingoMan[bingoManIndex].reset(); } void sBingoManTable::procEffect(int bingoManIndex, float offset, bool& end) { m_bingoMan[bingoManIndex].procEffect(offset, end); } void sBingoEffectState::init(sBingo* bingo, int bingoManStatus) { m_bingo = bingo; m_bingoManStatus = bingoManStatus; setState(STATE_INC_1X); } void sBingoEffectState::setState(int state) { m_state = state; switch (state) { case STATE_INC_1X: m_bingo->setEffectShow(sBingo::EFFECT_BAR, true, 1.0f); m_bingo->setEffectShow(sBingo::EFFECT_BINGOMAN_1X, true, 0.0f); m_bingo->setEffectShow(sBingo::EFFECT_BAR_1X, true, 0.0f); break; case STATE_INC_2X: m_bingo->setEffectShow(sBingo::EFFECT_BINGOMAN_2X, true, 0.0f); m_bingo->setEffectShow(sBingo::EFFECT_BAR_2X, true, 0.0f); break; case STATE_DEC_2X: break; case STATE_DEC_1X: m_bingo->setEffectShow(sBingo::EFFECT_BINGOMAN_2X, false, 0.0f); m_bingo->setEffectShow(sBingo::EFFECT_BAR_2X, false, 0.0f); break; case STATE_DEC_BINGOMAN: m_bingo->setEffectShow(sBingo::EFFECT_BAR, false, 0.0f); m_bingo->setEffectShow(sBingo::EFFECT_BINGOMAN_1X, false, 0.0f); m_bingo->setEffectShow(sBingo::EFFECT_BAR_1X, false, 0.0f); break; case STATE_END: m_bingo->setEffectShow(sBingo::EFFECT_BINGOMAN, false, 0.0f); break; } } void sBingoEffectState::process(float elapsedTime) { if (isEnd()) return ; float offsetAlpha = ALPHA_V * elapsedTime; switch (m_state) { case STATE_INC_1X: procInc1X(elapsedTime, offsetAlpha); break; case STATE_INC_2X: procInc2X(elapsedTime, offsetAlpha); break; case STATE_DEC_2X: procDec2X(elapsedTime, offsetAlpha); break; case STATE_DEC_1X: procDec1X(elapsedTime, offsetAlpha); break; case STATE_DEC_BINGOMAN: procDecBingoMan(elapsedTime, offsetAlpha); break; } } void sBingoEffectState::procInc1X(float elapsedTime, float offsetAlpha) { bool end = false; m_bingo->incEffectAlpha(sBingo::EFFECT_BINGOMAN_1X, offsetAlpha, end); m_bingo->incEffectAlpha(sBingo::EFFECT_BAR_1X, offsetAlpha, end); if (end) setState(STATE_INC_2X); } void sBingoEffectState::procInc2X(float elapsedTime, float offsetAlpha) { bool end = false; m_bingo->incEffectAlpha(sBingo::EFFECT_BINGOMAN_2X, offsetAlpha, end); m_bingo->incEffectAlpha(sBingo::EFFECT_BAR_2X, offsetAlpha, end); if (end) setState(STATE_DEC_2X); } void sBingoEffectState::procDec2X(float elapsedTime, float offsetAlpha) { bool end = false; m_bingo->decEffectAlpha(sBingo::EFFECT_BINGOMAN_2X, offsetAlpha, end); m_bingo->decEffectAlpha(sBingo::EFFECT_BAR_2X, offsetAlpha, end); if (end) setState(STATE_DEC_1X); } void sBingoEffectState::procDec1X(float elapsedTime, float offsetAlpha) { bool end = false; m_bingo->decEffectAlpha(sBingo::EFFECT_BINGOMAN_1X, offsetAlpha, end); m_bingo->decEffectAlpha(sBingo::EFFECT_BAR_1X, offsetAlpha, end); if (end) setState(STATE_DEC_BINGOMAN); } void sBingoEffectState::procDecBingoMan(float elapsedTime, float offsetAlpha) { bool end = false; m_bingo->decEffectAlpha(sBingo::EFFECT_BINGOMAN, offsetAlpha, end); if (end) setState(STATE_END); } sBingoEffect::~sBingoEffect() { m_list.clear(); m_updateBingoManList.clear(); } void sBingoEffect::add(sBingo* bingo, int bingoManStatus) { sBingoEffectState effectState; effectState.init(bingo, bingoManStatus); m_list.push_back(effectState); } bool sBingoEffect::is(int bingoIndex) const { std::list::const_iterator it = m_list.begin(); for (; it != m_list.end();++it) { if (it->m_bingo->getBingoIndex() == bingoIndex) return true; } return false; } void sBingoEffect::process(float elapsedTime, sBingoManTable* bingoManTable, sBingoBoard* bingoBoard) { std::list::iterator it = m_list.begin(); for (; it != m_list.end();) { it->process(elapsedTime); if (it->isEnd()) { resetBingoMan(bingoManTable, it->m_bingo); addUpdateBingoManList(bingoManTable, it->m_bingo); it = m_list.erase(it); } else { ++it; } } updateBingoManStatus(bingoBoard); } void sBingoEffect::resetBingoMan(sBingoManTable* bingoManTable, sBingo* bingo) { for (int i = 0; i < sBingo::MAX_BINGOMAN_NUM; ++i) { bingoManTable->reset(bingo->getBingoManIndex(i)); } } void sBingoEffect::addUpdateBingoManList(sBingoManTable* bingoManTable, sBingo* bingo) { for (int i = 0; i < sBingo::MAX_BINGOMAN_NUM; ++i) { m_updateBingoManList.push_back(bingo->getBingoManIndex(i)); } } void sBingoEffect::updateBingoManStatus(sBingoBoard* bingoBoard) { sArenaSystem* arenaSystem = g_pCurrentGameSystem->getArenaSystem(); std::list::iterator it = m_updateBingoManList.begin(); for (; it != m_updateBingoManList.end(); ++it) { int bingoManIndex = *it; bingoBoard->setStatus(arenaSystem->getBingoManStatus(bingoManIndex), bingoManIndex); } m_updateBingoManList.clear(); } sBingoManOccupationEffect::~sBingoManOccupationEffect() { m_list.clear(); } void sBingoManOccupationEffect::process(float elapsedTime, sBingoManTable* bingoManTable, bool& existEndBingoMan) { bool end; std::map::iterator it = m_list.begin(); for (; it != m_list.end();) { processBingoMan(elapsedTime, bingoManTable, it->second, end); if (end) { it = m_list.erase(it); existEndBingoMan = true; } else { ++it; } } } void sBingoManOccupationEffect::processBingoMan(float elapsedTime, sBingoManTable* bingoManTable, int bingoManIndex, bool& end) { float offset = ALPHA_V * elapsedTime; bingoManTable->procEffect(bingoManIndex, offset, end); } void sBingoManOccupationEffect::add(int bingoManIndex) { if (!is(bingoManIndex)) m_list.insert(std::make_pair(bingoManIndex, bingoManIndex)); } bool sBingoManOccupationEffect::is(int bingoManIndex) const { std::map::const_iterator it = m_list.find(bingoManIndex); return it != m_list.end(); } sBingo::sBingo(int bingoIndex) : m_bingoIndex(bingoIndex) { } sBingo::~sBingo() { for (int i = 0; i < MAX_EFFECT_TYPE_NUM; ++i) m_effectControlList[i].clear(); } void sBingo::setIndex(int i0, int i1, int i2) { m_manIndex[0] = i0; m_manIndex[1] = i1; m_manIndex[2] = i2; } void sBingo::addControlIndex(bool isBingoMan, int controlNum, ...) { /// enum의 순서가 보장되기 때문에 이렇게 가능하다 int baseEffectIndex = (isBingoMan) ? EFFECT_BINGOMAN : EFFECT_BAR; va_list args; va_start(args, controlNum); for (int i = 0; i < controlNum; ++i) { /// bingoman과 bar 타입들은 각각별도 인덱스가 같다 int index = va_arg(args, int); m_effectControlList[baseEffectIndex + 0].push_back(index); m_effectControlList[baseEffectIndex + 1].push_back(index); m_effectControlList[baseEffectIndex + 2].push_back(index); } va_end(args); } void sBingo::reset() { setEffectShow(EFFECT_BAR, false, 0.0f); setEffectShow(EFFECT_BINGOMAN_1X, false, 0.0f); setEffectShow(EFFECT_BAR_1X, false, 0.0f); setEffectShow(EFFECT_BINGOMAN_2X, false, 0.0f); setEffectShow(EFFECT_BAR_2X, false, 0.0f); } void sBingo::setBingoEffectAniName(int bingoManStatus) { setBingoAniName(EFFECT_BINGOMAN_1X, bingoManStatus); setBingoAniName(EFFECT_BINGOMAN_2X, bingoManStatus); setBingoAniName(EFFECT_BAR, bingoManStatus); setBingoAniName(EFFECT_BAR_1X, bingoManStatus); setBingoAniName(EFFECT_BAR_2X, bingoManStatus); } void sBingo::setBingoAniName(int effectType, int bingoManStatus) { char* occupationName, *anotherName; if (_PROP_STATE::PS_OWNED_BY_TEAM_0 == bingoManStatus) { occupationName = "alliance"; anotherName = "witch"; } else { occupationName = "witch"; anotherName = "alliance"; } size_t num = m_effectControlList[effectType].size(); for (size_t n = 0; n < num; ++n) { KUIWnd* wnd = getControl(effectType, (int)n); std::string aniName = wnd->GetAniName(); if (std::string::npos == aniName.find(occupationName)) { XStringUtil::Replace(aniName, anotherName, occupationName); } wnd->SetAniName(aniName.c_str()); } } void sBingo::setEffectShow(int effectType, bool show, float alpha) { size_t num = m_effectControlList[effectType].size(); for (size_t n = 0; n < num; ++n) { KUIWnd* wnd = getControl(effectType, (int)n); wnd->SetShow(show); wnd->ChangeAlpha(alpha); } } void sBingo::incEffectAlpha(int effectType, float offset, bool& end) { float firstAlpha = getFirstEffectControlAlpha(effectType); float alpha = firstAlpha + offset; if (1.0f <= alpha) { alpha = 1.0f; end = true; } setEffectAlpha(effectType, alpha); } void sBingo::decEffectAlpha(int effectType, float offset, bool& end) { float firstAlpha = getFirstEffectControlAlpha(effectType); float alpha = firstAlpha - offset; if (0.0f >= alpha) { alpha = 0.0f; end = true; } setEffectAlpha(effectType, alpha); } void sBingo::setEffectAlpha(int effectType, float alpha) { size_t num = m_effectControlList[effectType].size(); for (size_t n = 0; n < num; ++n) { KUIWnd* wnd = getControl(effectType, (int)n); wnd->ChangeAlpha(alpha); } } KUIWnd* sBingo::getControl(int effectType, int index) const { int controlIndex = m_effectControlList[effectType].at(index); return m_bingoControlTable->getControl(effectType, controlIndex); } float sBingo::getFirstEffectControlAlpha(int effectType) const { KUIWnd* wnd = getControl(effectType, 0); return wnd->GetAlpha(); } sBingoControlTable::~sBingoControlTable() { for (int i = 0; i < sBingo::MAX_EFFECT_TYPE_NUM; ++i) m_list[i].clear(); } void sBingoControlTable::addEffectWnd(SUIWnd* parent, int effectType, char const* prefixId, int controlNum) { std::string id; for (int i = 0; i < controlNum; ++i) { XStringUtil::Format(id, "%s_%02d", prefixId, i); m_list[effectType].push_back(parent->GetChild(id.c_str())); } } KUIWnd* sBingoControlTable::getControl(int effectType, int index) const { return m_list[effectType].at(index); } sBingoBoard::sBingoBoard() : m_bingoManTable(NULL) { } sBingoBoard::~sBingoBoard() { std::vector::iterator it = m_bingoList.begin(); for (; it != m_bingoList.end(); ++it) SAFE_DELETE(*it); m_bingoList.clear(); SAFE_DELETE(m_bingoManTable); } void sBingoBoard::reset() { struct sBingoReset { void operator()(sBingo* bingo) { bingo->reset(); } }; std::for_each(m_bingoList.begin(), m_bingoList.end(), sBingoReset()); m_bingoManTable->reset(); } void sBingoBoard::process(float elapsedTime, int& bingoCount) { bool existEndBingoMan = false; m_bingoManOccupationEffect.process(elapsedTime, m_bingoManTable, existEndBingoMan); bingoCount = 0; if (existEndBingoMan) checkBingo(bingoCount); m_bingoEffect.process(elapsedTime, m_bingoManTable, this); } void sBingoBoard::setStatus(int bingoManStatus, int bingoManIndex) { if (!m_bingoManTable->isValidIndex(bingoManIndex)) return ; if (m_bingoManTable->isBingo(bingoManIndex)) return ; int oldStatus = m_bingoManTable->getStatus(bingoManIndex); m_bingoManTable->setStatus(bingoManStatus, bingoManIndex); if (_PROP_STATE::PS_OWNED_BY_TEAM_0 == bingoManStatus || _PROP_STATE::PS_OWNED_BY_TEAM_1 == bingoManStatus) { /// 이미 연출 된 거면 또 연출이 안되게 걸러 줌 if (oldStatus != bingoManStatus) m_bingoManOccupationEffect.add(bingoManIndex); } } void sBingoBoard::checkBingo(int& bingoCount) { /// double 체크에 쓰임, 각 팀별 빙고 갯수 int team0BingoCount = 0; int team1BingoCount = 0; int bingoManStatus; std::vector::iterator it = m_bingoList.begin(); size_t bingoNum = m_bingoList.size(); for (size_t bingoIndex = 0; bingoIndex < bingoNum; ++bingoIndex) { /// 빙고 연출 중인 인덱스는 제외 if (m_bingoEffect.is((int)bingoIndex)) continue; sBingo* bingo = m_bingoList[bingoIndex]; if (m_bingoManTable->checkBingo(bingo, bingoManStatus)) { bingo->setBingoEffectAniName(bingoManStatus); m_bingoManTable->setBingo(bingo, true); addBingoEffect((int)bingoIndex, bingoManStatus); if (_PROP_STATE::PS_OWNED_BY_TEAM_0 == bingoManStatus) ++team0BingoCount; else if (_PROP_STATE::PS_OWNED_BY_TEAM_1 == bingoManStatus) ++team1BingoCount; } } bingoCount = max(team0BingoCount, team1BingoCount); } void sBingoBoard::addBingoEffect(int bingoIndex, int bingoManStatus) { m_bingoEffect.add(m_bingoList[bingoIndex], bingoManStatus); } void sBingoBoard::initialize(SUIWnd* parent) { assert(!m_bingoManTable); m_bingoManTable = new sBingoManTable; m_bingoManTable->getWndInfo(parent); initBingoControlTable(parent); initBingoList(parent); } void sBingoBoard::initBingoControlTable(SUIWnd* parent) { m_bingoControlTable.addEffectWnd(parent, sBingo::EFFECT_BINGOMAN, "panel_bingo_default", 9); m_bingoControlTable.addEffectWnd(parent, sBingo::EFFECT_BINGOMAN_1X, "panel_effect_bingo_alliance_gain", 9); m_bingoControlTable.addEffectWnd(parent, sBingo::EFFECT_BINGOMAN_2X, "panel_effect_bingo_alliance_gain_2x", 9); m_bingoControlTable.addEffectWnd(parent, sBingo::EFFECT_BAR, "bar_bingo_alliance_gain", 16); m_bingoControlTable.addEffectWnd(parent, sBingo::EFFECT_BAR_1X, "bar_effect_bingo_alliance_gain", 16); m_bingoControlTable.addEffectWnd(parent, sBingo::EFFECT_BAR_2X, "bar_effect_bingo_alliance_gain_2x", 16); } void sBingoBoard::initBingoList(SUIWnd* parent) { /// push하는 순서가 빙고 인덱스가 되기 때문에 순서가 중요하다. sBingo* bingo; /* 0 1 2 x x x x x x */ bingo = new sBingo(0); bingo->setBingoControlTable(&m_bingoControlTable); bingo->setIndex(0, 1, 2); bingo->addControlIndex(true, 3, 0, 1, 2); /// bingoman bingo->addControlIndex(false, 2, 0, 1); /// bar m_bingoList.push_back(bingo); /* x x x 3 4 5 x x x */ bingo = new sBingo(1); bingo->setBingoControlTable(&m_bingoControlTable); bingo->setIndex(3, 4, 5); bingo->addControlIndex(true, 3, 3, 4, 5); /// bingoman bingo->addControlIndex(false, 2, 7, 8); /// bar m_bingoList.push_back(bingo); /* x x x x x x 6 7 8 */ bingo = new sBingo(2); bingo->setBingoControlTable(&m_bingoControlTable); bingo->setIndex(6, 7, 8); bingo->addControlIndex(true, 3, 6, 7, 8); /// bingoman bingo->addControlIndex(false, 2, 14, 15); /// bar m_bingoList.push_back(bingo); /* 0 x x 3 x x 6 x x */ bingo = new sBingo(3); bingo->setBingoControlTable(&m_bingoControlTable); bingo->setIndex(0, 3, 6); bingo->addControlIndex(true, 3, 0, 3, 6); /// bingoman bingo->addControlIndex(false, 2, 2, 9); /// bar m_bingoList.push_back(bingo); /* x 1 x x 4 x x 7 x */ bingo = new sBingo(4); bingo->setBingoControlTable(&m_bingoControlTable); bingo->setIndex(1, 4, 7); bingo->addControlIndex(true, 3, 1, 4, 7); /// bingoman bingo->addControlIndex(false, 2, 4, 11); /// bar m_bingoList.push_back(bingo); /* x x 2 x x 5 x x 8 */ bingo = new sBingo(5); bingo->setBingoControlTable(&m_bingoControlTable); bingo->setIndex(2, 5, 8); bingo->addControlIndex(true, 3, 2, 5, 8); /// bingoman bingo->addControlIndex(false, 2, 6, 13); /// bar m_bingoList.push_back(bingo); /* 0 x x x 4 x x x 8 */ bingo = new sBingo(6); bingo->setBingoControlTable(&m_bingoControlTable); bingo->setIndex(0, 4, 8); bingo->addControlIndex(true, 3, 0, 4, 8); /// bingoman bingo->addControlIndex(false, 2, 3, 12); /// bar m_bingoList.push_back(bingo); /* x x 2 x 4 x 6 x x */ bingo = new sBingo(7); bingo->setBingoControlTable(&m_bingoControlTable); bingo->setIndex(2, 4, 6); bingo->addControlIndex(true, 3, 2, 4, 6); /// bingoman bingo->addControlIndex(false, 2, 5, 10); /// bar m_bingoList.push_back(bingo); }