server/src/game/src/cmd_general.cpp

2651 lines
73 KiB
C++

#include "stdafx.h"
#include "utils.h"
#include "config.h"
#include "desc_client.h"
#include "desc_manager.h"
#include "char.h"
#include "char_manager.h"
#include "motion.h"
#include "packet.h"
#include "affect.h"
#include "pvp.h"
#include "start_position.h"
#include "party.h"
#include "guild_manager.h"
#include "p2p.h"
#include "dungeon.h"
#include "messenger_manager.h"
#include "war_map.h"
#include "questmanager.h"
#include "item_manager.h"
#include "monarch.h"
#include "mob_manager.h"
#include "item.h"
#include "arena.h"
#include "buffer_manager.h"
#include "unique_item.h"
#include "threeway_war.h"
#include "log.h"
#include <common/VnumHelper.h>
#ifdef __AUCTION__
#include "auction_manager.h"
#endif
extern int g_server_id;
extern int g_nPortalLimitTime;
ACMD(do_user_horse_ride)
{
if (ch->IsObserverMode())
return;
if (ch->IsDead() || ch->IsStun())
return;
if (ch->IsHorseRiding() == false)
{
// 말이 아닌 다른탈것을 타고있다.
if (ch->GetMountVnum())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC0\xCC\xB9\xCC \xC5\xBB\xB0\xCD\xC0\xBB \xC0\xCC\xBF\xEB\xC1\xDF\xC0\xD4\xB4\xCF\xB4\xD9."));
return;
}
if (ch->GetHorse() == NULL)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB8\xBB\xC0\xBB \xB8\xD5\xC0\xFA \xBC\xD2\xC8\xAF\xC7\xD8\xC1\xD6\xBC\xBC\xBF\xE4."));
return;
}
ch->StartRiding();
}
else
{
ch->StopRiding();
}
}
ACMD(do_user_horse_back)
{
if (ch->GetHorse() != NULL)
{
ch->HorseSummon(false);
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB8\xBB\xC0\xBB \xB5\xB9\xB7\xC1\xBA\xB8\xB3\xC2\xBD\xC0\xB4\xCF\xB4\xD9."));
}
else if (ch->IsHorseRiding() == true)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB8\xBB\xBF\xA1\xBC\xAD \xB8\xD5\xC0\xFA \xB3\xBB\xB7\xC1\xBE\xDF \xC7\xD5\xB4\xCF\xB4\xD9."));
}
else
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB8\xBB\xC0\xBB \xB8\xD5\xC0\xFA \xBC\xD2\xC8\xAF\xC7\xD8\xC1\xD6\xBC\xBC\xBF\xE4."));
}
}
ACMD(do_user_horse_feed)
{
// 개인상점을 연 상태에서는 말 먹이를 줄 수 없다.
if (ch->GetMyShop())
return;
if (ch->GetHorse() == NULL)
{
if (ch->IsHorseRiding() == false)
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB8\xBB\xC0\xBB \xB8\xD5\xC0\xFA \xBC\xD2\xC8\xAF\xC7\xD8\xC1\xD6\xBC\xBC\xBF\xE4."));
else
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB8\xBB\xC0\xBB \xC5\xBA \xBB\xF3\xC5\xC2\xBF\xA1\xBC\xAD\xB4\xC2 \xB8\xD4\xC0\xCC\xB8\xA6 \xC1\xD9 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
DWORD dwFood = ch->GetHorseGrade() + 50054 - 1;
if (ch->CountSpecifyItem(dwFood) > 0)
{
ch->RemoveSpecifyItem(dwFood, 1);
ch->FeedHorse();
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB8\xBB\xBF\xA1\xB0\xD4 %s%s \xC1\xD6\xBE\xFA\xBD\xC0\xB4\xCF\xB4\xD9."),
ITEM_MANAGER::instance().GetTable(dwFood)->szLocaleName, "");
}
else
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s \xBE\xC6\xC0\xCC\xC5\xDB\xC0\xCC \xC7\xCA\xBF\xE4\xC7\xD5\xB4\xCF\xB4\xD9"), ITEM_MANAGER::instance().GetTable(dwFood)->szLocaleName);
}
}
#define MAX_REASON_LEN 128
EVENTINFO(TimedEventInfo)
{
DynamicCharacterPtr ch;
int subcmd;
int left_second;
char szReason[MAX_REASON_LEN];
TimedEventInfo()
: ch()
, subcmd( 0 )
, left_second( 0 )
{
::memset( szReason, 0, MAX_REASON_LEN );
}
};
struct SendDisconnectFunc
{
void operator () (LPDESC d)
{
if (d->GetCharacter())
{
if (d->GetCharacter()->GetGMLevel() == GM_PLAYER)
d->GetCharacter()->ChatPacket(CHAT_TYPE_COMMAND, "quit Shutdown(SendDisconnectFunc)");
}
}
};
struct DisconnectFunc
{
void operator () (LPDESC d)
{
if (d->GetType() == DESC_TYPE_CONNECTOR)
return;
if (d->IsPhase(PHASE_P2P))
return;
if (d->GetCharacter())
d->GetCharacter()->Disconnect("Shutdown(DisconnectFunc)");
d->SetPhase(PHASE_CLOSE);
}
};
EVENTINFO(shutdown_event_data)
{
int seconds;
shutdown_event_data()
: seconds( 0 )
{
}
};
EVENTFUNC(shutdown_event)
{
shutdown_event_data* info = dynamic_cast<shutdown_event_data*>( event->info );
if ( info == NULL )
{
SPDLOG_ERROR("shutdown_event> <Factor> Null pointer" );
return 0;
}
int * pSec = & (info->seconds);
if (*pSec < 0)
{
SPDLOG_INFO("shutdown_event sec {}", *pSec);
if (--*pSec == -10)
{
const DESC_MANAGER::DESC_SET & c_set_desc = DESC_MANAGER::instance().GetClientSet();
std::for_each(c_set_desc.begin(), c_set_desc.end(), DisconnectFunc());
return passes_per_sec;
}
else if (*pSec < -10)
return 0;
return passes_per_sec;
}
else if (*pSec == 0)
{
const DESC_MANAGER::DESC_SET & c_set_desc = DESC_MANAGER::instance().GetClientSet();
std::for_each(c_set_desc.begin(), c_set_desc.end(), SendDisconnectFunc());
g_bNoMoreClient = true;
--*pSec;
return passes_per_sec;
}
else
{
char buf[64];
snprintf(buf, sizeof(buf), LC_TEXT("\xBC\xCB\xB4\xD9\xBF\xEE\xC0\xCC %d\xC3\xCA \xB3\xB2\xBE\xD2\xBD\xC0\xB4\xCF\xB4\xD9."), *pSec);
SendNotice(buf);
--*pSec;
return passes_per_sec;
}
}
void Shutdown(int iSec)
{
if (g_bNoMoreClient)
{
thecore_shutdown();
return;
}
CWarMapManager::instance().OnShutdown();
char buf[64];
snprintf(buf, sizeof(buf), LC_TEXT("%d\xC3\xCA \xC8\xC4 \xB0\xD4\xC0\xD3\xC0\xCC \xBC\xCB\xB4\xD9\xBF\xEE \xB5\xCB\xB4\xCF\xB4\xD9."), iSec);
SendNotice(buf);
shutdown_event_data* info = AllocEventInfo<shutdown_event_data>();
info->seconds = iSec;
event_create(shutdown_event, info, 1);
}
ACMD(do_shutdown)
{
if (NULL == ch)
{
SPDLOG_ERROR("Accept shutdown command from {}.", ch->GetName());
}
TPacketGGShutdown p;
p.bHeader = HEADER_GG_SHUTDOWN;
P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGShutdown));
Shutdown(10);
}
EVENTFUNC(timed_event)
{
TimedEventInfo * info = dynamic_cast<TimedEventInfo *>( event->info );
if ( info == NULL )
{
SPDLOG_ERROR("timed_event> <Factor> Null pointer" );
return 0;
}
LPCHARACTER ch = info->ch;
if (ch == NULL) { // <Factor>
return 0;
}
LPDESC d = ch->GetDesc();
if (info->left_second <= 0)
{
ch->m_pkTimedEvent = NULL;
if (true == LC_IsEurope() || true == LC_IsYMIR() || true == LC_IsKorea())
{
switch (info->subcmd)
{
case SCMD_LOGOUT:
case SCMD_QUIT:
case SCMD_PHASE_SELECT:
{
TPacketNeedLoginLogInfo acc_info;
acc_info.dwPlayerID = ch->GetDesc()->GetAccountTable().id;
db_clientdesc->DBPacket( HEADER_GD_VALID_LOGOUT, 0, &acc_info, sizeof(acc_info) );
LogManager::instance().DetailLoginLog( false, ch );
}
break;
}
}
switch (info->subcmd)
{
case SCMD_LOGOUT:
if (d)
d->SetPhase(PHASE_CLOSE);
break;
case SCMD_QUIT:
ch->ChatPacket(CHAT_TYPE_COMMAND, "quit");
break;
case SCMD_PHASE_SELECT:
{
ch->Disconnect("timed_event - SCMD_PHASE_SELECT");
if (d)
{
d->SetPhase(PHASE_SELECT);
}
}
break;
}
return 0;
}
else
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d\xC3\xCA \xB3\xB2\xBE\xD2\xBD\xC0\xB4\xCF\xB4\xD9."), info->left_second);
--info->left_second;
}
return PASSES_PER_SEC(1);
}
ACMD(do_cmd)
{
/* RECALL_DELAY
if (ch->m_pkRecallEvent != NULL)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC3\xEB\xBC\xD2 \xB5\xC7\xBE\xFA\xBD\xC0\xB4\xCF\xB4\xD9."));
event_cancel(&ch->m_pkRecallEvent);
return;
}
// END_OF_RECALL_DELAY */
if (ch->m_pkTimedEvent)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC3\xEB\xBC\xD2 \xB5\xC7\xBE\xFA\xBD\xC0\xB4\xCF\xB4\xD9."));
event_cancel(&ch->m_pkTimedEvent);
return;
}
switch (subcmd)
{
case SCMD_LOGOUT:
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB7\xCE\xB1\xD7\xC0\xCE \xC8\xAD\xB8\xE9\xC0\xB8\xB7\xCE \xB5\xB9\xBE\xC6 \xB0\xA9\xB4\xCF\xB4\xD9. \xC0\xE1\xBD\xC3\xB8\xB8 \xB1\xE2\xB4\xD9\xB8\xAE\xBC\xBC\xBF\xE4."));
break;
case SCMD_QUIT:
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB0\xD4\xC0\xD3\xC0\xBB \xC1\xBE\xB7\xE1 \xC7\xD5\xB4\xCF\xB4\xD9. \xC0\xE1\xBD\xC3\xB8\xB8 \xB1\xE2\xB4\xD9\xB8\xAE\xBC\xBC\xBF\xE4."));
break;
case SCMD_PHASE_SELECT:
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC4\xB3\xB8\xAF\xC5\xCD\xB8\xA6 \xC0\xFC\xC8\xAF \xC7\xD5\xB4\xCF\xB4\xD9. \xC0\xE1\xBD\xC3\xB8\xB8 \xB1\xE2\xB4\xD9\xB8\xAE\xBC\xBC\xBF\xE4."));
break;
}
int nExitLimitTime = 10;
if (ch->IsHack(false, true, nExitLimitTime) &&
false == CThreeWayWar::instance().IsSungZiMapIndex(ch->GetMapIndex()) &&
(!ch->GetWarMap() || ch->GetWarMap()->GetType() == GUILD_WAR_TYPE_FLAG))
{
return;
}
switch (subcmd)
{
case SCMD_LOGOUT:
case SCMD_QUIT:
case SCMD_PHASE_SELECT:
{
TimedEventInfo* info = AllocEventInfo<TimedEventInfo>();
{
if (ch->IsPosition(POS_FIGHTING))
info->left_second = 10;
else
info->left_second = 3;
}
info->ch = ch;
info->subcmd = subcmd;
strlcpy(info->szReason, argument, sizeof(info->szReason));
ch->m_pkTimedEvent = event_create(timed_event, info, 1);
}
break;
}
}
ACMD(do_mount)
{
/*
char arg1[256];
struct action_mount_param param;
// 이미 타고 있으면
if (ch->GetMountingChr())
{
char arg2[256];
two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
if (!*arg1 || !*arg2)
return;
param.x = atoi(arg1);
param.y = atoi(arg2);
param.vid = ch->GetMountingChr()->GetVID();
param.is_unmount = true;
float distance = DISTANCE_SQRT(param.x - (DWORD) ch->GetX(), param.y - (DWORD) ch->GetY());
if (distance > 600.0f)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC1\xBB \xB4\xF5 \xB0\xA1\xB1\xEE\xC0\xCC \xB0\xA1\xBC\xAD \xB3\xBB\xB8\xAE\xBC\xBC\xBF\xE4."));
return;
}
action_enqueue(ch, ACTION_TYPE_MOUNT, &param, 0.0f, true);
return;
}
one_argument(argument, arg1, sizeof(arg1));
if (!*arg1)
return;
LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(atoi(arg1));
if (!tch->IsNPC() || !tch->IsMountable())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB0\xC5\xB1\xE2\xBF\xA1\xB4\xC2 \xC5\xBB \xBC\xF6 \xBE\xF8\xBE\xEE\xBF\xE4."));
return;
}
float distance = DISTANCE_SQRT(tch->GetX() - ch->GetX(), tch->GetY() - ch->GetY());
if (distance > 600.0f)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC1\xBB \xB4\xF5 \xB0\xA1\xB1\xEE\xC0\xCC \xB0\xA1\xBC\xAD \xC5\xB8\xBC\xBC\xBF\xE4."));
return;
}
param.vid = tch->GetVID();
param.is_unmount = false;
action_enqueue(ch, ACTION_TYPE_MOUNT, &param, 0.0f, true);
*/
}
ACMD(do_fishing)
{
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
if (!*arg1)
return;
ch->SetRotation(atof(arg1));
ch->fishing();
}
ACMD(do_console)
{
ch->ChatPacket(CHAT_TYPE_COMMAND, "ConsoleEnable");
}
ACMD(do_restart)
{
if (false == ch->IsDead())
{
ch->ChatPacket(CHAT_TYPE_COMMAND, "CloseRestartWindow");
ch->StartRecoveryEvent();
return;
}
if (NULL == ch->m_pkDeadEvent)
return;
int iTimeToDead = (event_time(ch->m_pkDeadEvent) / passes_per_sec);
if (subcmd != SCMD_RESTART_TOWN && (!ch->GetWarMap() || ch->GetWarMap()->GetType() == GUILD_WAR_TYPE_FLAG))
{
if (!test_server)
{
if (ch->IsHack())
{
//성지 맵일경우에는 체크 하지 않는다.
if (false == CThreeWayWar::instance().IsSungZiMapIndex(ch->GetMapIndex()))
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBE\xC6\xC1\xF7 \xC0\xE7\xBD\xC3\xC0\xDB \xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9. (%d\xC3\xCA \xB3\xB2\xC0\xBD)"), iTimeToDead - (180 - g_nPortalLimitTime));
return;
}
}
if (iTimeToDead > 170)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBE\xC6\xC1\xF7 \xC0\xE7\xBD\xC3\xC0\xDB \xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9. (%d\xC3\xCA \xB3\xB2\xC0\xBD)"), iTimeToDead - 170);
return;
}
}
}
//PREVENT_HACK
//DESC : 창고, 교환 창 후 포탈을 사용하는 버그에 이용될수 있어서
// 쿨타임을 추가
if (subcmd == SCMD_RESTART_TOWN)
{
if (ch->IsHack())
{
//길드맵, 성지맵에서는 체크 하지 않는다.
if ((!ch->GetWarMap() || ch->GetWarMap()->GetType() == GUILD_WAR_TYPE_FLAG) ||
false == CThreeWayWar::instance().IsSungZiMapIndex(ch->GetMapIndex()))
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBE\xC6\xC1\xF7 \xC0\xE7\xBD\xC3\xC0\xDB \xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9. (%d\xC3\xCA \xB3\xB2\xC0\xBD)"), iTimeToDead - (180 - g_nPortalLimitTime));
return;
}
}
if (iTimeToDead > 173)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBE\xC6\xC1\xF7 \xB8\xB6\xC0\xBB\xBF\xA1\xBC\xAD \xC0\xE7\xBD\xC3\xC0\xDB \xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9. (%d \xC3\xCA \xB3\xB2\xC0\xBD)"), iTimeToDead - 173);
return;
}
}
//END_PREVENT_HACK
ch->ChatPacket(CHAT_TYPE_COMMAND, "CloseRestartWindow");
ch->GetDesc()->SetPhase(PHASE_GAME);
ch->SetPosition(POS_STANDING);
ch->StartRecoveryEvent();
//FORKED_LOAD
//DESC: 삼거리 전투시 부활을 할경우 맵의 입구가 아닌 삼거리 전투의 시작지점으로 이동하게 된다.
if (1 == quest::CQuestManager::instance().GetEventFlag("threeway_war"))
{
if (subcmd == SCMD_RESTART_TOWN || subcmd == SCMD_RESTART_HERE)
{
if (true == CThreeWayWar::instance().IsThreeWayWarMapIndex(ch->GetMapIndex()) &&
false == CThreeWayWar::instance().IsSungZiMapIndex(ch->GetMapIndex()))
{
ch->WarpSet(EMPIRE_START_X(ch->GetEmpire()), EMPIRE_START_Y(ch->GetEmpire()));
ch->ReviveInvisible(5);
ch->PointChange(POINT_HP, ch->GetMaxHP() - ch->GetHP());
ch->PointChange(POINT_SP, ch->GetMaxSP() - ch->GetSP());
return;
}
//성지
if (true == CThreeWayWar::instance().IsSungZiMapIndex(ch->GetMapIndex()))
{
if (CThreeWayWar::instance().GetReviveTokenForPlayer(ch->GetPlayerID()) <= 0)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBC\xBA\xC1\xF6\xBF\xA1\xBC\xAD \xBA\xCE\xC8\xB0 \xB1\xE2\xC8\xB8\xB8\xA6 \xB8\xF0\xB5\xCE \xC0\xD2\xBE\xFA\xBD\xC0\xB4\xCF\xB4\xD9! \xB8\xB6\xC0\xBB\xB7\xCE \xC0\xCC\xB5\xBF\xC7\xD5\xB4\xCF\xB4\xD9!"));
ch->WarpSet(EMPIRE_START_X(ch->GetEmpire()), EMPIRE_START_Y(ch->GetEmpire()));
}
else
{
ch->Show(ch->GetMapIndex(), GetSungziStartX(ch->GetEmpire()), GetSungziStartY(ch->GetEmpire()));
}
ch->PointChange(POINT_HP, ch->GetMaxHP() - ch->GetHP());
ch->PointChange(POINT_SP, ch->GetMaxSP() - ch->GetSP());
ch->ReviveInvisible(5);
return;
}
}
}
//END_FORKED_LOAD
if (ch->GetDungeon())
ch->GetDungeon()->UseRevive(ch);
if (ch->GetWarMap() && !ch->IsObserverMode())
{
CWarMap * pMap = ch->GetWarMap();
DWORD dwGuildOpponent = pMap ? pMap->GetGuildOpponent(ch) : 0;
if (dwGuildOpponent)
{
switch (subcmd)
{
case SCMD_RESTART_TOWN:
SPDLOG_DEBUG("do_restart: restart town");
PIXEL_POSITION pos;
if (CWarMapManager::instance().GetStartPosition(ch->GetMapIndex(), ch->GetGuild()->GetID() < dwGuildOpponent ? 0 : 1, pos))
ch->Show(ch->GetMapIndex(), pos.x, pos.y);
else
ch->ExitToSavedLocation();
ch->PointChange(POINT_HP, ch->GetMaxHP() - ch->GetHP());
ch->PointChange(POINT_SP, ch->GetMaxSP() - ch->GetSP());
ch->ReviveInvisible(5);
break;
case SCMD_RESTART_HERE:
SPDLOG_DEBUG("do_restart: restart here");
ch->RestartAtSamePos();
//ch->Show(ch->GetMapIndex(), ch->GetX(), ch->GetY());
ch->PointChange(POINT_HP, ch->GetMaxHP() - ch->GetHP());
ch->PointChange(POINT_SP, ch->GetMaxSP() - ch->GetSP());
ch->ReviveInvisible(5);
break;
}
return;
}
}
switch (subcmd)
{
case SCMD_RESTART_TOWN:
SPDLOG_DEBUG("do_restart: restart town");
PIXEL_POSITION pos;
if (SECTREE_MANAGER::instance().GetRecallPositionByEmpire(ch->GetMapIndex(), ch->GetEmpire(), pos))
ch->WarpSet(pos.x, pos.y);
else
ch->WarpSet(EMPIRE_START_X(ch->GetEmpire()), EMPIRE_START_Y(ch->GetEmpire()));
ch->PointChange(POINT_HP, 50 - ch->GetHP());
ch->DeathPenalty(1);
break;
case SCMD_RESTART_HERE:
SPDLOG_DEBUG("do_restart: restart here");
ch->RestartAtSamePos();
//ch->Show(ch->GetMapIndex(), ch->GetX(), ch->GetY());
ch->PointChange(POINT_HP, 50 - ch->GetHP());
ch->DeathPenalty(0);
ch->ReviveInvisible(5);
break;
}
}
#define MAX_STAT 90
ACMD(do_stat_reset)
{
ch->PointChange(POINT_STAT_RESET_COUNT, 12 - ch->GetPoint(POINT_STAT_RESET_COUNT));
}
ACMD(do_stat_minus)
{
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
if (!*arg1)
return;
if (ch->IsPolymorphed())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB5\xD0\xB0\xA9 \xC1\xDF\xBF\xA1\xB4\xC2 \xB4\xC9\xB7\xC2\xC0\xBB \xBF\xC3\xB8\xB1 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
if (ch->GetPoint(POINT_STAT_RESET_COUNT) <= 0)
return;
if (!strcmp(arg1, "st"))
{
if (ch->GetRealPoint(POINT_ST) <= JobInitialPoints[ch->GetJob()].st)
return;
ch->SetRealPoint(POINT_ST, ch->GetRealPoint(POINT_ST) - 1);
ch->SetPoint(POINT_ST, ch->GetPoint(POINT_ST) - 1);
ch->ComputePoints();
ch->PointChange(POINT_ST, 0);
}
else if (!strcmp(arg1, "dx"))
{
if (ch->GetRealPoint(POINT_DX) <= JobInitialPoints[ch->GetJob()].dx)
return;
ch->SetRealPoint(POINT_DX, ch->GetRealPoint(POINT_DX) - 1);
ch->SetPoint(POINT_DX, ch->GetPoint(POINT_DX) - 1);
ch->ComputePoints();
ch->PointChange(POINT_DX, 0);
}
else if (!strcmp(arg1, "ht"))
{
if (ch->GetRealPoint(POINT_HT) <= JobInitialPoints[ch->GetJob()].ht)
return;
ch->SetRealPoint(POINT_HT, ch->GetRealPoint(POINT_HT) - 1);
ch->SetPoint(POINT_HT, ch->GetPoint(POINT_HT) - 1);
ch->ComputePoints();
ch->PointChange(POINT_HT, 0);
ch->PointChange(POINT_MAX_HP, 0);
}
else if (!strcmp(arg1, "iq"))
{
if (ch->GetRealPoint(POINT_IQ) <= JobInitialPoints[ch->GetJob()].iq)
return;
ch->SetRealPoint(POINT_IQ, ch->GetRealPoint(POINT_IQ) - 1);
ch->SetPoint(POINT_IQ, ch->GetPoint(POINT_IQ) - 1);
ch->ComputePoints();
ch->PointChange(POINT_IQ, 0);
ch->PointChange(POINT_MAX_SP, 0);
}
else
return;
ch->PointChange(POINT_STAT, +1);
ch->PointChange(POINT_STAT_RESET_COUNT, -1);
ch->ComputePoints();
}
ACMD(do_stat)
{
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
if (!*arg1)
return;
if (ch->IsPolymorphed())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB5\xD0\xB0\xA9 \xC1\xDF\xBF\xA1\xB4\xC2 \xB4\xC9\xB7\xC2\xC0\xBB \xBF\xC3\xB8\xB1 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
if (ch->GetPoint(POINT_STAT) <= 0)
return;
BYTE idx = 0;
if (!strcmp(arg1, "st"))
idx = POINT_ST;
else if (!strcmp(arg1, "dx"))
idx = POINT_DX;
else if (!strcmp(arg1, "ht"))
idx = POINT_HT;
else if (!strcmp(arg1, "iq"))
idx = POINT_IQ;
else
return;
if (ch->GetRealPoint(idx) >= MAX_STAT)
return;
ch->SetRealPoint(idx, ch->GetRealPoint(idx) + 1);
ch->SetPoint(idx, ch->GetPoint(idx) + 1);
ch->ComputePoints();
ch->PointChange(idx, 0);
if (idx == POINT_IQ)
{
ch->PointChange(POINT_MAX_HP, 0);
}
else if (idx == POINT_HT)
{
ch->PointChange(POINT_MAX_SP, 0);
}
ch->PointChange(POINT_STAT, -1);
ch->ComputePoints();
}
ACMD(do_pvp)
{
if (ch->GetArena() != NULL || CArenaManager::instance().IsArenaMap(ch->GetMapIndex()) == true)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB4\xEB\xB7\xC3\xC0\xE5\xBF\xA1\xBC\xAD \xBB\xE7\xBF\xEB\xC7\xCF\xBD\xC7 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
DWORD vid = 0;
str_to_number(vid, arg1);
LPCHARACTER pkVictim = CHARACTER_MANAGER::instance().Find(vid);
if (!pkVictim)
return;
if (pkVictim->IsNPC())
return;
if (pkVictim->GetArena() != NULL)
{
pkVictim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBB\xF3\xB4\xEB\xB9\xE6\xC0\xCC \xB4\xEB\xB7\xC3\xC1\xDF\xC0\xD4\xB4\xCF\xB4\xD9."));
return;
}
CPVPManager::instance().Insert(ch, pkVictim);
}
ACMD(do_guildskillup)
{
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
if (!*arg1)
return;
if (!ch->GetGuild())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xB1\xE6\xB5\xE5\xBF\xA1 \xBC\xD3\xC7\xD8\xC0\xD6\xC1\xF6 \xBE\xCA\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
CGuild* g = ch->GetGuild();
TGuildMember* gm = g->GetMember(ch->GetPlayerID());
if (gm->grade == GUILD_LEADER_GRADE)
{
DWORD vnum = 0;
str_to_number(vnum, arg1);
g->SkillLevelUp(vnum);
}
else
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xB1\xE6\xB5\xE5 \xBD\xBA\xC5\xB3 \xB7\xB9\xBA\xA7\xC0\xBB \xBA\xAF\xB0\xE6\xC7\xD2 \xB1\xC7\xC7\xD1\xC0\xCC \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
}
}
ACMD(do_skillup)
{
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
if (!*arg1)
return;
DWORD vnum = 0;
str_to_number(vnum, arg1);
if (true == ch->CanUseSkill(vnum))
{
ch->SkillLevelUp(vnum);
}
else
{
switch(vnum)
{
case SKILL_HORSE_WILDATTACK:
case SKILL_HORSE_CHARGE:
case SKILL_HORSE_ESCAPE:
case SKILL_HORSE_WILDATTACK_RANGE:
case SKILL_7_A_ANTI_TANHWAN:
case SKILL_7_B_ANTI_AMSEOP:
case SKILL_7_C_ANTI_SWAERYUNG:
case SKILL_7_D_ANTI_YONGBI:
case SKILL_8_A_ANTI_GIGONGCHAM:
case SKILL_8_B_ANTI_YEONSA:
case SKILL_8_C_ANTI_MAHWAN:
case SKILL_8_D_ANTI_BYEURAK:
case SKILL_ADD_HP:
case SKILL_RESIST_PENETRATE:
ch->SkillLevelUp(vnum);
break;
}
}
}
//
// @version 05/06/20 Bang2ni - 커맨드 처리 Delegate to CHARACTER class
//
ACMD(do_safebox_close)
{
ch->CloseSafebox();
}
//
// @version 05/06/20 Bang2ni - 커맨드 처리 Delegate to CHARACTER class
//
ACMD(do_safebox_password)
{
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
ch->ReqSafeboxLoad(arg1);
}
ACMD(do_safebox_change_password)
{
char arg1[256];
char arg2[256];
two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
if (!*arg1 || strlen(arg1)>6)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xC3\xA2\xB0\xED> \xC0\xDF\xB8\xF8\xB5\xC8 \xBE\xCF\xC8\xA3\xB8\xA6 \xC0\xD4\xB7\xC2\xC7\xCF\xBC\xCC\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
if (!*arg2 || strlen(arg2)>6)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xC3\xA2\xB0\xED> \xC0\xDF\xB8\xF8\xB5\xC8 \xBE\xCF\xC8\xA3\xB8\xA6 \xC0\xD4\xB7\xC2\xC7\xCF\xBC\xCC\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
if (LC_IsBrazil() == true)
{
for (int i = 0; i < 6; ++i)
{
if (arg2[i] == '\0')
break;
if (isalpha(arg2[i]) == false)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xC3\xA2\xB0\xED> \xBA\xF1\xB9\xD0\xB9\xF8\xC8\xA3\xB4\xC2 \xBF\xB5\xB9\xAE\xC0\xDA\xB8\xB8 \xB0\xA1\xB4\xC9\xC7\xD5\xB4\xCF\xB4\xD9."));
return;
}
}
}
TSafeboxChangePasswordPacket p;
p.dwID = ch->GetDesc()->GetAccountTable().id;
strlcpy(p.szOldPassword, arg1, sizeof(p.szOldPassword));
strlcpy(p.szNewPassword, arg2, sizeof(p.szNewPassword));
db_clientdesc->DBPacket(HEADER_GD_SAFEBOX_CHANGE_PASSWORD, ch->GetDesc()->GetHandle(), &p, sizeof(p));
}
ACMD(do_mall_password)
{
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
if (!*arg1 || strlen(arg1) > 6)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xC3\xA2\xB0\xED> \xC0\xDF\xB8\xF8\xB5\xC8 \xBE\xCF\xC8\xA3\xB8\xA6 \xC0\xD4\xB7\xC2\xC7\xCF\xBC\xCC\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
int iPulse = thecore_pulse();
if (ch->GetMall())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xC3\xA2\xB0\xED> \xC3\xA2\xB0\xED\xB0\xA1 \xC0\xCC\xB9\xCC \xBF\xAD\xB7\xC1\xC0\xD6\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
if (iPulse - ch->GetMallLoadTime() < passes_per_sec * 10) // 10초에 한번만 요청 가능
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xC3\xA2\xB0\xED> \xC3\xA2\xB0\xED\xB8\xA6 \xB4\xDD\xC0\xBA\xC1\xF6 10\xC3\xCA \xBE\xC8\xBF\xA1\xB4\xC2 \xBF\xAD \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
ch->SetMallLoadTime(iPulse);
TSafeboxLoadPacket p;
p.dwID = ch->GetDesc()->GetAccountTable().id;
strlcpy(p.szLogin, ch->GetDesc()->GetAccountTable().login, sizeof(p.szLogin));
strlcpy(p.szPassword, arg1, sizeof(p.szPassword));
db_clientdesc->DBPacket(HEADER_GD_MALL_LOAD, ch->GetDesc()->GetHandle(), &p, sizeof(p));
}
ACMD(do_mall_close)
{
if (ch->GetMall())
{
ch->SetMallLoadTime(thecore_pulse());
ch->CloseMall();
ch->Save();
}
}
ACMD(do_ungroup)
{
if (!ch->GetParty())
return;
if (!CPartyManager::instance().IsEnablePCParty())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xC6\xC4\xC6\xBC> \xBC\xAD\xB9\xF6 \xB9\xAE\xC1\xA6\xB7\xCE \xC6\xC4\xC6\xBC \xB0\xFC\xB7\xC3 \xC3\xB3\xB8\xAE\xB8\xA6 \xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
if (ch->GetDungeon())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xC6\xC4\xC6\xBC> \xB4\xF8\xC0\xFC \xBE\xC8\xBF\xA1\xBC\xAD\xB4\xC2 \xC6\xC4\xC6\xBC\xBF\xA1\xBC\xAD \xB3\xAA\xB0\xA5 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
LPPARTY pParty = ch->GetParty();
if (pParty->GetMemberCount() == 2)
{
// party disband
CPartyManager::instance().DeleteParty(pParty);
}
else
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xC6\xC4\xC6\xBC> \xC6\xC4\xC6\xBC\xBF\xA1\xBC\xAD \xB3\xAA\xB0\xA1\xBC\xCC\xBD\xC0\xB4\xCF\xB4\xD9."));
//pParty->SendPartyRemoveOneToAll(ch);
pParty->Quit(ch->GetPlayerID());
//pParty->SendPartyRemoveAllToOne(ch);
}
}
ACMD(do_close_shop)
{
if (ch->GetMyShop())
{
ch->CloseMyShop();
return;
}
}
ACMD(do_set_walk_mode)
{
ch->SetNowWalking(true);
ch->SetWalking(true);
}
ACMD(do_set_run_mode)
{
ch->SetNowWalking(false);
ch->SetWalking(false);
}
ACMD(do_war)
{
//내 길드 정보를 얻어오고
CGuild * g = ch->GetGuild();
if (!g)
return;
//전쟁중인지 체크한번!
if (g->UnderAnyWar())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xC0\xCC\xB9\xCC \xB4\xD9\xB8\xA5 \xC0\xFC\xC0\xEF\xBF\xA1 \xC2\xFC\xC0\xFC \xC1\xDF \xC0\xD4\xB4\xCF\xB4\xD9."));
return;
}
//파라메터를 두배로 나누고
char arg1[256], arg2[256];
int type = GUILD_WAR_TYPE_FIELD;
two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
if (!*arg1)
return;
if (*arg2)
{
str_to_number(type, arg2);
if (type >= GUILD_WAR_TYPE_MAX_NUM)
type = GUILD_WAR_TYPE_FIELD;
}
//길드의 마스터 아이디를 얻어온뒤
DWORD gm_pid = g->GetMasterPID();
//마스터인지 체크(길전은 길드장만이 가능)
if (gm_pid != ch->GetPlayerID())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xB1\xE6\xB5\xE5\xC0\xFC\xBF\xA1 \xB4\xEB\xC7\xD1 \xB1\xC7\xC7\xD1\xC0\xCC \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
//상대 길드를 얻어오고
CGuild * opp_g = CGuildManager::instance().FindGuildByName(arg1);
if (!opp_g)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xB1\xD7\xB7\xB1 \xB1\xE6\xB5\xE5\xB0\xA1 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
//상대길드와의 상태 체크
switch (g->GetGuildWarState(opp_g->GetID()))
{
case GUILD_WAR_NONE:
{
if (opp_g->UnderAnyWar())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xBB\xF3\xB4\xEB\xB9\xE6 \xB1\xE6\xB5\xE5\xB0\xA1 \xC0\xCC\xB9\xCC \xC0\xFC\xC0\xEF \xC1\xDF \xC0\xD4\xB4\xCF\xB4\xD9."));
return;
}
int iWarPrice = KOR_aGuildWarInfo[type].iWarPrice;
if (g->GetGuildMoney() < iWarPrice)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xC0\xFC\xBA\xF1\xB0\xA1 \xBA\xCE\xC1\xB7\xC7\xCF\xBF\xA9 \xB1\xE6\xB5\xE5\xC0\xFC\xC0\xBB \xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
if (opp_g->GetGuildMoney() < iWarPrice)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xBB\xF3\xB4\xEB\xB9\xE6 \xB1\xE6\xB5\xE5\xC0\xC7 \xC0\xFC\xBA\xF1\xB0\xA1 \xBA\xCE\xC1\xB7\xC7\xCF\xBF\xA9 \xB1\xE6\xB5\xE5\xC0\xFC\xC0\xBB \xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
}
break;
case GUILD_WAR_SEND_DECLARE:
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC0\xCC\xB9\xCC \xBC\xB1\xC0\xFC\xC6\xF7\xB0\xED \xC1\xDF\xC0\xCE \xB1\xE6\xB5\xE5\xC0\xD4\xB4\xCF\xB4\xD9."));
return;
}
break;
case GUILD_WAR_RECV_DECLARE:
{
if (opp_g->UnderAnyWar())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xBB\xF3\xB4\xEB\xB9\xE6 \xB1\xE6\xB5\xE5\xB0\xA1 \xC0\xCC\xB9\xCC \xC0\xFC\xC0\xEF \xC1\xDF \xC0\xD4\xB4\xCF\xB4\xD9."));
g->RequestRefuseWar(opp_g->GetID());
return;
}
}
break;
case GUILD_WAR_RESERVE:
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xC0\xCC\xB9\xCC \xC0\xFC\xC0\xEF\xC0\xCC \xBF\xB9\xBE\xE0\xB5\xC8 \xB1\xE6\xB5\xE5 \xC0\xD4\xB4\xCF\xB4\xD9."));
return;
}
break;
case GUILD_WAR_END:
return;
default:
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xC0\xCC\xB9\xCC \xC0\xFC\xC0\xEF \xC1\xDF\xC0\xCE \xB1\xE6\xB5\xE5\xC0\xD4\xB4\xCF\xB4\xD9."));
g->RequestRefuseWar(opp_g->GetID());
return;
}
if (!g->CanStartWar(type))
{
// 길드전을 할 수 있는 조건을 만족하지않는다.
if (g->GetLadderPoint() == 0)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xB7\xB9\xB4\xF5 \xC1\xA1\xBC\xF6\xB0\xA1 \xB8\xF0\xC0\xDA\xB6\xF3\xBC\xAD \xB1\xE6\xB5\xE5\xC0\xFC\xC0\xBB \xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
SPDLOG_DEBUG("GuildWar.StartError.NEED_LADDER_POINT");
}
else if (g->GetMemberCount() < GUILD_WAR_MIN_MEMBER_COUNT)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xB1\xE6\xB5\xE5\xC0\xFC\xC0\xBB \xC7\xCF\xB1\xE2 \xC0\xA7\xC7\xD8\xBC\xB1 \xC3\xD6\xBC\xD2\xC7\xD1 %d\xB8\xED\xC0\xCC \xC0\xD6\xBE\xEE\xBE\xDF \xC7\xD5\xB4\xCF\xB4\xD9."), GUILD_WAR_MIN_MEMBER_COUNT);
SPDLOG_DEBUG("GuildWar.StartError.NEED_MINIMUM_MEMBER[{}]", (int) GUILD_WAR_MIN_MEMBER_COUNT);
}
else
{
SPDLOG_DEBUG("GuildWar.StartError.UNKNOWN_ERROR");
}
return;
}
// 필드전 체크만 하고 세세한 체크는 상대방이 승낙할때 한다.
if (!opp_g->CanStartWar(GUILD_WAR_TYPE_FIELD))
{
if (opp_g->GetLadderPoint() == 0)
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xBB\xF3\xB4\xEB\xB9\xE6 \xB1\xE6\xB5\xE5\xC0\xC7 \xB7\xB9\xB4\xF5 \xC1\xA1\xBC\xF6\xB0\xA1 \xB8\xF0\xC0\xDA\xB6\xF3\xBC\xAD \xB1\xE6\xB5\xE5\xC0\xFC\xC0\xBB \xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
else if (opp_g->GetMemberCount() < GUILD_WAR_MIN_MEMBER_COUNT)
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xBB\xF3\xB4\xEB\xB9\xE6 \xB1\xE6\xB5\xE5\xC0\xC7 \xB1\xE6\xB5\xE5\xBF\xF8 \xBC\xF6\xB0\xA1 \xBA\xCE\xC1\xB7\xC7\xCF\xBF\xA9 \xB1\xE6\xB5\xE5\xC0\xFC\xC0\xBB \xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
do
{
if (g->GetMasterCharacter() != NULL)
break;
CCI *pCCI = P2P_MANAGER::instance().FindByPID(g->GetMasterPID());
if (pCCI != NULL)
break;
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xBB\xF3\xB4\xEB\xB9\xE6 \xB1\xE6\xB5\xE5\xC0\xC7 \xB1\xE6\xB5\xE5\xC0\xE5\xC0\xCC \xC1\xA2\xBC\xD3\xC1\xDF\xC0\xCC \xBE\xC6\xB4\xD5\xB4\xCF\xB4\xD9."));
g->RequestRefuseWar(opp_g->GetID());
return;
} while (false);
do
{
if (opp_g->GetMasterCharacter() != NULL)
break;
CCI *pCCI = P2P_MANAGER::instance().FindByPID(opp_g->GetMasterPID());
if (pCCI != NULL)
break;
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xBB\xF3\xB4\xEB\xB9\xE6 \xB1\xE6\xB5\xE5\xC0\xC7 \xB1\xE6\xB5\xE5\xC0\xE5\xC0\xCC \xC1\xA2\xBC\xD3\xC1\xDF\xC0\xCC \xBE\xC6\xB4\xD5\xB4\xCF\xB4\xD9."));
g->RequestRefuseWar(opp_g->GetID());
return;
} while (false);
g->RequestDeclareWar(opp_g->GetID(), type);
}
ACMD(do_nowar)
{
CGuild* g = ch->GetGuild();
if (!g)
return;
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
if (!*arg1)
return;
DWORD gm_pid = g->GetMasterPID();
if (gm_pid != ch->GetPlayerID())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xB1\xE6\xB5\xE5\xC0\xFC\xBF\xA1 \xB4\xEB\xC7\xD1 \xB1\xC7\xC7\xD1\xC0\xCC \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
CGuild* opp_g = CGuildManager::instance().FindGuildByName(arg1);
if (!opp_g)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xB1\xD7\xB7\xB1 \xB1\xE6\xB5\xE5\xB0\xA1 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
g->RequestRefuseWar(opp_g->GetID());
}
ACMD(do_detaillog)
{
ch->DetailLog();
}
ACMD(do_monsterlog)
{
ch->ToggleMonsterLog();
}
ACMD(do_pkmode)
{
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
if (!*arg1)
return;
BYTE mode = 0;
str_to_number(mode, arg1);
if (mode == PK_MODE_PROTECT)
return;
if (ch->GetLevel() < PK_PROTECT_LEVEL && mode != 0)
return;
ch->SetPKMode(mode);
}
ACMD(do_messenger_auth)
{
if (ch->GetArena())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB4\xEB\xB7\xC3\xC0\xE5\xBF\xA1\xBC\xAD \xBB\xE7\xBF\xEB\xC7\xCF\xBD\xC7 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
char arg1[256], arg2[256];
two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
if (!*arg1 || !*arg2)
return;
char answer = LOWER(*arg1);
if (answer != 'y')
{
LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(arg2);
if (tch)
tch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s \xB4\xD4\xC0\xB8\xB7\xCE \xBA\xCE\xC5\xCD \xC4\xA3\xB1\xB8 \xB5\xEE\xB7\xCF\xC0\xBB \xB0\xC5\xBA\xCE \xB4\xE7\xC7\xDF\xBD\xC0\xB4\xCF\xB4\xD9."), ch->GetName());
}
MessengerManager::instance().AuthToAdd(ch->GetName(), arg2, answer == 'y' ? false : true); // DENY
}
ACMD(do_setblockmode)
{
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
if (*arg1)
{
BYTE flag = 0;
str_to_number(flag, arg1);
ch->SetBlockMode(flag);
}
}
ACMD(do_unmount)
{
if (true == ch->UnEquipSpecialRideUniqueItem())
{
ch->RemoveAffect(AFFECT_MOUNT);
ch->RemoveAffect(AFFECT_MOUNT_BONUS);
if (ch->IsHorseRiding())
{
ch->StopRiding();
}
}
else
{
ch->ChatPacket( CHAT_TYPE_INFO, LC_TEXT("\xC0\xCE\xBA\xA5\xC5\xE4\xB8\xAE\xB0\xA1 \xB2\xCB \xC2\xF7\xBC\xAD \xB3\xBB\xB8\xB1 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
}
}
ACMD(do_observer_exit)
{
if (ch->IsObserverMode())
{
if (ch->GetWarMap())
ch->SetWarMap(NULL);
if (ch->GetArena() != NULL || ch->GetArenaObserverMode() == true)
{
ch->SetArenaObserverMode(false);
if (ch->GetArena() != NULL)
ch->GetArena()->RemoveObserver(ch->GetPlayerID());
ch->SetArena(NULL);
ch->WarpSet(ARENA_RETURN_POINT_X(ch->GetEmpire()), ARENA_RETURN_POINT_Y(ch->GetEmpire()));
}
else
{
ch->ExitToSavedLocation();
}
ch->SetObserverMode(false);
}
}
ACMD(do_view_equip)
{
if (ch->GetGMLevel() <= GM_PLAYER)
return;
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
if (*arg1)
{
DWORD vid = 0;
str_to_number(vid, arg1);
LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(vid);
if (!tch)
return;
if (!tch->IsPC())
return;
/*
int iSPCost = ch->GetMaxSP() / 3;
if (ch->GetSP() < iSPCost)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC1\xA4\xBD\xC5\xB7\xC2\xC0\xCC \xBA\xCE\xC1\xB7\xC7\xCF\xBF\xA9 \xB4\xD9\xB8\xA5 \xBB\xE7\xB6\xF7\xC0\xC7 \xC0\xE5\xBA\xF1\xB8\xA6 \xBA\xBC \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
ch->PointChange(POINT_SP, -iSPCost);
*/
tch->SendEquipment(ch);
}
}
ACMD(do_party_request)
{
if (ch->GetArena())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB4\xEB\xB7\xC3\xC0\xE5\xBF\xA1\xBC\xAD \xBB\xE7\xBF\xEB\xC7\xCF\xBD\xC7 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
if (ch->GetParty())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC0\xCC\xB9\xCC \xC6\xC4\xC6\xBC\xBF\xA1 \xBC\xD3\xC7\xD8 \xC0\xD6\xC0\xB8\xB9\xC7\xB7\xCE \xB0\xA1\xC0\xD4\xBD\xC5\xC3\xBB\xC0\xBB \xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
if (!*arg1)
return;
DWORD vid = 0;
str_to_number(vid, arg1);
LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(vid);
if (tch)
if (!ch->RequestToParty(tch))
ch->ChatPacket(CHAT_TYPE_COMMAND, "PartyRequestDenied");
}
ACMD(do_party_request_accept)
{
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
if (!*arg1)
return;
DWORD vid = 0;
str_to_number(vid, arg1);
LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(vid);
if (tch)
ch->AcceptToParty(tch);
}
ACMD(do_party_request_deny)
{
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
if (!*arg1)
return;
DWORD vid = 0;
str_to_number(vid, arg1);
LPCHARACTER tch = CHARACTER_MANAGER::instance().Find(vid);
if (tch)
ch->DenyToParty(tch);
}
ACMD(do_monarch_warpto)
{
if (true == LC_IsYMIR() || true == LC_IsKorea())
return;
if (!CMonarch::instance().IsMonarch(ch->GetPlayerID(), ch->GetEmpire()))
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB1\xBA\xC1\xD6\xB8\xB8\xC0\xCC \xBB\xE7\xBF\xEB \xB0\xA1\xB4\xC9\xC7\xD1 \xB1\xE2\xB4\xC9\xC0\xD4\xB4\xCF\xB4\xD9"));
return;
}
//군주 쿨타임 검사
if (!ch->IsMCOK(CHARACTER::MI_WARP))
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d \xC3\xCA\xB0\xA3 \xC4\xF0\xC5\xB8\xC0\xD3\xC0\xCC \xC0\xFB\xBF\xEB\xC1\xDF\xC0\xD4\xB4\xCF\xB4\xD9."), ch->GetMCLTime(CHARACTER::MI_WARP));
return;
}
//군주 몹 소환 비용
const int WarpPrice = 10000;
//군주 국고 검사
if (!CMonarch::instance().IsMoneyOk(WarpPrice, ch->GetEmpire()))
{
int NationMoney = CMonarch::instance().GetMoney(ch->GetEmpire());
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB1\xB9\xB0\xED\xBF\xA1 \xB5\xB7\xC0\xCC \xBA\xCE\xC1\xB7\xC7\xD5\xB4\xCF\xB4\xD9. \xC7\xF6\xC0\xE7 : %u \xC7\xCA\xBF\xE4\xB1\xDD\xBE\xD7 : %u"), NationMoney, WarpPrice);
return;
}
int x = 0, y = 0;
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
if (!*arg1)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBB\xE7\xBF\xEB\xB9\xFD: warpto <character name>"));
return;
}
LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(arg1);
if (!tch)
{
CCI * pkCCI = P2P_MANAGER::instance().Find(arg1);
if (pkCCI)
{
if (pkCCI->bEmpire != ch->GetEmpire())
{
ch->ChatPacket (CHAT_TYPE_INFO, LC_TEXT("\xC5\xB8\xC1\xA6\xB1\xB9 \xC0\xAF\xC0\xFA\xBF\xA1\xB0\xD4\xB4\xC2 \xC0\xCC\xB5\xBF\xC7\xD2\xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9"));
return;
}
if (pkCCI->bChannel != g_bChannel)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC7\xD8\xB4\xE7 \xC0\xAF\xC0\xFA\xB4\xC2 %d \xC3\xA4\xB3\xCE\xBF\xA1 \xC0\xD6\xBD\xC0\xB4\xCF\xB4\xD9. (\xC7\xF6\xC0\xE7 \xC3\xA4\xB3\xCE %d)"), pkCCI->bChannel, g_bChannel);
return;
}
if (!IsMonarchWarpZone(pkCCI->lMapIndex))
{
ch->ChatPacket (CHAT_TYPE_INFO, LC_TEXT("\xC7\xD8\xB4\xE7 \xC1\xF6\xBF\xAA\xC0\xB8\xB7\xCE \xC0\xCC\xB5\xBF\xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
PIXEL_POSITION pos;
if (!SECTREE_MANAGER::instance().GetCenterPositionOfMap(pkCCI->lMapIndex, pos))
ch->ChatPacket(CHAT_TYPE_INFO, "Cannot find map (index %d)", pkCCI->lMapIndex);
else
{
//ch->ChatPacket(CHAT_TYPE_INFO, "You warp to (%d, %d)", pos.x, pos.y);
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s \xBF\xA1\xB0\xD4\xB7\xCE \xC0\xCC\xB5\xBF\xC7\xD5\xB4\xCF\xB4\xD9"), arg1);
ch->WarpSet(pos.x, pos.y);
//군주 돈 삭감
CMonarch::instance().SendtoDBDecMoney(WarpPrice, ch->GetEmpire(), ch);
//쿨타임 초기화
ch->SetMC(CHARACTER::MI_WARP);
}
}
else if (NULL == CHARACTER_MANAGER::instance().FindPC(arg1))
{
ch->ChatPacket(CHAT_TYPE_INFO, "There is no one by that name");
}
return;
}
else
{
if (tch->GetEmpire() != ch->GetEmpire())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC5\xB8\xC1\xA6\xB1\xB9 \xC0\xAF\xC0\xFA\xBF\xA1\xB0\xD4\xB4\xC2 \xC0\xCC\xB5\xBF\xC7\xD2\xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9"));
return;
}
if (!IsMonarchWarpZone(tch->GetMapIndex()))
{
ch->ChatPacket (CHAT_TYPE_INFO, LC_TEXT("\xC7\xD8\xB4\xE7 \xC1\xF6\xBF\xAA\xC0\xB8\xB7\xCE \xC0\xCC\xB5\xBF\xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
x = tch->GetX();
y = tch->GetY();
}
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s \xBF\xA1\xB0\xD4\xB7\xCE \xC0\xCC\xB5\xBF\xC7\xD5\xB4\xCF\xB4\xD9"), arg1);
ch->WarpSet(x, y);
ch->Stop();
//군주 돈 삭감
CMonarch::instance().SendtoDBDecMoney(WarpPrice, ch->GetEmpire(), ch);
//쿨타임 초기화
ch->SetMC(CHARACTER::MI_WARP);
}
ACMD(do_monarch_transfer)
{
if (true == LC_IsYMIR() || true == LC_IsKorea())
return;
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
if (!*arg1)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBB\xE7\xBF\xEB\xB9\xFD: transfer <name>"));
return;
}
if (!CMonarch::instance().IsMonarch(ch->GetPlayerID(), ch->GetEmpire()))
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB1\xBA\xC1\xD6\xB8\xB8\xC0\xCC \xBB\xE7\xBF\xEB \xB0\xA1\xB4\xC9\xC7\xD1 \xB1\xE2\xB4\xC9\xC0\xD4\xB4\xCF\xB4\xD9"));
return;
}
//군주 쿨타임 검사
if (!ch->IsMCOK(CHARACTER::MI_TRANSFER))
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d \xC3\xCA\xB0\xA3 \xC4\xF0\xC5\xB8\xC0\xD3\xC0\xCC \xC0\xFB\xBF\xEB\xC1\xDF\xC0\xD4\xB4\xCF\xB4\xD9."), ch->GetMCLTime(CHARACTER::MI_TRANSFER));
return;
}
//군주 워프 비용
const int WarpPrice = 10000;
//군주 국고 검사
if (!CMonarch::instance().IsMoneyOk(WarpPrice, ch->GetEmpire()))
{
int NationMoney = CMonarch::instance().GetMoney(ch->GetEmpire());
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB1\xB9\xB0\xED\xBF\xA1 \xB5\xB7\xC0\xCC \xBA\xCE\xC1\xB7\xC7\xD5\xB4\xCF\xB4\xD9. \xC7\xF6\xC0\xE7 : %u \xC7\xCA\xBF\xE4\xB1\xDD\xBE\xD7 : %u"), NationMoney, WarpPrice);
return;
}
LPCHARACTER tch = CHARACTER_MANAGER::instance().FindPC(arg1);
if (!tch)
{
CCI * pkCCI = P2P_MANAGER::instance().Find(arg1);
if (pkCCI)
{
if (pkCCI->bEmpire != ch->GetEmpire())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB4\xD9\xB8\xA5 \xC1\xA6\xB1\xB9 \xC0\xAF\xC0\xFA\xB4\xC2 \xBC\xD2\xC8\xAF\xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
if (pkCCI->bChannel != g_bChannel)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s \xB4\xD4\xC0\xBA %d \xC3\xA4\xB3\xCE\xBF\xA1 \xC1\xA2\xBC\xD3 \xC1\xDF \xC0\xD4\xB4\xCF\xB4\xD9. (\xC7\xF6\xC0\xE7 \xC3\xA4\xB3\xCE: %d)"), arg1, pkCCI->bChannel, g_bChannel);
return;
}
if (!IsMonarchWarpZone(pkCCI->lMapIndex))
{
ch->ChatPacket (CHAT_TYPE_INFO, LC_TEXT("\xC7\xD8\xB4\xE7 \xC1\xF6\xBF\xAA\xC0\xB8\xB7\xCE \xC0\xCC\xB5\xBF\xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
if (!IsMonarchWarpZone(ch->GetMapIndex()))
{
ch->ChatPacket (CHAT_TYPE_INFO, LC_TEXT("\xC7\xD8\xB4\xE7 \xC1\xF6\xBF\xAA\xC0\xB8\xB7\xCE \xBC\xD2\xC8\xAF\xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
TPacketGGTransfer pgg;
pgg.bHeader = HEADER_GG_TRANSFER;
strlcpy(pgg.szName, arg1, sizeof(pgg.szName));
pgg.lX = ch->GetX();
pgg.lY = ch->GetY();
P2P_MANAGER::instance().Send(&pgg, sizeof(TPacketGGTransfer));
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s \xB4\xD4\xC0\xBB \xBC\xD2\xC8\xAF\xC7\xCF\xBF\xB4\xBD\xC0\xB4\xCF\xB4\xD9."), arg1);
//군주 돈 삭감
CMonarch::instance().SendtoDBDecMoney(WarpPrice, ch->GetEmpire(), ch);
//쿨타임 초기화
ch->SetMC(CHARACTER::MI_TRANSFER);
}
else
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC0\xD4\xB7\xC2\xC7\xCF\xBD\xC5 \xC0\xCC\xB8\xA7\xC0\xBB \xB0\xA1\xC1\xF8 \xBB\xE7\xBF\xEB\xC0\xDA\xB0\xA1 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
}
return;
}
if (ch == tch)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC0\xDA\xBD\xC5\xC0\xBB \xBC\xD2\xC8\xAF\xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
if (tch->GetEmpire() != ch->GetEmpire())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB4\xD9\xB8\xA5 \xC1\xA6\xB1\xB9 \xC0\xAF\xC0\xFA\xB4\xC2 \xBC\xD2\xC8\xAF\xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
if (!IsMonarchWarpZone(tch->GetMapIndex()))
{
ch->ChatPacket (CHAT_TYPE_INFO, LC_TEXT("\xC7\xD8\xB4\xE7 \xC1\xF6\xBF\xAA\xC0\xB8\xB7\xCE \xC0\xCC\xB5\xBF\xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
if (!IsMonarchWarpZone(ch->GetMapIndex()))
{
ch->ChatPacket (CHAT_TYPE_INFO, LC_TEXT("\xC7\xD8\xB4\xE7 \xC1\xF6\xBF\xAA\xC0\xB8\xB7\xCE \xBC\xD2\xC8\xAF\xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."));
return;
}
//tch->Show(ch->GetMapIndex(), ch->GetX(), ch->GetY(), ch->GetZ());
tch->WarpSet(ch->GetX(), ch->GetY(), ch->GetMapIndex());
//군주 돈 삭감
CMonarch::instance().SendtoDBDecMoney(WarpPrice, ch->GetEmpire(), ch);
//쿨타임 초기화
ch->SetMC(CHARACTER::MI_TRANSFER);
}
ACMD(do_monarch_info)
{
if (CMonarch::instance().IsMonarch(ch->GetPlayerID(), ch->GetEmpire()))
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB3\xAA\xC0\xC7 \xB1\xBA\xC1\xD6 \xC1\xA4\xBA\xB8"));
TMonarchInfo * p = CMonarch::instance().GetMonarch();
for (int n = 1; n < 4; ++n)
{
if (n == ch->GetEmpire())
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("[%s\xB1\xBA\xC1\xD6] : %s \xBA\xB8\xC0\xAF\xB1\xDD\xBE\xD7 %lld "), EMPIRE_NAME(n), p->name[n], p->money[n]);
else
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("[%s\xB1\xBA\xC1\xD6] : %s "), EMPIRE_NAME(n), p->name[n]);
}
}
else
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB1\xBA\xC1\xD6 \xC1\xA4\xBA\xB8"));
TMonarchInfo * p = CMonarch::instance().GetMonarch();
for (int n = 1; n < 4; ++n)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("[%s\xB1\xBA\xC1\xD6] : %s "), EMPIRE_NAME(n), p->name[n]);
}
}
}
ACMD(do_elect)
{
db_clientdesc->DBPacketHeader(HEADER_GD_COME_TO_VOTE, ch->GetDesc()->GetHandle(), 0);
}
// LUA_ADD_GOTO_INFO
struct GotoInfo
{
std::string st_name;
BYTE empire;
int mapIndex;
DWORD x, y;
GotoInfo()
{
st_name = "";
empire = 0;
mapIndex = 0;
x = 0;
y = 0;
}
GotoInfo(const GotoInfo& c_src)
{
__copy__(c_src);
}
void operator = (const GotoInfo& c_src)
{
__copy__(c_src);
}
void __copy__(const GotoInfo& c_src)
{
st_name = c_src.st_name;
empire = c_src.empire;
mapIndex = c_src.mapIndex;
x = c_src.x;
y = c_src.y;
}
};
extern void BroadcastNotice(const char * c_pszBuf);
ACMD(do_monarch_tax)
{
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
if (!*arg1)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Usage: monarch_tax <1-50>");
return;
}
// 군주 검사
if (!ch->IsMonarch())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB1\xBA\xC1\xD6\xB8\xB8\xC0\xCC \xBB\xE7\xBF\xEB\xC7\xD2\xBC\xF6 \xC0\xD6\xB4\xC2 \xB1\xE2\xB4\xC9\xC0\xD4\xB4\xCF\xB4\xD9"));
return;
}
// 세금설정
int tax = 0;
str_to_number(tax, arg1);
if (tax < 1 || tax > 50)
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("1-50 \xBB\xE7\xC0\xCC\xC0\xC7 \xBC\xF6\xC4\xA1\xB8\xA6 \xBC\xB1\xC5\xC3\xC7\xD8\xC1\xD6\xBC\xBC\xBF\xE4"));
quest::CQuestManager::instance().SetEventFlag("trade_tax", tax);
// 군주에게 메세지 하나
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBC\xBC\xB1\xDD\xC0\xCC %d %\xB7\xCE \xBC\xB3\xC1\xA4\xB5\xC7\xBE\xFA\xBD\xC0\xB4\xCF\xB4\xD9"));
// 공지
char szMsg[1024];
snprintf(szMsg, sizeof(szMsg), "\xB1\xBA\xC1\xD6\xC0\xC7 \xB8\xED\xC0\xB8\xB7\xCE \xBC\xBC\xB1\xDD\xC0\xCC %d %% \xB7\xCE \xBA\xAF\xB0\xE6\xB5\xC7\xBE\xFA\xBD\xC0\xB4\xCF\xB4\xD9", tax);
BroadcastNotice(szMsg);
snprintf(szMsg, sizeof(szMsg), "\xBE\xD5\xC0\xB8\xB7\xCE\xB4\xC2 \xB0\xC5\xB7\xA1 \xB1\xDD\xBE\xD7\xC0\xC7 %d %% \xB0\xA1 \xB1\xB9\xB0\xED\xB7\xCE \xB5\xE9\xBE\xEE\xB0\xA1\xB0\xD4\xB5\xCB\xB4\xCF\xB4\xD9.", tax);
BroadcastNotice(szMsg);
// 쿨타임 초기화
ch->SetMC(CHARACTER::MI_TAX);
}
static const DWORD cs_dwMonarchMobVnums[] =
{
191, // 산견신
192, // 저신
193, // 웅신
194, // 호신
391, // 미정
392, // 은정
393, // 세랑
394, // 진희
491, // 맹환
492, // 보우
493, // 구패
494, // 추흔
591, // 비류단대장
691, // 웅귀 족장
791, // 밀교교주
1304, // 누렁범귀
1901, // 구미호
2091, // 여왕거미
2191, // 거대사막거북
2206, // 화염왕i
0,
};
ACMD(do_monarch_mob)
{
char arg1[256];
LPCHARACTER tch;
one_argument(argument, arg1, sizeof(arg1));
if (!ch->IsMonarch())
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB1\xBA\xC1\xD6\xB8\xB8\xC0\xCC \xBB\xE7\xBF\xEB\xC7\xD2\xBC\xF6 \xC0\xD6\xB4\xC2 \xB1\xE2\xB4\xC9\xC0\xD4\xB4\xCF\xB4\xD9"));
return;
}
if (!*arg1)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Usage: mmob <mob name>");
return;
}
BYTE pcEmpire = ch->GetEmpire();
BYTE mapEmpire = SECTREE_MANAGER::instance().GetEmpireFromMapIndex(ch->GetMapIndex());
if (LC_IsYMIR() == true || LC_IsKorea() == true)
{
if (mapEmpire != pcEmpire && mapEmpire != 0)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC0\xDA\xB1\xB9 \xBF\xB5\xC5\xE4\xBF\xA1\xBC\xAD\xB8\xB8 \xBB\xE7\xBF\xEB\xC7\xD2 \xBC\xF6 \xC0\xD6\xB4\xC2 \xB1\xE2\xB4\xC9\xC0\xD4\xB4\xCF\xB4\xD9"));
return;
}
}
// 군주 몹 소환 비용
const int SummonPrice = 5000000;
// 군주 쿨타임 검사
if (!ch->IsMCOK(CHARACTER::MI_SUMMON))
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d \xC3\xCA\xB0\xA3 \xC4\xF0\xC5\xB8\xC0\xD3\xC0\xCC \xC0\xFB\xBF\xEB\xC1\xDF\xC0\xD4\xB4\xCF\xB4\xD9."), ch->GetMCLTime(CHARACTER::MI_SUMMON));
return;
}
// 군주 국고 검사
if (!CMonarch::instance().IsMoneyOk(SummonPrice, ch->GetEmpire()))
{
int NationMoney = CMonarch::instance().GetMoney(ch->GetEmpire());
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB1\xB9\xB0\xED\xBF\xA1 \xB5\xB7\xC0\xCC \xBA\xCE\xC1\xB7\xC7\xD5\xB4\xCF\xB4\xD9. \xC7\xF6\xC0\xE7 : %u \xC7\xCA\xBF\xE4\xB1\xDD\xBE\xD7 : %u"), NationMoney, SummonPrice);
return;
}
const CMob * pkMob;
DWORD vnum = 0;
if (isdigit(*arg1))
{
str_to_number(vnum, arg1);
if ((pkMob = CMobManager::instance().Get(vnum)) == NULL)
vnum = 0;
}
else
{
pkMob = CMobManager::Instance().Get(arg1, true);
if (pkMob)
vnum = pkMob->m_table.dwVnum;
}
DWORD count;
// 소환 가능 몹 검사
for (count = 0; cs_dwMonarchMobVnums[count] != 0; ++count)
if (cs_dwMonarchMobVnums[count] == vnum)
break;
if (0 == cs_dwMonarchMobVnums[count])
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBC\xD2\xC8\xAF\xC7\xD2\xBC\xF6 \xBE\xF8\xB4\xC2 \xB8\xF3\xBD\xBA\xC5\xCD \xC0\xD4\xB4\xCF\xB4\xD9. \xBC\xD2\xC8\xAF\xB0\xA1\xB4\xC9\xC7\xD1 \xB8\xF3\xBD\xBA\xC5\xCD\xB4\xC2 \xC8\xA8\xC6\xE4\xC0\xCC\xC1\xF6\xB8\xA6 \xC2\xFC\xC1\xB6\xC7\xCF\xBC\xBC\xBF\xE4"));
return;
}
tch = CHARACTER_MANAGER::instance().SpawnMobRange(vnum,
ch->GetMapIndex(),
ch->GetX() - Random::get(200, 750),
ch->GetY() - Random::get(200, 750),
ch->GetX() + Random::get(200, 750),
ch->GetY() + Random::get(200, 750),
true,
pkMob->m_table.bType == CHAR_TYPE_STONE,
true);
if (tch)
{
// 군주 돈 삭감
CMonarch::instance().SendtoDBDecMoney(SummonPrice, ch->GetEmpire(), ch);
// 쿨타임 초기화
ch->SetMC(CHARACTER::MI_SUMMON);
}
}
static const char* FN_point_string(int apply_number)
{
switch (apply_number)
{
case POINT_MAX_HP: return LC_TEXT("\xC3\xD6\xB4\xEB \xBB\xFD\xB8\xED\xB7\xC2 +%d");
case POINT_MAX_SP: return LC_TEXT("\xC3\xD6\xB4\xEB \xC1\xA4\xBD\xC5\xB7\xC2 +%d");
case POINT_HT: return LC_TEXT("\xC3\xBC\xB7\xC2 +%d");
case POINT_IQ: return LC_TEXT("\xC1\xF6\xB4\xC9 +%d");
case POINT_ST: return LC_TEXT("\xB1\xD9\xB7\xC2 +%d");
case POINT_DX: return LC_TEXT("\xB9\xCE\xC3\xB8 +%d");
case POINT_ATT_SPEED: return LC_TEXT("\xB0\xF8\xB0\xDD\xBC\xD3\xB5\xB5 +%d");
case POINT_MOV_SPEED: return LC_TEXT("\xC0\xCC\xB5\xBF\xBC\xD3\xB5\xB5 %d");
case POINT_CASTING_SPEED: return LC_TEXT("\xC4\xF0\xC5\xB8\xC0\xD3 -%d");
case POINT_HP_REGEN: return LC_TEXT("\xBB\xFD\xB8\xED\xB7\xC2 \xC8\xB8\xBA\xB9 +%d");
case POINT_SP_REGEN: return LC_TEXT("\xC1\xA4\xBD\xC5\xB7\xC2 \xC8\xB8\xBA\xB9 +%d");
case POINT_POISON_PCT: return LC_TEXT("\xB5\xB6\xB0\xF8\xB0\xDD %d");
case POINT_STUN_PCT: return LC_TEXT("\xBD\xBA\xC5\xCF +%d");
case POINT_SLOW_PCT: return LC_TEXT("\xBD\xBD\xB7\xCE\xBF\xEC +%d");
case POINT_CRITICAL_PCT: return LC_TEXT("%d%% \xC8\xAE\xB7\xFC\xB7\xCE \xC4\xA1\xB8\xED\xC5\xB8 \xB0\xF8\xB0\xDD");
case POINT_RESIST_CRITICAL: return LC_TEXT("\xBB\xF3\xB4\xEB\xC0\xC7 \xC4\xA1\xB8\xED\xC5\xB8 \xC8\xAE\xB7\xFC %d%% \xB0\xA8\xBC\xD2");
case POINT_PENETRATE_PCT: return LC_TEXT("%d%% \xC8\xAE\xB7\xFC\xB7\xCE \xB0\xFC\xC5\xEB \xB0\xF8\xB0\xDD");
case POINT_RESIST_PENETRATE: return LC_TEXT("\xBB\xF3\xB4\xEB\xC0\xC7 \xB0\xFC\xC5\xEB \xB0\xF8\xB0\xDD \xC8\xAE\xB7\xFC %d%% \xB0\xA8\xBC\xD2");
case POINT_ATTBONUS_HUMAN: return LC_TEXT("\xC0\xCE\xB0\xA3\xB7\xF9 \xB8\xF3\xBD\xBA\xC5\xCD \xC5\xB8\xB0\xDD\xC4\xA1 +%d%%");
case POINT_ATTBONUS_ANIMAL: return LC_TEXT("\xB5\xBF\xB9\xB0\xB7\xF9 \xB8\xF3\xBD\xBA\xC5\xCD \xC5\xB8\xB0\xDD\xC4\xA1 +%d%%");
case POINT_ATTBONUS_ORC: return LC_TEXT("\xBF\xF5\xB1\xCD\xC1\xB7 \xC5\xB8\xB0\xDD\xC4\xA1 +%d%%");
case POINT_ATTBONUS_MILGYO: return LC_TEXT("\xB9\xD0\xB1\xB3\xB7\xF9 \xC5\xB8\xB0\xDD\xC4\xA1 +%d%%");
case POINT_ATTBONUS_UNDEAD: return LC_TEXT("\xBD\xC3\xC3\xBC\xB7\xF9 \xC5\xB8\xB0\xDD\xC4\xA1 +%d%%");
case POINT_ATTBONUS_DEVIL: return LC_TEXT("\xBE\xC7\xB8\xB6\xB7\xF9 \xC5\xB8\xB0\xDD\xC4\xA1 +%d%%");
case POINT_STEAL_HP: return LC_TEXT("\xC5\xB8\xB0\xDD\xC4\xA1 %d%% \xB8\xA6 \xBB\xFD\xB8\xED\xB7\xC2\xC0\xB8\xB7\xCE \xC8\xED\xBC\xF6");
case POINT_STEAL_SP: return LC_TEXT("\xC5\xB8\xB7\xC2\xC4\xA1 %d%% \xB8\xA6 \xC1\xA4\xBD\xC5\xB7\xC2\xC0\xB8\xB7\xCE \xC8\xED\xBC\xF6");
case POINT_MANA_BURN_PCT: return LC_TEXT("%d%% \xC8\xAE\xB7\xFC\xB7\xCE \xC5\xB8\xB0\xDD\xBD\xC3 \xBB\xF3\xB4\xEB \xC0\xFC\xBD\xC5\xB7\xC2 \xBC\xD2\xB8\xF0");
case POINT_DAMAGE_SP_RECOVER: return LC_TEXT("%d%% \xC8\xAE\xB7\xFC\xB7\xCE \xC7\xC7\xC7\xD8\xBD\xC3 \xC1\xA4\xBD\xC5\xB7\xC2 \xC8\xB8\xBA\xB9");
case POINT_BLOCK: return LC_TEXT("\xB9\xB0\xB8\xAE\xC5\xB8\xB0\xDD\xBD\xC3 \xBA\xED\xB7\xB0 \xC8\xAE\xB7\xFC %d%%");
case POINT_DODGE: return LC_TEXT("\xC8\xB0 \xB0\xF8\xB0\xDD \xC8\xB8\xC7\xC7 \xC8\xAE\xB7\xFC %d%%");
case POINT_RESIST_SWORD: return LC_TEXT("\xC7\xD1\xBC\xD5\xB0\xCB \xB9\xE6\xBE\xEE %d%%");
case POINT_RESIST_TWOHAND: return LC_TEXT("\xBE\xE7\xBC\xD5\xB0\xCB \xB9\xE6\xBE\xEE %d%%");
case POINT_RESIST_DAGGER: return LC_TEXT("\xB5\xCE\xBC\xD5\xB0\xCB \xB9\xE6\xBE\xEE %d%%");
case POINT_RESIST_BELL: return LC_TEXT("\xB9\xE6\xBF\xEF \xB9\xE6\xBE\xEE %d%%");
case POINT_RESIST_FAN: return LC_TEXT("\xBA\xCE\xC3\xA4 \xB9\xE6\xBE\xEE %d%%");
case POINT_RESIST_BOW: return LC_TEXT("\xC8\xB0\xB0\xF8\xB0\xDD \xC0\xFA\xC7\xD7 %d%%");
case POINT_RESIST_FIRE: return LC_TEXT("\xC8\xAD\xBF\xB0 \xC0\xFA\xC7\xD7 %d%%");
case POINT_RESIST_ELEC: return LC_TEXT("\xC0\xFC\xB1\xE2 \xC0\xFA\xC7\xD7 %d%%");
case POINT_RESIST_MAGIC: return LC_TEXT("\xB8\xB6\xB9\xFD \xC0\xFA\xC7\xD7 %d%%");
case POINT_RESIST_WIND: return LC_TEXT("\xB9\xD9\xB6\xF7 \xC0\xFA\xC7\xD7 %d%%");
case POINT_RESIST_ICE: return LC_TEXT("\xB3\xC3\xB1\xE2 \xC0\xFA\xC7\xD7 %d%%");
case POINT_RESIST_EARTH: return LC_TEXT("\xB4\xEB\xC1\xF6 \xC0\xFA\xC7\xD7 %d%%");
case POINT_RESIST_DARK: return LC_TEXT("\xBE\xEE\xB5\xD2 \xC0\xFA\xC7\xD7 %d%%");
case POINT_REFLECT_MELEE: return LC_TEXT("\xC1\xF7\xC1\xA2 \xC5\xB8\xB0\xDD\xC4\xA1 \xB9\xDD\xBB\xE7 \xC8\xAE\xB7\xFC : %d%%");
case POINT_REFLECT_CURSE: return LC_TEXT("\xC0\xFA\xC1\xD6 \xB5\xC7\xB5\xB9\xB8\xAE\xB1\xE2 \xC8\xAE\xB7\xFC %d%%");
case POINT_POISON_REDUCE: return LC_TEXT("\xB5\xB6 \xC0\xFA\xC7\xD7 %d%%");
case POINT_KILL_SP_RECOVER: return LC_TEXT("%d%% \xC8\xAE\xB7\xFC\xB7\xCE \xC0\xFB\xC5\xF0\xC4\xA1\xBD\xC3 \xC1\xA4\xBD\xC5\xB7\xC2 \xC8\xB8\xBA\xB9");
case POINT_EXP_DOUBLE_BONUS: return LC_TEXT("%d%% \xC8\xAE\xB7\xFC\xB7\xCE \xC0\xFB\xC5\xF0\xC4\xA1\xBD\xC3 \xB0\xE6\xC7\xE8\xC4\xA1 \xC3\xDF\xB0\xA1 \xBB\xF3\xBD\xC2");
case POINT_GOLD_DOUBLE_BONUS: return LC_TEXT("%d%% \xC8\xAE\xB7\xFC\xB7\xCE \xC0\xFB\xC5\xF0\xC4\xA1\xBD\xC3 \xB5\xB7 2\xB9\xE8 \xB5\xE5\xB7\xD3");
case POINT_ITEM_DROP_BONUS: return LC_TEXT("%d%% \xC8\xAE\xB7\xFC\xB7\xCE \xC0\xFB\xC5\xF0\xC4\xA1\xBD\xC3 \xBE\xC6\xC0\xCC\xC5\xDB 2\xB9\xE8 \xB5\xE5\xB7\xD3");
case POINT_POTION_BONUS: return LC_TEXT("\xB9\xB0\xBE\xE0 \xBB\xE7\xBF\xEB\xBD\xC3 %d%% \xBC\xBA\xB4\xC9 \xC1\xF5\xB0\xA1");
case POINT_KILL_HP_RECOVERY: return LC_TEXT("%d%% \xC8\xAE\xB7\xFC\xB7\xCE \xC0\xFB\xC5\xF0\xC4\xA1\xBD\xC3 \xBB\xFD\xB8\xED\xB7\xC2 \xC8\xB8\xBA\xB9");
// case POINT_IMMUNE_STUN: return LC_TEXT("\xB1\xE2\xC0\xFD\xC7\xCF\xC1\xF6 \xBE\xCA\xC0\xBD %d%%");
// case POINT_IMMUNE_SLOW: return LC_TEXT("\xB4\xC0\xB7\xC1\xC1\xF6\xC1\xF6 \xBE\xCA\xC0\xBD %d%%");
// case POINT_IMMUNE_FALL: return LC_TEXT("\xB3\xD1\xBE\xEE\xC1\xF6\xC1\xF6 \xBE\xCA\xC0\xBD %d%%");
// case POINT_SKILL: return LC_TEXT("");
// case POINT_BOW_DISTANCE: return LC_TEXT("");
case POINT_ATT_GRADE_BONUS: return LC_TEXT("\xB0\xF8\xB0\xDD\xB7\xC2 +%d");
case POINT_DEF_GRADE_BONUS: return LC_TEXT("\xB9\xE6\xBE\xEE\xB7\xC2 +%d");
case POINT_MAGIC_ATT_GRADE: return LC_TEXT("\xB8\xB6\xB9\xFD \xB0\xF8\xB0\xDD\xB7\xC2 +%d");
case POINT_MAGIC_DEF_GRADE: return LC_TEXT("\xB8\xB6\xB9\xFD \xB9\xE6\xBE\xEE\xB7\xC2 +%d");
// case POINT_CURSE_PCT: return LC_TEXT("");
case POINT_MAX_STAMINA: return LC_TEXT("\xC3\xD6\xB4\xEB \xC1\xF6\xB1\xB8\xB7\xC2 +%d");
case POINT_ATTBONUS_WARRIOR: return LC_TEXT("\xB9\xAB\xBB\xE7\xBF\xA1\xB0\xD4 \xB0\xAD\xC7\xD4 +%d%%");
case POINT_ATTBONUS_ASSASSIN: return LC_TEXT("\xC0\xDA\xB0\xB4\xBF\xA1\xB0\xD4 \xB0\xAD\xC7\xD4 +%d%%");
case POINT_ATTBONUS_SURA: return LC_TEXT("\xBC\xF6\xB6\xF3\xBF\xA1\xB0\xD4 \xB0\xAD\xC7\xD4 +%d%%");
case POINT_ATTBONUS_SHAMAN: return LC_TEXT("\xB9\xAB\xB4\xE7\xBF\xA1\xB0\xD4 \xB0\xAD\xC7\xD4 +%d%%");
case POINT_ATTBONUS_MONSTER: return LC_TEXT("\xB8\xF3\xBD\xBA\xC5\xCD\xBF\xA1\xB0\xD4 \xB0\xAD\xC7\xD4 +%d%%");
case POINT_MALL_ATTBONUS: return LC_TEXT("\xB0\xF8\xB0\xDD\xB7\xC2 +%d%%");
case POINT_MALL_DEFBONUS: return LC_TEXT("\xB9\xE6\xBE\xEE\xB7\xC2 +%d%%");
case POINT_MALL_EXPBONUS: return LC_TEXT("\xB0\xE6\xC7\xE8\xC4\xA1 %d%%");
case POINT_MALL_ITEMBONUS: return LC_TEXT("\xBE\xC6\xC0\xCC\xC5\xDB \xB5\xE5\xB7\xD3\xC0\xB2 %.1f\xB9\xE8");
case POINT_MALL_GOLDBONUS: return LC_TEXT("\xB5\xB7 \xB5\xE5\xB7\xD3\xC0\xB2 %.1f\xB9\xE8");
case POINT_MAX_HP_PCT: return LC_TEXT("\xC3\xD6\xB4\xEB \xBB\xFD\xB8\xED\xB7\xC2 +%d%%");
case POINT_MAX_SP_PCT: return LC_TEXT("\xC3\xD6\xB4\xEB \xC1\xA4\xBD\xC5\xB7\xC2 +%d%%");
case POINT_SKILL_DAMAGE_BONUS: return LC_TEXT("\xBD\xBA\xC5\xB3 \xB5\xA5\xB9\xCC\xC1\xF6 %d%%");
case POINT_NORMAL_HIT_DAMAGE_BONUS: return LC_TEXT("\xC6\xF2\xC5\xB8 \xB5\xA5\xB9\xCC\xC1\xF6 %d%%");
case POINT_SKILL_DEFEND_BONUS: return LC_TEXT("\xBD\xBA\xC5\xB3 \xB5\xA5\xB9\xCC\xC1\xF6 \xC0\xFA\xC7\xD7 %d%%");
case POINT_NORMAL_HIT_DEFEND_BONUS: return LC_TEXT("\xC6\xF2\xC5\xB8 \xB5\xA5\xB9\xCC\xC1\xF6 \xC0\xFA\xC7\xD7 %d%%");
// case POINT_PC_BANG_EXP_BONUS: return LC_TEXT("");
// case POINT_PC_BANG_DROP_BONUS: return LC_TEXT("");
// case POINT_EXTRACT_HP_PCT: return LC_TEXT("");
case POINT_RESIST_WARRIOR: return LC_TEXT("\xB9\xAB\xBB\xE7\xB0\xF8\xB0\xDD\xBF\xA1 %d%% \xC0\xFA\xC7\xD7");
case POINT_RESIST_ASSASSIN: return LC_TEXT("\xC0\xDA\xB0\xB4\xB0\xF8\xB0\xDD\xBF\xA1 %d%% \xC0\xFA\xC7\xD7");
case POINT_RESIST_SURA: return LC_TEXT("\xBC\xF6\xB6\xF3\xB0\xF8\xB0\xDD\xBF\xA1 %d%% \xC0\xFA\xC7\xD7");
case POINT_RESIST_SHAMAN: return LC_TEXT("\xB9\xAB\xB4\xE7\xB0\xF8\xB0\xDD\xBF\xA1 %d%% \xC0\xFA\xC7\xD7");
default: return NULL;
}
}
static bool FN_hair_affect_string(LPCHARACTER ch, char *buf, size_t bufsiz)
{
if (NULL == ch || NULL == buf)
return false;
CAffect* aff = NULL;
time_t expire = 0;
struct tm ltm;
int year, mon, day;
int offset = 0;
aff = ch->FindAffect(AFFECT_HAIR);
if (NULL == aff)
return false;
expire = ch->GetQuestFlag("hair.limit_time");
if (expire < get_global_time())
return false;
// set apply string
offset = snprintf(buf, bufsiz, FN_point_string(aff->bApplyOn), aff->lApplyValue);
if (offset < 0 || offset >= (int) bufsiz)
offset = bufsiz - 1;
localtime_r(&expire, &ltm);
year = ltm.tm_year + 1900;
mon = ltm.tm_mon + 1;
day = ltm.tm_mday;
snprintf(buf + offset, bufsiz - offset, LC_TEXT(" (\xB8\xB8\xB7\xE1\xC0\xCF : %d\xB3\xE2 %d\xBF\xF9 %d\xC0\xCF)"), year, mon, day);
return true;
}
ACMD(do_costume)
{
char buf[512];
const size_t bufferSize = sizeof(buf);
char arg1[256];
one_argument(argument, arg1, sizeof(arg1));
CItem* pBody = ch->GetWear(WEAR_COSTUME_BODY);
CItem* pHair = ch->GetWear(WEAR_COSTUME_HAIR);
ch->ChatPacket(CHAT_TYPE_INFO, "COSTUME status:");
if (pHair)
{
const char* itemName = pHair->GetName();
ch->ChatPacket(CHAT_TYPE_INFO, " HAIR : %s", itemName);
for (int i = 0; i < pHair->GetAttributeCount(); ++i)
{
const TPlayerItemAttribute& attr = pHair->GetAttribute(i);
if (0 < attr.bType)
{
snprintf(buf, bufferSize, FN_point_string(attr.bType), attr.sValue);
ch->ChatPacket(CHAT_TYPE_INFO, " %s", buf);
}
}
if (pHair->IsEquipped() && arg1[0] == 'h')
ch->UnequipItem(pHair);
}
if (pBody)
{
const char* itemName = pBody->GetName();
ch->ChatPacket(CHAT_TYPE_INFO, " BODY : %s", itemName);
if (pBody->IsEquipped() && arg1[0] == 'b')
ch->UnequipItem(pBody);
}
}
ACMD(do_hair)
{
char buf[256];
if (false == FN_hair_affect_string(ch, buf, sizeof(buf)))
return;
ch->ChatPacket(CHAT_TYPE_INFO, buf);
}
ACMD(do_inventory)
{
int index = 0;
int count = 1;
char arg1[256];
char arg2[256];
LPITEM item;
two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
if (!*arg1)
{
ch->ChatPacket(CHAT_TYPE_INFO, "Usage: inventory <start_index> <count>");
return;
}
if (!*arg2)
{
index = 0;
str_to_number(count, arg1);
}
else
{
str_to_number(index, arg1); index = std::min<int>(index, INVENTORY_MAX_NUM);
str_to_number(count, arg2); count = std::min<int>(count, INVENTORY_MAX_NUM);
}
for (int i = 0; i < count; ++i)
{
if (index >= INVENTORY_MAX_NUM)
break;
item = ch->GetInventoryItem(index);
ch->ChatPacket(CHAT_TYPE_INFO, "inventory [%d] = %s",
index, item ? item->GetName() : "<NONE>");
++index;
}
}
//gift notify quest command
ACMD(do_gift)
{
ch->ChatPacket(CHAT_TYPE_COMMAND, "gift");
}
ACMD(do_cube)
{
if (!ch->CanDoCube())
return;
SPDLOG_TRACE("CUBE COMMAND <{}>: {}", ch->GetName(), argument);
int cube_index = 0, inven_index = 0;
const char *line;
char arg1[256], arg2[256], arg3[256];
line = two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
one_argument(line, arg3, sizeof(arg3));
if (0 == arg1[0])
{
// print usage
ch->ChatPacket(CHAT_TYPE_INFO, "Usage: cube open");
ch->ChatPacket(CHAT_TYPE_INFO, " cube close");
ch->ChatPacket(CHAT_TYPE_INFO, " cube add <inveltory_index>");
ch->ChatPacket(CHAT_TYPE_INFO, " cube delete <cube_index>");
ch->ChatPacket(CHAT_TYPE_INFO, " cube list");
ch->ChatPacket(CHAT_TYPE_INFO, " cube cancel");
ch->ChatPacket(CHAT_TYPE_INFO, " cube make [all]");
return;
}
const std::string& strArg1 = std::string(arg1);
// r_info (request information)
// /cube r_info ==> (Client -> Server) 현재 NPC가 만들 수 있는 레시피 요청
// (Server -> Client) /cube r_list npcVNUM resultCOUNT 123,1/125,1/128,1/130,5
//
// /cube r_info 3 ==> (Client -> Server) 현재 NPC가 만들수 있는 레시피 중 3번째 아이템을 만드는 데 필요한 정보를 요청
// /cube r_info 3 5 ==> (Client -> Server) 현재 NPC가 만들수 있는 레시피 중 3번째 아이템부터 이후 5개의 아이템을 만드는 데 필요한 재료 정보를 요청
// (Server -> Client) /cube m_info startIndex count 125,1|126,2|127,2|123,5&555,5&555,4/120000@125,1|126,2|127,2|123,5&555,5&555,4/120000
//
if (strArg1 == "r_info")
{
if (0 == arg2[0])
Cube_request_result_list(ch);
else
{
if (isdigit(*arg2))
{
int listIndex = 0, requestCount = 1;
str_to_number(listIndex, arg2);
if (0 != arg3[0] && isdigit(*arg3))
str_to_number(requestCount, arg3);
Cube_request_material_info(ch, listIndex, requestCount);
}
}
return;
}
switch (LOWER(arg1[0]))
{
case 'o': // open
Cube_open(ch);
break;
case 'c': // close
Cube_close(ch);
break;
case 'l': // list
Cube_show_list(ch);
break;
case 'a': // add cue_index inven_index
{
if (0 == arg2[0] || !isdigit(*arg2) ||
0 == arg3[0] || !isdigit(*arg3))
return;
str_to_number(cube_index, arg2);
str_to_number(inven_index, arg3);
Cube_add_item (ch, cube_index, inven_index);
}
break;
case 'd': // delete
{
if (0 == arg2[0] || !isdigit(*arg2))
return;
str_to_number(cube_index, arg2);
Cube_delete_item (ch, cube_index);
}
break;
case 'm': // make
if (0 != arg2[0])
{
while (true == Cube_make(ch))
SPDLOG_TRACE("cube make success");
}
else
Cube_make(ch);
break;
default:
return;
}
}
ACMD(do_in_game_mall)
{
if (LC_IsYMIR() == true || LC_IsKorea() == true)
{
ch->ChatPacket(CHAT_TYPE_COMMAND, "mall http://metin2.co.kr/04_mall/mall/login.htm");
return;
}
if (true == LC_IsTaiwan())
{
ch->ChatPacket(CHAT_TYPE_COMMAND, "mall http://203.69.141.203/mall/mall/item_main.htm");
return;
}
// ㅠ_ㅠ 쾌도서버 아이템몰 URL 하드코딩 추가
if (true == LC_IsWE_Korea())
{
ch->ChatPacket(CHAT_TYPE_COMMAND, "mall http://metin2.co.kr/50_we_mall/mall/login.htm");
return;
}
if (LC_IsJapan() == true)
{
ch->ChatPacket(CHAT_TYPE_COMMAND, "mall http://mt2.oge.jp/itemmall/itemList.php");
return;
}
if (LC_IsNewCIBN() == true && test_server)
{
ch->ChatPacket(CHAT_TYPE_COMMAND, "mall http://218.99.6.51/04_mall/mall/login.htm");
return;
}
if (LC_IsSingapore() == true)
{
ch->ChatPacket(CHAT_TYPE_COMMAND, "mall http://www.metin2.sg/ishop.php");
return;
}
/*
if (LC_IsCanada() == true)
{
ch->ChatPacket(CHAT_TYPE_COMMAND, "mall http://mall.z8games.com/mall_entry.aspx?tb=m2");
return;
}*/
if (LC_IsEurope() == true)
{
char country_code[3];
switch (LC_GetLocalType())
{
case LC_GERMANY: country_code[0] = 'd'; country_code[1] = 'e'; country_code[2] = '\0'; break;
case LC_FRANCE: country_code[0] = 'f'; country_code[1] = 'r'; country_code[2] = '\0'; break;
case LC_ITALY: country_code[0] = 'i'; country_code[1] = 't'; country_code[2] = '\0'; break;
case LC_SPAIN: country_code[0] = 'e'; country_code[1] = 's'; country_code[2] = '\0'; break;
case LC_UK: country_code[0] = 'e'; country_code[1] = 'n'; country_code[2] = '\0'; break;
case LC_TURKEY: country_code[0] = 't'; country_code[1] = 'r'; country_code[2] = '\0'; break;
case LC_POLAND: country_code[0] = 'p'; country_code[1] = 'l'; country_code[2] = '\0'; break;
case LC_PORTUGAL: country_code[0] = 'p'; country_code[1] = 't'; country_code[2] = '\0'; break;
case LC_GREEK: country_code[0] = 'g'; country_code[1] = 'r'; country_code[2] = '\0'; break;
case LC_RUSSIA: country_code[0] = 'r'; country_code[1] = 'u'; country_code[2] = '\0'; break;
case LC_DENMARK: country_code[0] = 'd'; country_code[1] = 'k'; country_code[2] = '\0'; break;
case LC_BULGARIA: country_code[0] = 'b'; country_code[1] = 'g'; country_code[2] = '\0'; break;
case LC_CROATIA: country_code[0] = 'h'; country_code[1] = 'r'; country_code[2] = '\0'; break;
case LC_MEXICO: country_code[0] = 'm'; country_code[1] = 'x'; country_code[2] = '\0'; break;
case LC_ARABIA: country_code[0] = 'a'; country_code[1] = 'e'; country_code[2] = '\0'; break;
case LC_CZECH: country_code[0] = 'c'; country_code[1] = 'z'; country_code[2] = '\0'; break;
case LC_ROMANIA: country_code[0] = 'r'; country_code[1] = 'o'; country_code[2] = '\0'; break;
case LC_HUNGARY: country_code[0] = 'h'; country_code[1] = 'u'; country_code[2] = '\0'; break;
case LC_NETHERLANDS: country_code[0] = 'n'; country_code[1] = 'l'; country_code[2] = '\0'; break;
case LC_USA: country_code[0] = 'u'; country_code[1] = 's'; country_code[2] = '\0'; break;
case LC_CANADA: country_code[0] = 'c'; country_code[1] = 'a'; country_code[2] = '\0'; break;
default:
if (test_server == true)
{
country_code[0] = 'd'; country_code[1] = 'e'; country_code[2] = '\0';
}
break;
}
char buf[512+1];
snprintf(buf, sizeof(buf), "mall http://%s/ishop?pid=%u&c=%s&sid=%d",
g_strWebMallURL.c_str(), ch->GetPlayerID(), country_code, g_server_id);
ch->ChatPacket(CHAT_TYPE_COMMAND, buf);
}
}
// 주사위
ACMD(do_dice)
{
char arg1[256], arg2[256];
int start = 1, end = 100;
two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
if (*arg1 && *arg2)
{
start = atoi(arg1);
end = atoi(arg2);
}
else if (*arg1 && !*arg2)
{
start = 1;
end = atoi(arg1);
}
end = std::max(start, end);
start = std::min(start, end);
int n = Random::get(start, end);
if (ch->GetParty())
ch->GetParty()->ChatPacketToAllMember(CHAT_TYPE_INFO, LC_TEXT("%s\xB4\xD4\xC0\xCC \xC1\xD6\xBB\xE7\xC0\xA7\xB8\xA6 \xB1\xBC\xB7\xC1 %d\xB0\xA1 \xB3\xAA\xBF\xD4\xBD\xC0\xB4\xCF\xB4\xD9. (%d-%d)"), ch->GetName(), n, start, end);
else
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB4\xE7\xBD\xC5\xC0\xCC \xC1\xD6\xBB\xE7\xC0\xA7\xB8\xA6 \xB1\xBC\xB7\xC1 %d\xB0\xA1 \xB3\xAA\xBF\xD4\xBD\xC0\xB4\xCF\xB4\xD9. (%d-%d)"), n, start, end);
}
ACMD(do_click_mall)
{
ch->ChatPacket(CHAT_TYPE_COMMAND, "ShowMeMallPassword");
}
ACMD(do_ride)
{
SPDLOG_TRACE("[DO_RIDE] start");
if (ch->IsDead() || ch->IsStun())
return;
// 내리기
{
if (ch->IsHorseRiding())
{
SPDLOG_TRACE("[DO_RIDE] stop riding");
ch->StopRiding();
return;
}
if (ch->GetMountVnum())
{
SPDLOG_TRACE("[DO_RIDE] unmount");
do_unmount(ch, NULL, 0, 0);
return;
}
}
// 타기
{
if (ch->GetHorse() != NULL)
{
SPDLOG_TRACE("[DO_RIDE] start riding");
ch->StartRiding();
return;
}
for (BYTE i=0; i<INVENTORY_MAX_NUM; ++i)
{
LPITEM item = ch->GetInventoryItem(i);
if (NULL == item)
continue;
// 유니크 탈것 아이템
if (item->IsRideItem())
{
if (NULL==ch->GetWear(WEAR_UNIQUE1) || NULL==ch->GetWear(WEAR_UNIQUE2))
{
SPDLOG_TRACE("[DO_RIDE] USE UNIQUE ITEM");
//ch->EquipItem(item);
ch->UseItem(TItemPos (INVENTORY, i));
return;
}
}
// 일반 탈것 아이템
// TODO : 탈것용 SubType 추가
switch (item->GetVnum())
{
case 71114: // 저신이용권
case 71116: // 산견신이용권
case 71118: // 투지범이용권
case 71120: // 사자왕이용권
SPDLOG_TRACE("[DO_RIDE] USE QUEST ITEM");
ch->UseItem(TItemPos (INVENTORY, i));
return;
}
// GF mantis #113524, 52001~52090 번 탈것
if( (item->GetVnum() > 52000) && (item->GetVnum() < 52091) ) {
SPDLOG_TRACE("[DO_RIDE] USE QUEST ITEM");
ch->UseItem(TItemPos (INVENTORY, i));
return;
}
}
}
// 타거나 내릴 수 없을때
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB8\xBB\xC0\xBB \xB8\xD5\xC0\xFA \xBC\xD2\xC8\xAF\xC7\xD8\xC1\xD6\xBC\xBC\xBF\xE4."));
}
#ifdef __AUCTION__
// temp_auction
ACMD(do_get_item_id_list)
{
for (int i = 0; i < INVENTORY_MAX_NUM; i++)
{
LPITEM item = ch->GetInventoryItem(i);
if (item != NULL)
ch->ChatPacket(CHAT_TYPE_INFO, "name : %s id : %d", item->GetProto()->szName, item->GetID());
}
}
// temp_auction
ACMD(do_enroll_auction)
{
char arg1[256];
char arg2[256];
char arg3[256];
char arg4[256];
two_arguments (two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2)), arg3, sizeof(arg3), arg4, sizeof(arg4));
DWORD item_id = strtoul(arg1, NULL, 10);
BYTE empire = strtoul(arg2, NULL, 10);
int bidPrice = strtol(arg3, NULL, 10);
int immidiatePurchasePrice = strtol(arg4, NULL, 10);
LPITEM item = ITEM_MANAGER::instance().Find(item_id);
if (item == NULL)
return;
AuctionManager::instance().enroll_auction(ch, item, empire, bidPrice, immidiatePurchasePrice);
}
ACMD(do_enroll_wish)
{
char arg1[256];
char arg2[256];
char arg3[256];
one_argument (two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2)), arg3, sizeof(arg3));
DWORD item_num = strtoul(arg1, NULL, 10);
BYTE empire = strtoul(arg2, NULL, 10);
int wishPrice = strtol(arg3, NULL, 10);
AuctionManager::instance().enroll_wish(ch, item_num, empire, wishPrice);
}
ACMD(do_enroll_sale)
{
char arg1[256];
char arg2[256];
char arg3[256];
one_argument (two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2)), arg3, sizeof(arg3));
DWORD item_id = strtoul(arg1, NULL, 10);
DWORD wisher_id = strtoul(arg2, NULL, 10);
int salePrice = strtol(arg3, NULL, 10);
LPITEM item = ITEM_MANAGER::instance().Find(item_id);
if (item == NULL)
return;
AuctionManager::instance().enroll_sale(ch, item, wisher_id, salePrice);
}
// temp_auction
// packet으로 통신하게 하고, 이건 삭제해야한다.
ACMD(do_get_auction_list)
{
char arg1[256];
char arg2[256];
char arg3[256];
two_arguments (one_argument (argument, arg1, sizeof(arg1)), arg2, sizeof(arg2), arg3, sizeof(arg3));
AuctionManager::instance().get_auction_list (ch, strtoul(arg1, NULL, 10), strtoul(arg2, NULL, 10), strtoul(arg3, NULL, 10));
}
//
//ACMD(do_get_wish_list)
//{
// char arg1[256];
// char arg2[256];
// char arg3[256];
// two_arguments (one_argument (argument, arg1, sizeof(arg1)), arg2, sizeof(arg2), arg3, sizeof(arg3));
//
// AuctionManager::instance().get_wish_list (ch, strtoul(arg1, NULL, 10), strtoul(arg2, NULL, 10), strtoul(arg3, NULL, 10));
//}
ACMD (do_get_my_auction_list)
{
char arg1[256];
char arg2[256];
two_arguments (argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
AuctionManager::instance().get_my_auction_list (ch, strtoul(arg1, NULL, 10), strtoul(arg2, NULL, 10));
}
ACMD (do_get_my_purchase_list)
{
char arg1[256];
char arg2[256];
two_arguments (argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
AuctionManager::instance().get_my_purchase_list (ch, strtoul(arg1, NULL, 10), strtoul(arg2, NULL, 10));
}
ACMD (do_auction_bid)
{
char arg1[256];
char arg2[256];
two_arguments (argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
AuctionManager::instance().bid (ch, strtoul(arg1, NULL, 10), strtoul(arg2, NULL, 10));
}
ACMD (do_auction_impur)
{
char arg1[256];
one_argument (argument, arg1, sizeof(arg1));
AuctionManager::instance().immediate_purchase (ch, strtoul(arg1, NULL, 10));
}
ACMD (do_get_auctioned_item)
{
char arg1[256];
char arg2[256];
two_arguments (argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
AuctionManager::instance().get_auctioned_item (ch, strtoul(arg1, NULL, 10), strtoul(arg2, NULL, 10));
}
ACMD (do_buy_sold_item)
{
char arg1[256];
char arg2[256];
one_argument (argument, arg1, sizeof(arg1));
AuctionManager::instance().get_auctioned_item (ch, strtoul(arg1, NULL, 10), strtoul(arg2, NULL, 10));
}
ACMD (do_cancel_auction)
{
char arg1[256];
one_argument (argument, arg1, sizeof(arg1));
AuctionManager::instance().cancel_auction (ch, strtoul(arg1, NULL, 10));
}
ACMD (do_cancel_wish)
{
char arg1[256];
one_argument (argument, arg1, sizeof(arg1));
AuctionManager::instance().cancel_wish (ch, strtoul(arg1, NULL, 10));
}
ACMD (do_cancel_sale)
{
char arg1[256];
one_argument (argument, arg1, sizeof(arg1));
AuctionManager::instance().cancel_sale (ch, strtoul(arg1, NULL, 10));
}
ACMD (do_rebid)
{
char arg1[256];
char arg2[256];
two_arguments (argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
AuctionManager::instance().rebid (ch, strtoul(arg1, NULL, 10), strtoul(arg2, NULL, 10));
}
ACMD (do_bid_cancel)
{
char arg1[256];
char arg2[256];
two_arguments (argument, arg1, sizeof(arg1), arg2, sizeof(arg2));
AuctionManager::instance().bid_cancel (ch, strtoul(arg1, NULL, 10));
}
#endif