server/game/src/char_affect.cpp

838 lines
19 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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);
}