forked from metin2/server
838 lines
19 KiB
C++
838 lines
19 KiB
C++
|
||
#include "stdafx.h"
|
||
|
||
#include "config.h"
|
||
#include "char.h"
|
||
#include "char_manager.h"
|
||
#include "affect.h"
|
||
#include "packet.h"
|
||
#include "buffer_manager.h"
|
||
#include "desc_client.h"
|
||
#include "battle.h"
|
||
#include "guild.h"
|
||
#include "utils.h"
|
||
#include "locale_service.h"
|
||
#include "lua_incl.h"
|
||
#include "arena.h"
|
||
#include "horsename_manager.h"
|
||
#include "item.h"
|
||
#include "DragonSoul.h"
|
||
|
||
#define IS_NO_SAVE_AFFECT(type) ((type) == AFFECT_WAR_FLAG || (type) == AFFECT_REVIVE_INVISIBLE || ((type) >= AFFECT_PREMIUM_START && (type) <= AFFECT_PREMIUM_END))
|
||
#define IS_NO_CLEAR_ON_DEATH_AFFECT(type) ((type) == AFFECT_BLOCK_CHAT || ((type) >= 500 && (type) < 600))
|
||
|
||
void SendAffectRemovePacket(LPDESC d, DWORD pid, DWORD type, BYTE point)
|
||
{
|
||
TPacketGCAffectRemove ptoc;
|
||
ptoc.bHeader = HEADER_GC_AFFECT_REMOVE;
|
||
ptoc.dwType = type;
|
||
ptoc.bApplyOn = point;
|
||
d->Packet(&ptoc, sizeof(TPacketGCAffectRemove));
|
||
|
||
TPacketGDRemoveAffect ptod;
|
||
ptod.dwPID = pid;
|
||
ptod.dwType = type;
|
||
ptod.bApplyOn = point;
|
||
db_clientdesc->DBPacket(HEADER_GD_REMOVE_AFFECT, 0, &ptod, sizeof(ptod));
|
||
}
|
||
|
||
void SendAffectAddPacket(LPDESC d, CAffect * pkAff)
|
||
{
|
||
TPacketGCAffectAdd ptoc;
|
||
ptoc.bHeader = HEADER_GC_AFFECT_ADD;
|
||
ptoc.elem.dwType = pkAff->dwType;
|
||
ptoc.elem.bApplyOn = pkAff->bApplyOn;
|
||
ptoc.elem.lApplyValue = pkAff->lApplyValue;
|
||
ptoc.elem.dwFlag = pkAff->dwFlag;
|
||
ptoc.elem.lDuration = pkAff->lDuration;
|
||
ptoc.elem.lSPCost = pkAff->lSPCost;
|
||
d->Packet(&ptoc, sizeof(TPacketGCAffectAdd));
|
||
}
|
||
////////////////////////////////////////////////////////////////////
|
||
// Affect
|
||
CAffect * CHARACTER::FindAffect(DWORD dwType, BYTE bApply) const
|
||
{
|
||
itertype(m_list_pkAffect) it = m_list_pkAffect.begin();
|
||
|
||
while (it != m_list_pkAffect.end())
|
||
{
|
||
CAffect * pkAffect = *it++;
|
||
|
||
if (pkAffect->dwType == dwType && (bApply == APPLY_NONE || bApply == pkAffect->bApplyOn))
|
||
return pkAffect;
|
||
}
|
||
|
||
return NULL;
|
||
}
|
||
|
||
EVENTFUNC(affect_event)
|
||
{
|
||
char_event_info* info = dynamic_cast<char_event_info*>( event->info );
|
||
|
||
if ( info == NULL )
|
||
{
|
||
sys_err( "affect_event> <Factor> Null pointer" );
|
||
return 0;
|
||
}
|
||
|
||
LPCHARACTER ch = info->ch;
|
||
|
||
if (ch == NULL) { // <Factor>
|
||
return 0;
|
||
}
|
||
|
||
if (!ch->UpdateAffect())
|
||
return 0;
|
||
else
|
||
return passes_per_sec; // 1<><31>
|
||
}
|
||
|
||
bool CHARACTER::UpdateAffect()
|
||
{
|
||
// affect_event <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ƴ<EFBFBD><C6B4><EFBFBD><EFBFBD><EFBFBD>, 1<><31>¥<EFBFBD><C2A5> <20>̺<EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
// <20>̰<EFBFBD> <20><><EFBFBD>̶<EFBFBD> <20><><EFBFBD>⼭ <20><><EFBFBD><EFBFBD> ó<><C3B3><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD>.
|
||
if (GetPoint(POINT_HP_RECOVERY) > 0)
|
||
{
|
||
if (GetMaxHP() <= GetHP())
|
||
{
|
||
PointChange(POINT_HP_RECOVERY, -GetPoint(POINT_HP_RECOVERY));
|
||
}
|
||
else
|
||
{
|
||
int iVal = 0;
|
||
|
||
if (LC_IsYMIR())
|
||
{
|
||
iVal = MIN(GetPoint(POINT_HP_RECOVERY), GetMaxHP() * 9 / 100);
|
||
}
|
||
else
|
||
{
|
||
iVal = MIN(GetPoint(POINT_HP_RECOVERY), GetMaxHP() * 7 / 100);
|
||
}
|
||
|
||
PointChange(POINT_HP, iVal);
|
||
PointChange(POINT_HP_RECOVERY, -iVal);
|
||
}
|
||
}
|
||
|
||
if (GetPoint(POINT_SP_RECOVERY) > 0)
|
||
{
|
||
if (GetMaxSP() <= GetSP())
|
||
PointChange(POINT_SP_RECOVERY, -GetPoint(POINT_SP_RECOVERY));
|
||
else
|
||
{
|
||
int iVal;
|
||
|
||
if (!g_iUseLocale)
|
||
iVal = MIN(GetPoint(POINT_SP_RECOVERY), GetMaxSP() * 7 / 100);
|
||
else
|
||
iVal = MIN(GetPoint(POINT_SP_RECOVERY), GetMaxSP() * 7 / 100);
|
||
|
||
PointChange(POINT_SP, iVal);
|
||
PointChange(POINT_SP_RECOVERY, -iVal);
|
||
}
|
||
}
|
||
|
||
if (GetPoint(POINT_HP_RECOVER_CONTINUE) > 0)
|
||
{
|
||
PointChange(POINT_HP, GetPoint(POINT_HP_RECOVER_CONTINUE));
|
||
}
|
||
|
||
if (GetPoint(POINT_SP_RECOVER_CONTINUE) > 0)
|
||
{
|
||
PointChange(POINT_SP, GetPoint(POINT_SP_RECOVER_CONTINUE));
|
||
}
|
||
|
||
AutoRecoveryItemProcess( AFFECT_AUTO_HP_RECOVERY );
|
||
AutoRecoveryItemProcess( AFFECT_AUTO_SP_RECOVERY );
|
||
|
||
// <20><><EFBFBD>̳<D7B9> ȸ<><C8B8>
|
||
if (GetMaxStamina() > GetStamina())
|
||
{
|
||
int iSec = (get_dword_time() - GetStopTime()) / 3000;
|
||
if (iSec)
|
||
PointChange(POINT_STAMINA, GetMaxStamina()/1);
|
||
}
|
||
|
||
|
||
// ProcessAffect<63><74> affect<63><74> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> true<75><65> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
if (ProcessAffect())
|
||
if (GetPoint(POINT_HP_RECOVERY) == 0 && GetPoint(POINT_SP_RECOVERY) == 0 && GetStamina() == GetMaxStamina())
|
||
{
|
||
m_pkAffectEvent = NULL;
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
void CHARACTER::StartAffectEvent()
|
||
{
|
||
if (m_pkAffectEvent)
|
||
return;
|
||
|
||
char_event_info* info = AllocEventInfo<char_event_info>();
|
||
info->ch = this;
|
||
m_pkAffectEvent = event_create(affect_event, info, passes_per_sec);
|
||
sys_log(1, "StartAffectEvent %s %p %p", GetName(), this, get_pointer(m_pkAffectEvent));
|
||
}
|
||
|
||
void CHARACTER::ClearAffect(bool bSave)
|
||
{
|
||
TAffectFlag afOld = m_afAffectFlag;
|
||
WORD wMovSpd = GetPoint(POINT_MOV_SPEED);
|
||
WORD wAttSpd = GetPoint(POINT_ATT_SPEED);
|
||
|
||
itertype(m_list_pkAffect) it = m_list_pkAffect.begin();
|
||
|
||
while (it != m_list_pkAffect.end())
|
||
{
|
||
CAffect * pkAff = *it;
|
||
|
||
if (bSave)
|
||
{
|
||
if ( IS_NO_CLEAR_ON_DEATH_AFFECT(pkAff->dwType) || IS_NO_SAVE_AFFECT(pkAff->dwType) )
|
||
{
|
||
++it;
|
||
continue;
|
||
}
|
||
|
||
if (IsPC())
|
||
{
|
||
SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
|
||
}
|
||
}
|
||
|
||
ComputeAffect(pkAff, false);
|
||
|
||
it = m_list_pkAffect.erase(it);
|
||
CAffect::Release(pkAff);
|
||
}
|
||
|
||
if (afOld != m_afAffectFlag ||
|
||
wMovSpd != GetPoint(POINT_MOV_SPEED) ||
|
||
wAttSpd != GetPoint(POINT_ATT_SPEED))
|
||
UpdatePacket();
|
||
|
||
CheckMaximumPoints();
|
||
|
||
if (m_list_pkAffect.empty())
|
||
event_cancel(&m_pkAffectEvent);
|
||
}
|
||
|
||
int CHARACTER::ProcessAffect()
|
||
{
|
||
bool bDiff = false;
|
||
CAffect *pkAff = NULL;
|
||
|
||
//
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>̾<EFBFBD> ó<><C3B3>
|
||
//
|
||
for (int i = 0; i <= PREMIUM_MAX_NUM; ++i)
|
||
{
|
||
int aff_idx = i + AFFECT_PREMIUM_START;
|
||
|
||
pkAff = FindAffect(aff_idx);
|
||
|
||
if (!pkAff)
|
||
continue;
|
||
|
||
int remain = GetPremiumRemainSeconds(i);
|
||
|
||
if (remain < 0)
|
||
{
|
||
RemoveAffect(aff_idx);
|
||
bDiff = true;
|
||
}
|
||
else
|
||
pkAff->lDuration = remain + 1;
|
||
}
|
||
|
||
////////// HAIR_AFFECT
|
||
pkAff = FindAffect(AFFECT_HAIR);
|
||
if (pkAff)
|
||
{
|
||
// IF HAIR_LIMIT_TIME() < CURRENT_TIME()
|
||
if ( this->GetQuestFlag("hair.limit_time") < get_global_time())
|
||
{
|
||
// SET HAIR NORMAL
|
||
this->SetPart(PART_HAIR, 0);
|
||
// REMOVE HAIR AFFECT
|
||
RemoveAffect(AFFECT_HAIR);
|
||
}
|
||
else
|
||
{
|
||
// INCREASE AFFECT DURATION
|
||
++(pkAff->lDuration);
|
||
}
|
||
}
|
||
////////// HAIR_AFFECT
|
||
//
|
||
|
||
CHorseNameManager::instance().Validate(this);
|
||
|
||
TAffectFlag afOld = m_afAffectFlag;
|
||
int lMovSpd = GetPoint(POINT_MOV_SPEED);
|
||
int lAttSpd = GetPoint(POINT_ATT_SPEED);
|
||
|
||
itertype(m_list_pkAffect) it;
|
||
|
||
it = m_list_pkAffect.begin();
|
||
|
||
while (it != m_list_pkAffect.end())
|
||
{
|
||
pkAff = *it;
|
||
|
||
bool bEnd = false;
|
||
|
||
if (pkAff->dwType >= GUILD_SKILL_START && pkAff->dwType <= GUILD_SKILL_END)
|
||
{
|
||
if (!GetGuild() || !GetGuild()->UnderAnyWar())
|
||
bEnd = true;
|
||
}
|
||
|
||
if (pkAff->lSPCost > 0)
|
||
{
|
||
if (GetSP() < pkAff->lSPCost)
|
||
bEnd = true;
|
||
else
|
||
PointChange(POINT_SP, -pkAff->lSPCost);
|
||
}
|
||
|
||
// AFFECT_DURATION_BUG_FIX
|
||
// <20><><EFBFBD><EFBFBD> ȿ<><C8BF> <20><><EFBFBD><EFBFBD><EFBFBD>۵<EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> <20><><EFBFBD>δ<EFBFBD>.
|
||
// <20>ð<EFBFBD><C3B0><EFBFBD> <20>ſ<EFBFBD> ũ<><C5A9> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>̶<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
if ( --pkAff->lDuration <= 0 )
|
||
{
|
||
bEnd = true;
|
||
}
|
||
// END_AFFECT_DURATION_BUG_FIX
|
||
|
||
if (bEnd)
|
||
{
|
||
it = m_list_pkAffect.erase(it);
|
||
ComputeAffect(pkAff, false);
|
||
bDiff = true;
|
||
if (IsPC())
|
||
{
|
||
SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
|
||
}
|
||
|
||
CAffect::Release(pkAff);
|
||
|
||
continue;
|
||
}
|
||
|
||
++it;
|
||
}
|
||
|
||
if (bDiff)
|
||
{
|
||
if (afOld != m_afAffectFlag ||
|
||
lMovSpd != GetPoint(POINT_MOV_SPEED) ||
|
||
lAttSpd != GetPoint(POINT_ATT_SPEED))
|
||
{
|
||
UpdatePacket();
|
||
}
|
||
|
||
CheckMaximumPoints();
|
||
}
|
||
|
||
if (m_list_pkAffect.empty())
|
||
return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
void CHARACTER::SaveAffect()
|
||
{
|
||
TPacketGDAddAffect p;
|
||
|
||
itertype(m_list_pkAffect) it = m_list_pkAffect.begin();
|
||
|
||
while (it != m_list_pkAffect.end())
|
||
{
|
||
CAffect * pkAff = *it++;
|
||
|
||
if (IS_NO_SAVE_AFFECT(pkAff->dwType))
|
||
continue;
|
||
|
||
sys_log(1, "AFFECT_SAVE: %u %u %d %d", pkAff->dwType, pkAff->bApplyOn, pkAff->lApplyValue, pkAff->lDuration);
|
||
|
||
p.dwPID = GetPlayerID();
|
||
p.elem.dwType = pkAff->dwType;
|
||
p.elem.bApplyOn = pkAff->bApplyOn;
|
||
p.elem.lApplyValue = pkAff->lApplyValue;
|
||
p.elem.dwFlag = pkAff->dwFlag;
|
||
p.elem.lDuration = pkAff->lDuration;
|
||
p.elem.lSPCost = pkAff->lSPCost;
|
||
db_clientdesc->DBPacket(HEADER_GD_ADD_AFFECT, 0, &p, sizeof(p));
|
||
}
|
||
}
|
||
|
||
EVENTINFO(load_affect_login_event_info)
|
||
{
|
||
DWORD pid;
|
||
DWORD count;
|
||
char* data;
|
||
|
||
load_affect_login_event_info()
|
||
: pid( 0 )
|
||
, count( 0 )
|
||
, data( 0 )
|
||
{
|
||
}
|
||
};
|
||
|
||
EVENTFUNC(load_affect_login_event)
|
||
{
|
||
load_affect_login_event_info* info = dynamic_cast<load_affect_login_event_info*>( event->info );
|
||
|
||
if ( info == NULL )
|
||
{
|
||
sys_err( "load_affect_login_event_info> <Factor> Null pointer" );
|
||
return 0;
|
||
}
|
||
|
||
DWORD dwPID = info->pid;
|
||
LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(dwPID);
|
||
|
||
if (!ch)
|
||
{
|
||
M2_DELETE_ARRAY(info->data);
|
||
return 0;
|
||
}
|
||
|
||
LPDESC d = ch->GetDesc();
|
||
|
||
if (!d)
|
||
{
|
||
M2_DELETE_ARRAY(info->data);
|
||
return 0;
|
||
}
|
||
|
||
if (d->IsPhase(PHASE_HANDSHAKE) ||
|
||
d->IsPhase(PHASE_LOGIN) ||
|
||
d->IsPhase(PHASE_SELECT) ||
|
||
d->IsPhase(PHASE_DEAD) ||
|
||
d->IsPhase(PHASE_LOADING))
|
||
{
|
||
return PASSES_PER_SEC(1);
|
||
}
|
||
else if (d->IsPhase(PHASE_CLOSE))
|
||
{
|
||
M2_DELETE_ARRAY(info->data);
|
||
return 0;
|
||
}
|
||
else if (d->IsPhase(PHASE_GAME))
|
||
{
|
||
sys_log(1, "Affect Load by Event");
|
||
ch->LoadAffect(info->count, (TPacketAffectElement*)info->data);
|
||
M2_DELETE_ARRAY(info->data);
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
sys_err("input_db.cpp:quest_login_event INVALID PHASE pid %d", ch->GetPlayerID());
|
||
M2_DELETE_ARRAY(info->data);
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
void CHARACTER::LoadAffect(DWORD dwCount, TPacketAffectElement * pElements)
|
||
{
|
||
m_bIsLoadedAffect = false;
|
||
|
||
if (!GetDesc()->IsPhase(PHASE_GAME))
|
||
{
|
||
if (test_server)
|
||
sys_log(0, "LOAD_AFFECT: Creating Event", GetName(), dwCount);
|
||
|
||
load_affect_login_event_info* info = AllocEventInfo<load_affect_login_event_info>();
|
||
|
||
info->pid = GetPlayerID();
|
||
info->count = dwCount;
|
||
info->data = M2_NEW char[sizeof(TPacketAffectElement) * dwCount];
|
||
memcpy(info->data, pElements, sizeof(TPacketAffectElement) * dwCount);
|
||
|
||
event_create(load_affect_login_event, info, PASSES_PER_SEC(1));
|
||
|
||
return;
|
||
}
|
||
|
||
ClearAffect(true);
|
||
|
||
if (test_server)
|
||
sys_log(0, "LOAD_AFFECT: %s count %d", GetName(), dwCount);
|
||
|
||
TAffectFlag afOld = m_afAffectFlag;
|
||
|
||
int lMovSpd = GetPoint(POINT_MOV_SPEED);
|
||
int lAttSpd = GetPoint(POINT_ATT_SPEED);
|
||
|
||
for (DWORD i = 0; i < dwCount; ++i, ++pElements)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʴ´<CAB4>.
|
||
if (pElements->dwType == SKILL_MUYEONG)
|
||
continue;
|
||
|
||
if (AFFECT_AUTO_HP_RECOVERY == pElements->dwType || AFFECT_AUTO_SP_RECOVERY == pElements->dwType)
|
||
{
|
||
LPITEM item = FindItemByID( pElements->dwFlag );
|
||
|
||
if (NULL == item)
|
||
continue;
|
||
|
||
item->Lock(true);
|
||
}
|
||
|
||
if (pElements->bApplyOn >= POINT_MAX_NUM)
|
||
{
|
||
sys_err("invalid affect data %s ApplyOn %u ApplyValue %d",
|
||
GetName(), pElements->bApplyOn, pElements->lApplyValue);
|
||
continue;
|
||
}
|
||
|
||
if (test_server)
|
||
{
|
||
sys_log(0, "Load Affect : Affect %s %d %d", GetName(), pElements->dwType, pElements->bApplyOn );
|
||
}
|
||
|
||
CAffect* pkAff = CAffect::Acquire();
|
||
m_list_pkAffect.push_back(pkAff);
|
||
|
||
pkAff->dwType = pElements->dwType;
|
||
pkAff->bApplyOn = pElements->bApplyOn;
|
||
pkAff->lApplyValue = pElements->lApplyValue;
|
||
pkAff->dwFlag = pElements->dwFlag;
|
||
pkAff->lDuration = pElements->lDuration;
|
||
pkAff->lSPCost = pElements->lSPCost;
|
||
|
||
SendAffectAddPacket(GetDesc(), pkAff);
|
||
|
||
ComputeAffect(pkAff, true);
|
||
|
||
|
||
}
|
||
|
||
if ( CArenaManager::instance().IsArenaMap(GetMapIndex()) == true )
|
||
{
|
||
RemoveGoodAffect();
|
||
}
|
||
|
||
if (afOld != m_afAffectFlag || lMovSpd != GetPoint(POINT_MOV_SPEED) || lAttSpd != GetPoint(POINT_ATT_SPEED))
|
||
{
|
||
UpdatePacket();
|
||
}
|
||
|
||
StartAffectEvent();
|
||
|
||
m_bIsLoadedAffect = true;
|
||
|
||
// <20><>ȥ<EFBFBD><C8A5> <20><><EFBFBD><EFBFBD> <20>ε<EFBFBD> <20><> <20>ʱ<EFBFBD>ȭ
|
||
DragonSoul_Initialize();
|
||
}
|
||
|
||
bool CHARACTER::AddAffect(DWORD dwType, BYTE bApplyOn, int lApplyValue, DWORD dwFlag, int lDuration, int lSPCost, bool bOverride, bool IsCube )
|
||
{
|
||
// CHAT_BLOCK
|
||
if (dwType == AFFECT_BLOCK_CHAT && lDuration > 1)
|
||
{
|
||
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ä<><C3A4><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>Ǿ<EFBFBD><C7BE><EFBFBD><EFBFBD>ϴ<EFBFBD>."));
|
||
}
|
||
// END_OF_CHAT_BLOCK
|
||
|
||
if (lDuration == 0)
|
||
{
|
||
sys_err("Character::AddAffect lDuration == 0 type %d", lDuration, dwType);
|
||
lDuration = 1;
|
||
}
|
||
|
||
CAffect * pkAff = NULL;
|
||
|
||
if (IsCube)
|
||
pkAff = FindAffect(dwType,bApplyOn);
|
||
else
|
||
pkAff = FindAffect(dwType);
|
||
|
||
if (dwFlag == AFF_STUN)
|
||
{
|
||
if (m_posDest.x != GetX() || m_posDest.y != GetY())
|
||
{
|
||
m_posDest.x = m_posStart.x = GetX();
|
||
m_posDest.y = m_posStart.y = GetY();
|
||
battle_end(this);
|
||
|
||
SyncPacket();
|
||
}
|
||
}
|
||
|
||
// <20>̹<EFBFBD> <20>ִ<EFBFBD> ȿ<><C8BF><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> ó<><C3B3>
|
||
if (pkAff && bOverride)
|
||
{
|
||
ComputeAffect(pkAff, false); // <20>ϴ<EFBFBD> ȿ<><C8BF><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD>
|
||
|
||
if (GetDesc())
|
||
SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
|
||
}
|
||
else
|
||
{
|
||
//
|
||
// <20><> <20><><EFBFBD>带 <20>߰<EFBFBD>
|
||
//
|
||
// NOTE: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> type <20><><EFBFBD>ε<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE> <20><><EFBFBD><EFBFBD> <20><> <20>ִ<EFBFBD>.
|
||
//
|
||
pkAff = CAffect::Acquire();
|
||
m_list_pkAffect.push_back(pkAff);
|
||
|
||
}
|
||
|
||
sys_log(1, "AddAffect %s type %d apply %d %d flag %u duration %d", GetName(), dwType, bApplyOn, lApplyValue, dwFlag, lDuration);
|
||
sys_log(0, "AddAffect %s type %d apply %d %d flag %u duration %d", GetName(), dwType, bApplyOn, lApplyValue, dwFlag, lDuration);
|
||
|
||
pkAff->dwType = dwType;
|
||
pkAff->bApplyOn = bApplyOn;
|
||
pkAff->lApplyValue = lApplyValue;
|
||
pkAff->dwFlag = dwFlag;
|
||
pkAff->lDuration = lDuration;
|
||
pkAff->lSPCost = lSPCost;
|
||
|
||
WORD wMovSpd = GetPoint(POINT_MOV_SPEED);
|
||
WORD wAttSpd = GetPoint(POINT_ATT_SPEED);
|
||
|
||
ComputeAffect(pkAff, true);
|
||
|
||
if (pkAff->dwFlag || wMovSpd != GetPoint(POINT_MOV_SPEED) || wAttSpd != GetPoint(POINT_ATT_SPEED))
|
||
UpdatePacket();
|
||
|
||
StartAffectEvent();
|
||
|
||
if (IsPC())
|
||
{
|
||
SendAffectAddPacket(GetDesc(), pkAff);
|
||
|
||
if (IS_NO_SAVE_AFFECT(pkAff->dwType))
|
||
return true;
|
||
|
||
TPacketGDAddAffect p;
|
||
p.dwPID = GetPlayerID();
|
||
p.elem.dwType = pkAff->dwType;
|
||
p.elem.bApplyOn = pkAff->bApplyOn;
|
||
p.elem.lApplyValue = pkAff->lApplyValue;
|
||
p.elem.dwFlag = pkAff->dwFlag;
|
||
p.elem.lDuration = pkAff->lDuration;
|
||
p.elem.lSPCost = pkAff->lSPCost;
|
||
db_clientdesc->DBPacket(HEADER_GD_ADD_AFFECT, 0, &p, sizeof(p));
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
void CHARACTER::RefreshAffect()
|
||
{
|
||
itertype(m_list_pkAffect) it = m_list_pkAffect.begin();
|
||
|
||
while (it != m_list_pkAffect.end())
|
||
{
|
||
CAffect * pkAff = *it++;
|
||
ComputeAffect(pkAff, true);
|
||
}
|
||
}
|
||
|
||
void CHARACTER::ComputeAffect(CAffect * pkAff, bool bAdd)
|
||
{
|
||
if (bAdd && pkAff->dwType >= GUILD_SKILL_START && pkAff->dwType <= GUILD_SKILL_END)
|
||
{
|
||
if (!GetGuild())
|
||
return;
|
||
|
||
if (!GetGuild()->UnderAnyWar())
|
||
return;
|
||
}
|
||
|
||
if (pkAff->dwFlag)
|
||
{
|
||
if (!bAdd)
|
||
m_afAffectFlag.Reset(pkAff->dwFlag);
|
||
else
|
||
m_afAffectFlag.Set(pkAff->dwFlag);
|
||
}
|
||
|
||
if (bAdd)
|
||
PointChange(pkAff->bApplyOn, pkAff->lApplyValue);
|
||
else
|
||
PointChange(pkAff->bApplyOn, -pkAff->lApplyValue);
|
||
|
||
if (pkAff->dwType == SKILL_MUYEONG)
|
||
{
|
||
if (bAdd)
|
||
StartMuyeongEvent();
|
||
else
|
||
StopMuyeongEvent();
|
||
}
|
||
}
|
||
|
||
bool CHARACTER::RemoveAffect(CAffect * pkAff)
|
||
{
|
||
if (!pkAff)
|
||
return false;
|
||
|
||
// AFFECT_BUF_FIX
|
||
m_list_pkAffect.remove(pkAff);
|
||
// END_OF_AFFECT_BUF_FIX
|
||
|
||
ComputeAffect(pkAff, false);
|
||
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD>״<EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ų <20><><EFBFBD><EFBFBD>-><3E>а<EFBFBD>-><3E><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>(AFFECT_REVIVE_INVISIBLE) <20><> <20>ٷ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD>쿡 <20><EFBFBD><DFBB>Ѵ<EFBFBD>.
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>а<EFBFBD><D0B0><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><>ų ȿ<><C8BF><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20>а<EFBFBD> ȿ<><C8BF><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD> <20>Ǿ<EFBFBD><C7BE>ִµ<D6B4>,
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20>ٷ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD> RemoveAffect<63><74> <20>Ҹ<EFBFBD><D2B8><EFBFBD> <20>ǰ<EFBFBD>, ComputePoints<74>ϸ鼭 <20>а<EFBFBD> ȿ<><C8BF> + <20><><EFBFBD><EFBFBD> <20><>ų ȿ<><C8BF><EFBFBD><EFBFBD> <20>ȴ<EFBFBD>.
|
||
// ComputePoints<74><73><EFBFBD><EFBFBD> <20>а<EFBFBD> <20><><EFBFBD>¸<EFBFBD> <20><><EFBFBD><EFBFBD> <20><>ų ȿ<><C8BF> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ϸ<EFBFBD> <20>DZ<EFBFBD> <20>ϴµ<CFB4>,
|
||
// ComputePoints<74><73> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD> <20>־ ū <20><>ȭ<EFBFBD><C8AD> <20>ִ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.(<28> side effect<63><74> <20><EFBFBD><DFBB><EFBFBD><EFBFBD><EFBFBD> <20>˱<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.)
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> AFFECT_REVIVE_INVISIBLE<4C><45> RemoveAffect<63><74> <20><><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD> <20><><EFBFBD>츸 <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>.
|
||
// <20>ð<EFBFBD><C3B0><EFBFBD> <20><> <20>Ǿ<EFBFBD> <20><><EFBFBD><EFBFBD> ȿ<><C8BF><EFBFBD><EFBFBD> Ǯ<><C7AE><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>װ<EFBFBD> <20><EFBFBD><DFBB><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD> <20><EFBFBD> <20>Ȱ<EFBFBD><C8B0><EFBFBD> <20><>.
|
||
// (ProcessAffect<63><74> <20><><EFBFBD><EFBFBD> <20>ð<EFBFBD><C3B0><EFBFBD> <20><> <20>Ǿ Affect<63><74> <20><><EFBFBD><EFBFBD><EFBFBD>Ǵ<EFBFBD> <20><><EFBFBD><EFBFBD>, ComputePoints<74><73> <20>θ<EFBFBD><CEB8><EFBFBD> <20>ʴ´<CAB4>.)
|
||
if (AFFECT_REVIVE_INVISIBLE != pkAff->dwType)
|
||
{
|
||
ComputePoints();
|
||
}
|
||
CheckMaximumPoints();
|
||
|
||
if (test_server)
|
||
sys_log(0, "AFFECT_REMOVE: %s (flag %u apply: %u)", GetName(), pkAff->dwFlag, pkAff->bApplyOn);
|
||
|
||
if (IsPC())
|
||
{
|
||
SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
|
||
}
|
||
|
||
CAffect::Release(pkAff);
|
||
return true;
|
||
}
|
||
|
||
bool CHARACTER::RemoveAffect(DWORD dwType)
|
||
{
|
||
// CHAT_BLOCK
|
||
if (dwType == AFFECT_BLOCK_CHAT)
|
||
{
|
||
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("ä<EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ǯ<>Ƚ<EFBFBD><C8BD>ϴ<EFBFBD>."));
|
||
}
|
||
// END_OF_CHAT_BLOCK
|
||
|
||
bool flag = false;
|
||
|
||
CAffect * pkAff;
|
||
|
||
while ((pkAff = FindAffect(dwType)))
|
||
{
|
||
RemoveAffect(pkAff);
|
||
flag = true;
|
||
}
|
||
|
||
return flag;
|
||
}
|
||
|
||
bool CHARACTER::IsAffectFlag(DWORD dwAff) const
|
||
{
|
||
return m_afAffectFlag.IsSet(dwAff);
|
||
}
|
||
|
||
void CHARACTER::RemoveGoodAffect()
|
||
{
|
||
RemoveAffect(AFFECT_MOV_SPEED);
|
||
RemoveAffect(AFFECT_ATT_SPEED);
|
||
RemoveAffect(AFFECT_STR);
|
||
RemoveAffect(AFFECT_DEX);
|
||
RemoveAffect(AFFECT_INT);
|
||
RemoveAffect(AFFECT_CON);
|
||
RemoveAffect(AFFECT_CHINA_FIREWORK);
|
||
|
||
RemoveAffect(SKILL_JEONGWI);
|
||
RemoveAffect(SKILL_GEOMKYUNG);
|
||
RemoveAffect(SKILL_CHUNKEON);
|
||
RemoveAffect(SKILL_EUNHYUNG);
|
||
RemoveAffect(SKILL_GYEONGGONG);
|
||
RemoveAffect(SKILL_GWIGEOM);
|
||
RemoveAffect(SKILL_TERROR);
|
||
RemoveAffect(SKILL_JUMAGAP);
|
||
RemoveAffect(SKILL_MANASHILED);
|
||
RemoveAffect(SKILL_HOSIN);
|
||
RemoveAffect(SKILL_REFLECT);
|
||
RemoveAffect(SKILL_KWAESOK);
|
||
RemoveAffect(SKILL_JEUNGRYEOK);
|
||
RemoveAffect(SKILL_GICHEON);
|
||
}
|
||
|
||
bool CHARACTER::IsGoodAffect(BYTE bAffectType) const
|
||
{
|
||
switch (bAffectType)
|
||
{
|
||
case (AFFECT_MOV_SPEED):
|
||
case (AFFECT_ATT_SPEED):
|
||
case (AFFECT_STR):
|
||
case (AFFECT_DEX):
|
||
case (AFFECT_INT):
|
||
case (AFFECT_CON):
|
||
case (AFFECT_CHINA_FIREWORK):
|
||
|
||
case (SKILL_JEONGWI):
|
||
case (SKILL_GEOMKYUNG):
|
||
case (SKILL_CHUNKEON):
|
||
case (SKILL_EUNHYUNG):
|
||
case (SKILL_GYEONGGONG):
|
||
case (SKILL_GWIGEOM):
|
||
case (SKILL_TERROR):
|
||
case (SKILL_JUMAGAP):
|
||
case (SKILL_MANASHILED):
|
||
case (SKILL_HOSIN):
|
||
case (SKILL_REFLECT):
|
||
case (SKILL_KWAESOK):
|
||
case (SKILL_JEUNGRYEOK):
|
||
case (SKILL_GICHEON):
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
void CHARACTER::RemoveBadAffect()
|
||
{
|
||
sys_log(0, "RemoveBadAffect %s", GetName());
|
||
// <20><>
|
||
RemovePoison();
|
||
RemoveFire();
|
||
|
||
// <20><><EFBFBD><EFBFBD> : Value%<25><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 5<>ʰ<EFBFBD> <20>Ӹ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>ư<EFBFBD><C6B0><EFBFBD>. (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1/2 Ȯ<><C8AE><EFBFBD><EFBFBD> Ǯ<><C7AE>) AFF_STUN
|
||
RemoveAffect(AFFECT_STUN);
|
||
|
||
// <20><><EFBFBD>ο<EFBFBD> : Value%<25><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>/<2F>̼<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD><DEB6><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD>쿡 AFF_SLOW
|
||
RemoveAffect(AFFECT_SLOW);
|
||
|
||
// <20><><EFBFBD>Ӹ<EFBFBD><D3B8><EFBFBD>
|
||
RemoveAffect(SKILL_TUSOK);
|
||
|
||
// <20><><EFBFBD><EFBFBD>
|
||
//RemoveAffect(SKILL_CURSE);
|
||
|
||
// <20>Ĺ<EFBFBD><C4B9><EFBFBD>
|
||
//RemoveAffect(SKILL_PABUP);
|
||
|
||
// <20><><EFBFBD><EFBFBD> : Value%<25><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ų<EFBFBD><C5B2>. 2<><32> AFF_FAINT
|
||
//RemoveAffect(AFFECT_FAINT);
|
||
|
||
// <20>ٸ<EFBFBD><D9B8><EFBFBD><EFBFBD><EFBFBD> : Value%<25><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>̵<EFBFBD><CCB5>ӵ<EFBFBD><D3B5><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD>. 5<>ʰ<EFBFBD> -40 AFF_WEB
|
||
//RemoveAffect(AFFECT_WEB);
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> : Value%<25><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 10<31>ʰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ǯ<><C7AE>) AFF_SLEEP
|
||
//RemoveAffect(AFFECT_SLEEP);
|
||
|
||
// <20><><EFBFBD><EFBFBD> : Value%<25><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD>. <20><><EFBFBD>õ<EFBFBD><C3B5><EFBFBD> <20><><EFBFBD><EFBFBD> <20><EFBFBD><DEB6><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD>쿡 AFF_CURSE
|
||
//RemoveAffect(AFFECT_CURSE);
|
||
|
||
// <20><><EFBFBD><EFBFBD> : Value%<25><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 4<>ʰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ų<EFBFBD><C5B2>. AFF_PARA
|
||
//RemoveAffect(AFFECT_PARALYZE);
|
||
|
||
// <20>ε<EFBFBD><CEB5>ں<EFBFBD> : <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
//RemoveAffect(SKILL_BUDONG);
|
||
}
|
||
|