1
0
forked from metin2/server
server/game/src/OXEvent.cpp

442 lines
9.3 KiB
C++
Raw Normal View History

2022-03-05 12:44:06 +02:00
#include "stdafx.h"
#include "constants.h"
#include "config.h"
#include "questmanager.h"
#include "start_position.h"
#include "packet.h"
#include "buffer_manager.h"
#include "log.h"
#include "char.h"
#include "char_manager.h"
#include "OXEvent.h"
#include "desc.h"
bool COXEventManager::Initialize()
{
m_timedEvent = NULL;
m_map_char.clear();
m_map_attender.clear();
m_vec_quiz.clear();
SetStatus(OXEVENT_FINISH);
return true;
}
void COXEventManager::Destroy()
{
CloseEvent();
m_map_char.clear();
m_map_attender.clear();
m_vec_quiz.clear();
SetStatus(OXEVENT_FINISH);
}
OXEventStatus COXEventManager::GetStatus()
{
BYTE ret = quest::CQuestManager::instance().GetEventFlag("oxevent_status");
switch (ret)
{
case 0 :
return OXEVENT_FINISH;
case 1 :
return OXEVENT_OPEN;
case 2 :
return OXEVENT_CLOSE;
case 3 :
return OXEVENT_QUIZ;
default :
return OXEVENT_ERR;
}
return OXEVENT_ERR;
}
void COXEventManager::SetStatus(OXEventStatus status)
{
BYTE val = 0;
switch (status)
{
case OXEVENT_OPEN :
val = 1;
break;
case OXEVENT_CLOSE :
val = 2;
break;
case OXEVENT_QUIZ :
val = 3;
break;
case OXEVENT_FINISH :
case OXEVENT_ERR :
default :
val = 0;
break;
}
quest::CQuestManager::instance().RequestSetEventFlag("oxevent_status", val);
}
bool COXEventManager::Enter(LPCHARACTER pkChar)
{
if (GetStatus() == OXEVENT_FINISH)
{
sys_log(0, "OXEVENT : map finished. but char enter. %s", pkChar->GetName());
return false;
}
PIXEL_POSITION pos = pkChar->GetXYZ();
if (pos.x == 896500 && pos.y == 24600)
{
return EnterAttender(pkChar);
}
else if (pos.x == 896300 && pos.y == 28900)
{
return EnterAudience(pkChar);
}
else
{
sys_log(0, "OXEVENT : wrong pos enter %d %d", pos.x, pos.y);
return false;
}
return false;
}
bool COXEventManager::EnterAttender(LPCHARACTER pkChar)
{
DWORD pid = pkChar->GetPlayerID();
m_map_char.insert(std::make_pair(pid, pid));
m_map_attender.insert(std::make_pair(pid, pid));
return true;
}
bool COXEventManager::EnterAudience(LPCHARACTER pkChar)
{
DWORD pid = pkChar->GetPlayerID();
m_map_char.insert(std::make_pair(pid, pid));
return true;
}
bool COXEventManager::AddQuiz(unsigned char level, const char* pszQuestion, bool answer)
{
if (m_vec_quiz.size() < (size_t) level + 1)
m_vec_quiz.resize(level + 1);
struct tag_Quiz tmpQuiz;
tmpQuiz.level = level;
2022-03-05 19:59:39 +02:00
strncpy(tmpQuiz.Quiz, pszQuestion, sizeof(tmpQuiz.Quiz));
2022-03-05 12:44:06 +02:00
tmpQuiz.answer = answer;
m_vec_quiz[level].push_back(tmpQuiz);
return true;
}
bool COXEventManager::ShowQuizList(LPCHARACTER pkChar)
{
int c = 0;
for (size_t i = 0; i < m_vec_quiz.size(); ++i)
{
for (size_t j = 0; j < m_vec_quiz[i].size(); ++j, ++c)
{
pkChar->ChatPacket(CHAT_TYPE_INFO, "%d %s %s", m_vec_quiz[i][j].level, m_vec_quiz[i][j].Quiz, m_vec_quiz[i][j].answer ? LC_TEXT("<EFBFBD><EFBFBD>") : LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"));
}
}
pkChar->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>: %d"), c);
return true;
}
void COXEventManager::ClearQuiz()
{
for (unsigned int i = 0; i < m_vec_quiz.size(); ++i)
{
m_vec_quiz[i].clear();
}
m_vec_quiz.clear();
}
EVENTINFO(OXEventInfoData)
{
bool answer;
OXEventInfoData()
: answer( false )
{
}
};
EVENTFUNC(oxevent_timer)
{
static BYTE flag = 0;
OXEventInfoData* info = dynamic_cast<OXEventInfoData*>(event->info);
if ( info == NULL )
{
sys_err( "oxevent_timer> <Factor> Null pointer" );
return 0;
}
switch (flag)
{
case 0:
SendNoticeMap(LC_TEXT("10<EFBFBD>ʵ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰڽ<CFB0><DABD>ϴ<EFBFBD>."), OXEVENT_MAP_INDEX, true);
flag++;
return PASSES_PER_SEC(10);
case 1:
SendNoticeMap(LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"), OXEVENT_MAP_INDEX, true);
if (info->answer == true)
{
COXEventManager::instance().CheckAnswer(true);
SendNoticeMap(LC_TEXT("O <20>Դϴ<D4B4>"), OXEVENT_MAP_INDEX, true);
}
else
{
COXEventManager::instance().CheckAnswer(false);
SendNoticeMap(LC_TEXT("X <20>Դϴ<D4B4>"), OXEVENT_MAP_INDEX, true);
}
if (LC_IsJapan())
{
SendNoticeMap("<EFBFBD>ԈႦ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>X<EFBFBD><EFBFBD><EFBFBD>O<EFBFBD>Ɉړ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>܂<EFBFBD><EFBFBD>B", OXEVENT_MAP_INDEX, true);
}
else
{
SendNoticeMap(LC_TEXT("5<EFBFBD><EFBFBD> <20><> Ʋ<><C6B2><EFBFBD><EFBFBD> <20>е<EFBFBD><D0B5><EFBFBD> <20>ٱ<EFBFBD><D9B1><EFBFBD><EFBFBD><EFBFBD> <20>̵<EFBFBD> <20><>Ű<EFBFBD>ڽ<EFBFBD><DABD>ϴ<EFBFBD>."), OXEVENT_MAP_INDEX, true);
}
flag++;
return PASSES_PER_SEC(5);
case 2:
COXEventManager::instance().WarpToAudience();
COXEventManager::instance().SetStatus(OXEVENT_CLOSE);
SendNoticeMap(LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>غ<EFBFBD><D8BA><EFBFBD><EFBFBD>ּ<EFBFBD><D6BC><EFBFBD>."), OXEVENT_MAP_INDEX, true);
flag = 0;
break;
}
return 0;
}
bool COXEventManager::Quiz(unsigned char level, int timelimit)
{
if (m_vec_quiz.size() == 0) return false;
if (level > m_vec_quiz.size()) level = m_vec_quiz.size() - 1;
if (m_vec_quiz[level].size() <= 0) return false;
if (timelimit < 0) timelimit = 30;
int idx = number(0, m_vec_quiz[level].size()-1);
SendNoticeMap(LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Դϴ<D4B4>."), OXEVENT_MAP_INDEX, true);
SendNoticeMap(m_vec_quiz[level][idx].Quiz, OXEVENT_MAP_INDEX, true);
SendNoticeMap(LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> O, Ʋ<><C6B2><EFBFBD><EFBFBD> X<><58> <20>̵<EFBFBD><CCB5><EFBFBD><EFBFBD>ּ<EFBFBD><D6BC><EFBFBD>"), OXEVENT_MAP_INDEX, true);
if (m_timedEvent != NULL) {
event_cancel(&m_timedEvent);
}
OXEventInfoData* answer = AllocEventInfo<OXEventInfoData>();
answer->answer = m_vec_quiz[level][idx].answer;
timelimit -= 15;
m_timedEvent = event_create(oxevent_timer, answer, PASSES_PER_SEC(timelimit));
SetStatus(OXEVENT_QUIZ);
m_vec_quiz[level].erase(m_vec_quiz[level].begin()+idx);
return true;
}
bool COXEventManager::CheckAnswer(bool answer)
{
if (m_map_attender.size() <= 0) return true;
itertype(m_map_attender) iter = m_map_attender.begin();
itertype(m_map_attender) iter_tmp;
m_map_miss.clear();
int rect[4];
if (answer != true)
{
rect[0] = 892600;
rect[1] = 22900;
rect[2] = 896300;
rect[3] = 26400;
}
else
{
rect[0] = 896600;
rect[1] = 22900;
rect[2] = 900300;
rect[3] = 26400;
}
LPCHARACTER pkChar = NULL;
PIXEL_POSITION pos;
for (; iter != m_map_attender.end();)
{
pkChar = CHARACTER_MANAGER::instance().FindByPID(iter->second);
if (pkChar != NULL)
{
pos = pkChar->GetXYZ();
if (pos.x < rect[0] || pos.x > rect[2] || pos.y < rect[1] || pos.y > rect[3])
{
pkChar->EffectPacket(SE_FAIL);
iter_tmp = iter;
iter++;
m_map_attender.erase(iter_tmp);
m_map_miss.insert(std::make_pair(pkChar->GetPlayerID(), pkChar->GetPlayerID()));
}
else
{
pkChar->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դϴ<EFBFBD>!"));
// pkChar->CreateFly(number(FLY_FIREWORK1, FLY_FIREWORK6), pkChar);
char chatbuf[256];
int len = snprintf(chatbuf, sizeof(chatbuf),
"%s %u %u", number(0, 1) == 1 ? "cheer1" : "cheer2", (DWORD)pkChar->GetVID(), 0);
// <20><><EFBFBD>ϰ<EFBFBD><CFB0><EFBFBD> sizeof(chatbuf) <20>̻<EFBFBD><CCBB><EFBFBD> <20><><EFBFBD><EFBFBD> truncate<74>Ǿ<EFBFBD><C7BE>ٴ<EFBFBD> <20><>..
if (len < 0 || len >= (int) sizeof(chatbuf))
len = sizeof(chatbuf) - 1;
// \0 <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
++len;
TPacketGCChat pack_chat;
pack_chat.header = HEADER_GC_CHAT;
pack_chat.size = sizeof(TPacketGCChat) + len;
pack_chat.type = CHAT_TYPE_COMMAND;
pack_chat.id = 0;
TEMP_BUFFER buf;
buf.write(&pack_chat, sizeof(TPacketGCChat));
buf.write(chatbuf, len);
pkChar->PacketAround(buf.read_peek(), buf.size());
pkChar->EffectPacket(SE_SUCCESS);
++iter;
}
}
else
{
itertype(m_map_char) err = m_map_char.find(iter->first);
if (err != m_map_char.end()) m_map_char.erase(err);
itertype(m_map_miss) err2 = m_map_miss.find(iter->first);
if (err2 != m_map_miss.end()) m_map_miss.erase(err2);
iter_tmp = iter;
++iter;
m_map_attender.erase(iter_tmp);
}
}
return true;
}
void COXEventManager::WarpToAudience()
{
if (m_map_miss.size() <= 0) return;
itertype(m_map_miss) iter = m_map_miss.begin();
LPCHARACTER pkChar = NULL;
for (; iter != m_map_miss.end(); ++iter)
{
pkChar = CHARACTER_MANAGER::instance().FindByPID(iter->second);
if (pkChar != NULL)
{
switch ( number(0, 3))
{
case 0 : pkChar->Show(OXEVENT_MAP_INDEX, 896300, 28900); break;
case 1 : pkChar->Show(OXEVENT_MAP_INDEX, 890900, 28100); break;
case 2 : pkChar->Show(OXEVENT_MAP_INDEX, 896600, 20500); break;
case 3 : pkChar->Show(OXEVENT_MAP_INDEX, 902500, 28100); break;
default : pkChar->Show(OXEVENT_MAP_INDEX, 896300, 28900); break;
}
}
}
m_map_miss.clear();
}
bool COXEventManager::CloseEvent()
{
if (m_timedEvent != NULL) {
event_cancel(&m_timedEvent);
}
itertype(m_map_char) iter = m_map_char.begin();
LPCHARACTER pkChar = NULL;
for (; iter != m_map_char.end(); ++iter)
{
pkChar = CHARACTER_MANAGER::instance().FindByPID(iter->second);
if (pkChar != NULL)
pkChar->WarpSet(EMPIRE_START_X(pkChar->GetEmpire()), EMPIRE_START_Y(pkChar->GetEmpire()));
}
m_map_char.clear();
return true;
}
bool COXEventManager::LogWinner()
{
itertype(m_map_attender) iter = m_map_attender.begin();
for (; iter != m_map_attender.end(); ++iter)
{
LPCHARACTER pkChar = CHARACTER_MANAGER::instance().FindByPID(iter->second);
if (pkChar)
LogManager::instance().CharLog(pkChar, 0, "OXEVENT", "LastManStanding");
}
return true;
}
bool COXEventManager::GiveItemToAttender(DWORD dwItemVnum, BYTE count)
{
itertype(m_map_attender) iter = m_map_attender.begin();
for (; iter != m_map_attender.end(); ++iter)
{
LPCHARACTER pkChar = CHARACTER_MANAGER::instance().FindByPID(iter->second);
if (pkChar)
{
pkChar->AutoGiveItem(dwItemVnum, count);
LogManager::instance().ItemLog(pkChar->GetPlayerID(), 0, count, dwItemVnum, "OXEVENT_REWARD", "", pkChar->GetDesc()->GetHostName(), dwItemVnum);
}
}
return true;
}