2022-03-05 12:44:06 +02:00
# include "stdafx.h"
2022-03-05 19:59:39 +02:00
# include <common/teen_packet.h>
# include <common/VnumHelper.h>
2022-03-05 12:44:06 +02:00
# include "char.h"
# include "config.h"
# include "utils.h"
# include "crc32.h"
# include "char_manager.h"
# include "desc_client.h"
# include "desc_manager.h"
# include "buffer_manager.h"
# include "item_manager.h"
# include "motion.h"
# include "vector.h"
# include "packet.h"
# include "cmd.h"
# include "fishing.h"
# include "exchange.h"
# include "battle.h"
# include "affect.h"
# include "shop.h"
# include "shop_manager.h"
# include "safebox.h"
# include "regen.h"
# include "pvp.h"
# include "party.h"
# include "start_position.h"
# include "questmanager.h"
# include "log.h"
# include "p2p.h"
# include "guild.h"
# include "guild_manager.h"
# include "dungeon.h"
# include "messenger_manager.h"
# include "unique_item.h"
# include "priv_manager.h"
# include "war_map.h"
# include "xmas_event.h"
# include "banword.h"
# include "target.h"
# include "wedding.h"
# include "mob_manager.h"
# include "mining.h"
# include "monarch.h"
# include "castle.h"
# include "arena.h"
# include "dev_log.h"
# include "horsename_manager.h"
# include "pcbang.h"
# include "gm.h"
# include "map_location.h"
# include "BlueDragon_Binder.h"
# include "skill_power.h"
# include "buff_on_attributes.h"
# ifdef __PET_SYSTEM__
# include "PetSystem.h"
# endif
# include "DragonSoul.h"
extern const BYTE g_aBuffOnAttrPoints ;
extern bool RaceToJob ( unsigned race , unsigned * ret_job ) ;
extern int g_nPortalLimitTime ;
extern int test_server ;
extern bool IS_SUMMONABLE_ZONE ( int map_index ) ; // char_item.cpp
bool CAN_ENTER_ZONE ( const LPCHARACTER & ch , int map_index ) ;
bool CAN_ENTER_ZONE ( const LPCHARACTER & ch , int map_index )
{
switch ( map_index )
{
case 301 :
case 302 :
case 303 :
case 304 :
if ( ch - > GetLevel ( ) < 90 )
return false ;
}
return true ;
}
// <Factor> DynamicCharacterPtr member function definitions
LPCHARACTER DynamicCharacterPtr : : Get ( ) const {
LPCHARACTER p = NULL ;
if ( is_pc ) {
p = CHARACTER_MANAGER : : instance ( ) . FindByPID ( id ) ;
} else {
p = CHARACTER_MANAGER : : instance ( ) . Find ( id ) ;
}
return p ;
}
DynamicCharacterPtr & DynamicCharacterPtr : : operator = ( LPCHARACTER character ) {
if ( character = = NULL ) {
Reset ( ) ;
return * this ;
}
if ( character - > IsPC ( ) ) {
is_pc = true ;
id = character - > GetPlayerID ( ) ;
} else {
is_pc = false ;
id = character - > GetVID ( ) ;
}
return * this ;
}
CHARACTER : : CHARACTER ( )
{
m_stateIdle . Set ( this , & CHARACTER : : BeginStateEmpty , & CHARACTER : : StateIdle , & CHARACTER : : EndStateEmpty ) ;
m_stateMove . Set ( this , & CHARACTER : : BeginStateEmpty , & CHARACTER : : StateMove , & CHARACTER : : EndStateEmpty ) ;
m_stateBattle . Set ( this , & CHARACTER : : BeginStateEmpty , & CHARACTER : : StateBattle , & CHARACTER : : EndStateEmpty ) ;
Initialize ( ) ;
}
CHARACTER : : ~ CHARACTER ( )
{
Destroy ( ) ;
}
void CHARACTER : : Initialize ( )
{
CEntity : : Initialize ( ENTITY_CHARACTER ) ;
m_bNoOpenedShop = true ;
m_bOpeningSafebox = false ;
m_fSyncTime = get_float_time ( ) - 3 ;
m_dwPlayerID = 0 ;
m_dwKillerPID = 0 ;
m_iMoveCount = 0 ;
m_pkRegen = NULL ;
regen_id_ = 0 ;
m_posRegen . x = m_posRegen . y = m_posRegen . z = 0 ;
m_posStart . x = m_posStart . y = 0 ;
m_posDest . x = m_posDest . y = 0 ;
m_fRegenAngle = 0.0f ;
m_pkMobData = NULL ;
m_pkMobInst = NULL ;
m_pkShop = NULL ;
m_pkChrShopOwner = NULL ;
m_pkMyShop = NULL ;
m_pkExchange = NULL ;
m_pkParty = NULL ;
m_pkPartyRequestEvent = NULL ;
m_pGuild = NULL ;
m_pkChrTarget = NULL ;
m_pkMuyeongEvent = NULL ;
m_pkWarpNPCEvent = NULL ;
m_pkDeadEvent = NULL ;
m_pkStunEvent = NULL ;
m_pkSaveEvent = NULL ;
m_pkRecoveryEvent = NULL ;
m_pkTimedEvent = NULL ;
m_pkFishingEvent = NULL ;
m_pkWarpEvent = NULL ;
// MINING
m_pkMiningEvent = NULL ;
// END_OF_MINING
m_pkPoisonEvent = NULL ;
m_pkFireEvent = NULL ;
m_pkCheckSpeedHackEvent = NULL ;
m_speed_hack_count = 0 ;
m_pkAffectEvent = NULL ;
m_afAffectFlag = TAffectFlag ( 0 , 0 ) ;
m_pkDestroyWhenIdleEvent = NULL ;
m_pkChrSyncOwner = NULL ;
memset ( & m_points , 0 , sizeof ( m_points ) ) ;
memset ( & m_pointsInstant , 0 , sizeof ( m_pointsInstant ) ) ;
memset ( & m_quickslot , 0 , sizeof ( m_quickslot ) ) ;
m_bCharType = CHAR_TYPE_MONSTER ;
SetPosition ( POS_STANDING ) ;
m_dwPlayStartTime = m_dwLastMoveTime = get_dword_time ( ) ;
GotoState ( m_stateIdle ) ;
m_dwStateDuration = 1 ;
m_dwLastAttackTime = get_dword_time ( ) - 20000 ;
m_bAddChrState = 0 ;
m_pkChrStone = NULL ;
m_pkSafebox = NULL ;
m_iSafeboxSize = - 1 ;
m_iSafeboxLoadTime = 0 ;
m_pkMall = NULL ;
m_iMallLoadTime = 0 ;
m_posWarp . x = m_posWarp . y = m_posWarp . z = 0 ;
m_lWarpMapIndex = 0 ;
m_posExit . x = m_posExit . y = m_posExit . z = 0 ;
m_lExitMapIndex = 0 ;
m_pSkillLevels = NULL ;
m_dwMoveStartTime = 0 ;
m_dwMoveDuration = 0 ;
m_dwFlyTargetID = 0 ;
m_dwNextStatePulse = 0 ;
m_dwLastDeadTime = get_dword_time ( ) - 180000 ;
m_bSkipSave = false ;
m_bItemLoaded = false ;
m_bHasPoisoned = false ;
m_pkDungeon = NULL ;
m_iEventAttr = 0 ;
m_kAttackLog . dwVID = 0 ;
m_kAttackLog . dwTime = 0 ;
m_bNowWalking = m_bWalking = false ;
ResetChangeAttackPositionTime ( ) ;
m_bDetailLog = false ;
m_bMonsterLog = false ;
m_bDisableCooltime = false ;
m_iAlignment = 0 ;
m_iRealAlignment = 0 ;
m_iKillerModePulse = 0 ;
m_bPKMode = PK_MODE_PEACE ;
m_dwQuestNPCVID = 0 ;
m_dwQuestByVnum = 0 ;
m_pQuestItem = NULL ;
m_szMobileAuth [ 0 ] = ' \0 ' ;
m_dwUnderGuildWarInfoMessageTime = get_dword_time ( ) - 60000 ;
m_bUnderRefine = false ;
// REFINE_NPC
m_dwRefineNPCVID = 0 ;
// END_OF_REFINE_NPC
m_dwPolymorphRace = 0 ;
m_bStaminaConsume = false ;
ResetChainLightningIndex ( ) ;
m_dwMountVnum = 0 ;
m_chHorse = NULL ;
m_chRider = NULL ;
m_pWarMap = NULL ;
m_pWeddingMap = NULL ;
m_bChatCounter = 0 ;
ResetStopTime ( ) ;
m_dwLastVictimSetTime = get_dword_time ( ) - 3000 ;
m_iMaxAggro = - 100 ;
m_bSendHorseLevel = 0 ;
m_bSendHorseHealthGrade = 0 ;
m_bSendHorseStaminaGrade = 0 ;
m_dwLoginPlayTime = 0 ;
m_pkChrMarried = NULL ;
m_posSafeboxOpen . x = - 1000 ;
m_posSafeboxOpen . y = - 1000 ;
// EQUIP_LAST_SKILL_DELAY
m_dwLastSkillTime = get_dword_time ( ) ;
// END_OF_EQUIP_LAST_SKILL_DELAY
// MOB_SKILL_COOLTIME
memset ( m_adwMobSkillCooltime , 0 , sizeof ( m_adwMobSkillCooltime ) ) ;
// END_OF_MOB_SKILL_COOLTIME
m_isinPCBang = false ;
// ARENA
m_pArena = NULL ;
m_nPotionLimit = quest : : CQuestManager : : instance ( ) . GetEventFlag ( " arena_potion_limit_count " ) ;
// END_ARENA
//PREVENT_TRADE_WINDOW
m_isOpenSafebox = 0 ;
//END_PREVENT_TRADE_WINDOW
//PREVENT_REFINE_HACK
m_iRefineTime = 0 ;
//END_PREVENT_REFINE_HACK
//RESTRICT_USE_SEED_OR_MOONBOTTLE
m_iSeedTime = 0 ;
//END_RESTRICT_USE_SEED_OR_MOONBOTTLE
//PREVENT_PORTAL_AFTER_EXCHANGE
m_iExchangeTime = 0 ;
//END_PREVENT_PORTAL_AFTER_EXCHANGE
//
m_iSafeboxLoadTime = 0 ;
m_iMyShopTime = 0 ;
InitMC ( ) ;
m_deposit_pulse = 0 ;
SET_OVER_TIME ( this , OT_NONE ) ;
m_strNewName = " " ;
m_known_guild . clear ( ) ;
m_dwLogOffInterval = 0 ;
m_bComboSequence = 0 ;
m_dwLastComboTime = 0 ;
m_bComboIndex = 0 ;
m_iComboHackCount = 0 ;
m_dwSkipComboAttackByTime = 0 ;
m_dwMountTime = 0 ;
m_dwLastGoldDropTime = 0 ;
m_bIsLoadedAffect = false ;
cannot_dead = false ;
# ifdef __PET_SYSTEM__
m_petSystem = 0 ;
m_bIsPet = false ;
# endif
m_fAttMul = 1.0f ;
m_fDamMul = 1.0f ;
m_pointsInstant . iDragonSoulActiveDeck = - 1 ;
memset ( & m_tvLastSyncTime , 0 , sizeof ( m_tvLastSyncTime ) ) ;
m_iSyncHackCount = 0 ;
}
void CHARACTER : : Create ( const char * c_pszName , DWORD vid , bool isPC )
{
static int s_crc = 172814 ;
char crc_string [ 128 + 1 ] ;
snprintf ( crc_string , sizeof ( crc_string ) , " %s%p%d " , c_pszName , this , + + s_crc ) ;
m_vid = VID ( vid , GetCRC32 ( crc_string , strlen ( crc_string ) ) ) ;
if ( isPC )
m_stName = c_pszName ;
}
void CHARACTER : : Destroy ( )
{
CloseMyShop ( ) ;
if ( m_pkRegen )
{
if ( m_pkDungeon ) {
// Dungeon regen may not be valid at this point
if ( m_pkDungeon - > IsValidRegen ( m_pkRegen , regen_id_ ) ) {
- - m_pkRegen - > count ;
}
} else {
// Is this really safe?
- - m_pkRegen - > count ;
}
m_pkRegen = NULL ;
}
if ( m_pkDungeon )
{
SetDungeon ( NULL ) ;
}
# ifdef __PET_SYSTEM__
if ( m_petSystem )
{
m_petSystem - > Destroy ( ) ;
delete m_petSystem ;
m_petSystem = 0 ;
}
# endif
HorseSummon ( false ) ;
if ( GetRider ( ) )
GetRider ( ) - > ClearHorseInfo ( ) ;
if ( GetDesc ( ) )
{
GetDesc ( ) - > BindCharacter ( NULL ) ;
// BindDesc(NULL);
}
if ( m_pkExchange )
m_pkExchange - > Cancel ( ) ;
SetVictim ( NULL ) ;
if ( GetShop ( ) )
{
GetShop ( ) - > RemoveGuest ( this ) ;
SetShop ( NULL ) ;
}
ClearStone ( ) ;
ClearSync ( ) ;
ClearTarget ( ) ;
if ( NULL = = m_pkMobData )
{
DragonSoul_CleanUp ( ) ;
ClearItem ( ) ;
}
// <Factor> m_pkParty becomes NULL after CParty destructor call!
LPPARTY party = m_pkParty ;
if ( party )
{
if ( party - > GetLeaderPID ( ) = = GetVID ( ) & & ! IsPC ( ) )
{
M2_DELETE ( party ) ;
}
else
{
party - > Unlink ( this ) ;
if ( ! IsPC ( ) )
party - > Quit ( GetVID ( ) ) ;
}
SetParty ( NULL ) ; // <20> <> <EFBFBD> ص<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> .
}
if ( m_pkMobInst )
{
M2_DELETE ( m_pkMobInst ) ;
m_pkMobInst = NULL ;
}
m_pkMobData = NULL ;
if ( m_pkSafebox )
{
M2_DELETE ( m_pkSafebox ) ;
m_pkSafebox = NULL ;
}
if ( m_pkMall )
{
M2_DELETE ( m_pkMall ) ;
m_pkMall = NULL ;
}
m_set_pkChrSpawnedBy . clear ( ) ;
StopMuyeongEvent ( ) ;
event_cancel ( & m_pkWarpNPCEvent ) ;
event_cancel ( & m_pkRecoveryEvent ) ;
event_cancel ( & m_pkDeadEvent ) ;
event_cancel ( & m_pkSaveEvent ) ;
event_cancel ( & m_pkTimedEvent ) ;
event_cancel ( & m_pkStunEvent ) ;
event_cancel ( & m_pkFishingEvent ) ;
event_cancel ( & m_pkPoisonEvent ) ;
event_cancel ( & m_pkFireEvent ) ;
event_cancel ( & m_pkPartyRequestEvent ) ;
//DELAYED_WARP
event_cancel ( & m_pkWarpEvent ) ;
event_cancel ( & m_pkCheckSpeedHackEvent ) ;
//END_DELAYED_WARP
// RECALL_DELAY
//event_cancel(&m_pkRecallEvent);
// END_OF_RECALL_DELAY
// MINING
event_cancel ( & m_pkMiningEvent ) ;
// END_OF_MINING
for ( itertype ( m_mapMobSkillEvent ) it = m_mapMobSkillEvent . begin ( ) ; it ! = m_mapMobSkillEvent . end ( ) ; + + it )
{
LPEVENT pkEvent = it - > second ;
event_cancel ( & pkEvent ) ;
}
m_mapMobSkillEvent . clear ( ) ;
//event_cancel(&m_pkAffectEvent);
ClearAffect ( ) ;
for ( TMapBuffOnAttrs : : iterator it = m_map_buff_on_attrs . begin ( ) ; it ! = m_map_buff_on_attrs . end ( ) ; it + + )
{
if ( NULL ! = it - > second )
{
M2_DELETE ( it - > second ) ;
}
}
m_map_buff_on_attrs . clear ( ) ;
event_cancel ( & m_pkDestroyWhenIdleEvent ) ;
if ( m_pSkillLevels )
{
M2_DELETE_ARRAY ( m_pSkillLevels ) ;
m_pSkillLevels = NULL ;
}
CEntity : : Destroy ( ) ;
if ( GetSectree ( ) )
GetSectree ( ) - > RemoveEntity ( this ) ;
if ( m_bMonsterLog )
CHARACTER_MANAGER : : instance ( ) . UnregisterForMonsterLog ( this ) ;
}
const char * CHARACTER : : GetName ( ) const
{
return m_stName . empty ( ) ? ( m_pkMobData ? m_pkMobData - > m_table . szLocaleName : " " ) : m_stName . c_str ( ) ;
}
void CHARACTER : : OpenMyShop ( const char * c_pszSign , TShopItemTable * pTable , BYTE bItemCount )
{
if ( GetPart ( PART_MAIN ) > 2 )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <20> ֽ<EFBFBD> <D6BD> ϴ<EFBFBD> ." ) ) ;
return ;
}
if ( GetMyShop ( ) ) // <20> ̹<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ݴ´ <DDB4> .
{
CloseMyShop ( ) ;
return ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> .
quest : : PC * pPC = quest : : CQuestManager : : instance ( ) . GetPCForce ( GetPlayerID ( ) ) ;
// GetPCForce<63> <65> NULL<4C> <4C> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> Ȯ<> <C8AE> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
if ( pPC - > IsRunning ( ) )
return ;
if ( bItemCount = = 0 )
return ;
int64_t nTotalMoney = 0 ;
for ( int n = 0 ; n < bItemCount ; + + n )
{
nTotalMoney + = static_cast < int64_t > ( ( pTable + n ) - > price ) ;
}
nTotalMoney + = static_cast < int64_t > ( GetGold ( ) ) ;
if ( GOLD_MAX < = nTotalMoney )
{
sys_err ( " [OVERFLOW_GOLD] Overflow (GOLD_MAX) id %u name %s " , GetPlayerID ( ) , GetName ( ) ) ;
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " 20<EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ʰ<EFBFBD> <CAB0> Ͽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> " ) ) ;
return ;
}
char szSign [ SHOP_SIGN_MAX_LEN + 1 ] ;
2022-03-05 19:59:39 +02:00
strncpy ( szSign , c_pszSign , sizeof ( szSign ) ) ;
2022-03-05 12:44:06 +02:00
m_stShopSign = szSign ;
if ( m_stShopSign . length ( ) = = 0 )
return ;
if ( LC_IsCanada ( ) = = false )
{
if ( CBanwordManager : : instance ( ) . CheckString ( m_stShopSign . c_str ( ) , m_stShopSign . length ( ) ) )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> <EFBFBD> Ӿ <20> <> <EFBFBD> <20> <> <EFBFBD> Ե<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ̸<EFBFBD> <CCB8> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ." ) ) ;
return ;
}
}
// MYSHOP_PRICE_LIST
std : : map < DWORD , DWORD > itemkind ; // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> , first: vnum, second: <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
// END_OF_MYSHOP_PRICE_LIST
std : : set < TItemPos > cont ;
for ( BYTE i = 0 ; i < bItemCount ; + + i )
{
if ( cont . find ( ( pTable + i ) - > pos ) ! = cont . end ( ) )
{
sys_err ( " MYSHOP: duplicate shop item detected! (name: %s) " , GetName ( ) ) ;
return ;
}
// ANTI_GIVE, ANTI_MYSHOP check
LPITEM pkItem = GetItem ( ( pTable + i ) - > pos ) ;
if ( pkItem )
{
const TItemTable * item_table = pkItem - > GetProto ( ) ;
if ( item_table & & ( IS_SET ( item_table - > dwAntiFlags , ITEM_ANTIFLAG_GIVE | ITEM_ANTIFLAG_MYSHOP ) ) )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȭ <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> λ<EFBFBD> <CEBB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ǹ<EFBFBD> <C7B8> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ." ) ) ;
return ;
}
if ( pkItem - > IsEquipped ( ) = = true )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> λ<EFBFBD> <CEBB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ǹ<EFBFBD> <C7B8> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ." ) ) ;
return ;
}
if ( true = = pkItem - > isLocked ( ) )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> λ<EFBFBD> <CEBB> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ǹ<EFBFBD> <C7B8> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ." ) ) ;
return ;
}
// MYSHOP_PRICE_LIST
itemkind [ pkItem - > GetVnum ( ) ] = ( pTable + i ) - > price / pkItem - > GetCount ( ) ;
// END_OF_MYSHOP_PRICE_LIST
}
cont . insert ( ( pTable + i ) - > pos ) ;
}
// MYSHOP_PRICE_LIST
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ҽ <EFBFBD> Ų<EFBFBD> <C5B2> .
if ( CountSpecifyItem ( 71049 ) ) { // <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ʰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ѵ <EFBFBD> .
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϱ <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ŷ<EFBFBD> <C5B6> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> DB ij<> ÿ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> .
//
TPacketMyshopPricelistHeader header ;
TItemPriceInfo info ;
header . dwOwnerID = GetPlayerID ( ) ;
header . byCount = itemkind . size ( ) ;
TEMP_BUFFER buf ;
buf . write ( & header , sizeof ( header ) ) ;
for ( itertype ( itemkind ) it = itemkind . begin ( ) ; it ! = itemkind . end ( ) ; + + it )
{
info . dwVnum = it - > first ;
info . dwPrice = it - > second ;
buf . write ( & info , sizeof ( info ) ) ;
}
db_clientdesc - > DBPacket ( HEADER_GD_MYSHOP_PRICELIST_UPDATE , 0 , buf . read_peek ( ) , buf . size ( ) ) ;
}
// END_OF_MYSHOP_PRICE_LIST
else if ( CountSpecifyItem ( 50200 ) )
RemoveSpecifyItem ( 50200 , 1 ) ;
else
return ; // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ߴ <EFBFBD> .
if ( m_pkExchange )
m_pkExchange - > Cancel ( ) ;
TPacketGCShopSign p ;
p . bHeader = HEADER_GC_SHOP_SIGN ;
p . dwVID = GetVID ( ) ;
2022-03-05 19:59:39 +02:00
strncpy ( p . szSign , c_pszSign , sizeof ( p . szSign ) ) ;
2022-03-05 12:44:06 +02:00
PacketAround ( & p , sizeof ( TPacketGCShopSign ) ) ;
m_pkMyShop = CShopManager : : instance ( ) . CreatePCShop ( this , pTable , bItemCount ) ;
if ( IsPolymorphed ( ) = = true )
{
RemoveAffect ( AFFECT_POLYMORPH ) ;
}
if ( GetHorse ( ) )
{
HorseSummon ( false , true ) ;
}
// new mount <20> ̿<EFBFBD> <20> ߿<EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ڵ<EFBFBD> unmount
// StopRiding<6E> <67> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <EFBFBD> <EFBFBD> ó<> <C3B3> <EFBFBD> ϸ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <EFBFBD> <D7B7> <EFBFBD> <20> <> <EFBFBD> س<EFBFBD> <D8B3> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> .
else if ( GetMountVnum ( ) )
{
RemoveAffect ( AFFECT_MOUNT ) ;
RemoveAffect ( AFFECT_MOUNT_BONUS ) ;
}
//if (!LC_IsNewCIBN())
SetPolymorph ( 30000 , true ) ;
}
void CHARACTER : : CloseMyShop ( )
{
if ( GetMyShop ( ) )
{
m_stShopSign . clear ( ) ;
CShopManager : : instance ( ) . DestroyPCShop ( this ) ;
m_pkMyShop = NULL ;
TPacketGCShopSign p ;
p . bHeader = HEADER_GC_SHOP_SIGN ;
p . dwVID = GetVID ( ) ;
p . szSign [ 0 ] = ' \0 ' ;
PacketAround ( & p , sizeof ( p ) ) ;
//if (!LC_IsNewCIBN())
SetPolymorph ( GetJob ( ) , true ) ;
}
}
void EncodeMovePacket ( TPacketGCMove & pack , DWORD dwVID , BYTE bFunc , BYTE bArg , DWORD x , DWORD y , DWORD dwDuration , DWORD dwTime , BYTE bRot )
{
pack . bHeader = HEADER_GC_MOVE ;
pack . bFunc = bFunc ;
pack . bArg = bArg ;
pack . dwVID = dwVID ;
pack . dwTime = dwTime ? dwTime : get_dword_time ( ) ;
pack . bRot = bRot ;
pack . lX = x ;
pack . lY = y ;
pack . dwDuration = dwDuration ;
}
void CHARACTER : : RestartAtSamePos ( )
{
if ( m_bIsObserver )
return ;
EncodeRemovePacket ( this ) ;
EncodeInsertPacket ( this ) ;
ENTITY_MAP : : iterator it = m_map_view . begin ( ) ;
while ( it ! = m_map_view . end ( ) )
{
LPENTITY entity = ( it + + ) - > first ;
EncodeRemovePacket ( entity ) ;
if ( ! m_bIsObserver )
EncodeInsertPacket ( entity ) ;
if ( entity - > IsType ( ENTITY_CHARACTER ) )
{
LPCHARACTER lpChar = ( LPCHARACTER ) entity ;
if ( lpChar - > IsPC ( ) | | lpChar - > IsNPC ( ) | | lpChar - > IsMonster ( ) )
{
if ( ! entity - > IsObserverMode ( ) )
entity - > EncodeInsertPacket ( this ) ;
}
}
else
{
if ( ! entity - > IsObserverMode ( ) )
{
entity - > EncodeInsertPacket ( this ) ;
}
}
}
}
// Entity<74> <79> <20> <> <EFBFBD> <EFBFBD> <20> <> Ÿ<EFBFBD> <C5B8> <EFBFBD> ٰ<EFBFBD> <20> <> Ŷ<EFBFBD> <C5B6> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> .
void CHARACTER : : EncodeInsertPacket ( LPENTITY entity )
{
LPDESC d ;
if ( ! ( d = entity - > GetDesc ( ) ) )
return ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ̸<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ڵ<EFBFBD>
LPCHARACTER ch = ( LPCHARACTER ) entity ;
ch - > SendGuildName ( GetGuild ( ) ) ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ̸<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ڵ<EFBFBD>
TPacketGCCharacterAdd pack ;
pack . header = HEADER_GC_CHARACTER_ADD ;
pack . dwVID = m_vid ;
pack . bType = GetCharType ( ) ;
pack . angle = GetRotation ( ) ;
pack . x = GetX ( ) ;
pack . y = GetY ( ) ;
pack . z = GetZ ( ) ;
pack . wRaceNum = GetRaceNum ( ) ;
if ( IsPet ( ) )
{
pack . bMovingSpeed = 150 ;
}
else
{
pack . bMovingSpeed = GetLimitPoint ( POINT_MOV_SPEED ) ;
}
pack . bAttackSpeed = GetLimitPoint ( POINT_ATT_SPEED ) ;
pack . dwAffectFlag [ 0 ] = m_afAffectFlag . bits [ 0 ] ;
pack . dwAffectFlag [ 1 ] = m_afAffectFlag . bits [ 1 ] ;
pack . bStateFlag = m_bAddChrState ;
int iDur = 0 ;
if ( m_posDest . x ! = pack . x | | m_posDest . y ! = pack . y )
{
iDur = ( m_dwMoveStartTime + m_dwMoveDuration ) - get_dword_time ( ) ;
if ( iDur < = 0 )
{
pack . x = m_posDest . x ;
pack . y = m_posDest . y ;
}
}
d - > Packet ( & pack , sizeof ( pack ) ) ;
if ( IsPC ( ) = = true | | m_bCharType = = CHAR_TYPE_NPC )
{
TPacketGCCharacterAdditionalInfo addPacket ;
memset ( & addPacket , 0 , sizeof ( TPacketGCCharacterAdditionalInfo ) ) ;
addPacket . header = HEADER_GC_CHAR_ADDITIONAL_INFO ;
addPacket . dwVID = m_vid ;
addPacket . awPart [ CHR_EQUIPPART_ARMOR ] = GetPart ( PART_MAIN ) ;
addPacket . awPart [ CHR_EQUIPPART_WEAPON ] = GetPart ( PART_WEAPON ) ;
addPacket . awPart [ CHR_EQUIPPART_HEAD ] = GetPart ( PART_HEAD ) ;
addPacket . awPart [ CHR_EQUIPPART_HAIR ] = GetPart ( PART_HAIR ) ;
addPacket . bPKMode = m_bPKMode ;
addPacket . dwMountVnum = GetMountVnum ( ) ;
addPacket . bEmpire = m_bEmpire ;
if ( IsPC ( ) = = true & & ( LC_IsEurope ( ) = = true | | LC_IsCanada ( ) = = true | | LC_IsSingapore ( ) = = true ) )
{
addPacket . dwLevel = GetLevel ( ) ;
}
else
{
addPacket . dwLevel = 0 ;
}
if ( false )
{
LPCHARACTER ch = ( LPCHARACTER ) entity ;
if ( GetEmpire ( ) = = ch - > GetEmpire ( ) | | ch - > GetGMLevel ( ) > GM_PLAYER | | m_bCharType = = CHAR_TYPE_NPC )
{
goto show_all_info ;
}
else
{
memset ( addPacket . name , 0 , CHARACTER_NAME_MAX_LEN ) ;
addPacket . dwGuildID = 0 ;
addPacket . sAlignment = 0 ;
}
}
else
{
show_all_info :
2022-03-05 19:59:39 +02:00
strncpy ( addPacket . name , GetName ( ) , sizeof ( addPacket . name ) ) ;
2022-03-05 12:44:06 +02:00
if ( GetGuild ( ) ! = NULL )
{
addPacket . dwGuildID = GetGuild ( ) - > GetID ( ) ;
}
else
{
addPacket . dwGuildID = 0 ;
}
addPacket . sAlignment = m_iAlignment / 10 ;
}
d - > Packet ( & addPacket , sizeof ( TPacketGCCharacterAdditionalInfo ) ) ;
}
if ( iDur )
{
TPacketGCMove pack ;
EncodeMovePacket ( pack , GetVID ( ) , FUNC_MOVE , 0 , m_posDest . x , m_posDest . y , iDur , 0 , ( BYTE ) ( GetRotation ( ) / 5 ) ) ;
d - > Packet ( & pack , sizeof ( pack ) ) ;
TPacketGCWalkMode p ;
p . vid = GetVID ( ) ;
p . header = HEADER_GC_WALK_MODE ;
p . mode = m_bNowWalking ? WALKMODE_WALK : WALKMODE_RUN ;
d - > Packet ( & p , sizeof ( p ) ) ;
}
if ( entity - > IsType ( ENTITY_CHARACTER ) & & GetDesc ( ) )
{
LPCHARACTER ch = ( LPCHARACTER ) entity ;
if ( ch - > IsWalking ( ) )
{
TPacketGCWalkMode p ;
p . vid = ch - > GetVID ( ) ;
p . header = HEADER_GC_WALK_MODE ;
p . mode = ch - > m_bNowWalking ? WALKMODE_WALK : WALKMODE_RUN ;
GetDesc ( ) - > Packet ( & p , sizeof ( p ) ) ;
}
}
if ( GetMyShop ( ) )
{
TPacketGCShopSign p ;
p . bHeader = HEADER_GC_SHOP_SIGN ;
p . dwVID = GetVID ( ) ;
2022-03-05 19:59:39 +02:00
strncpy ( p . szSign , m_stShopSign . c_str ( ) , sizeof ( p . szSign ) ) ;
2022-03-05 12:44:06 +02:00
d - > Packet ( & p , sizeof ( TPacketGCShopSign ) ) ;
}
if ( entity - > IsType ( ENTITY_CHARACTER ) )
{
sys_log ( 3 , " EntityInsert %s (RaceNum %d) (%d %d) TO %s " ,
GetName ( ) , GetRaceNum ( ) , GetX ( ) / SECTREE_SIZE , GetY ( ) / SECTREE_SIZE , ( ( LPCHARACTER ) entity ) - > GetName ( ) ) ;
}
}
void CHARACTER : : EncodeRemovePacket ( LPENTITY entity )
{
if ( entity - > GetType ( ) ! = ENTITY_CHARACTER )
return ;
LPDESC d ;
if ( ! ( d = entity - > GetDesc ( ) ) )
return ;
TPacketGCCharacterDelete pack ;
pack . header = HEADER_GC_CHARACTER_DEL ;
pack . id = m_vid ;
d - > Packet ( & pack , sizeof ( TPacketGCCharacterDelete ) ) ;
if ( entity - > IsType ( ENTITY_CHARACTER ) )
sys_log ( 3 , " EntityRemove %s(%d) FROM %s " , GetName ( ) , ( DWORD ) m_vid , ( ( LPCHARACTER ) entity ) - > GetName ( ) ) ;
}
void CHARACTER : : UpdatePacket ( )
{
if ( GetSectree ( ) = = NULL ) return ;
TPacketGCCharacterUpdate pack ;
TPacketGCCharacterUpdate pack2 ;
pack . header = HEADER_GC_CHARACTER_UPDATE ;
pack . dwVID = m_vid ;
pack . awPart [ CHR_EQUIPPART_ARMOR ] = GetPart ( PART_MAIN ) ;
pack . awPart [ CHR_EQUIPPART_WEAPON ] = GetPart ( PART_WEAPON ) ;
pack . awPart [ CHR_EQUIPPART_HEAD ] = GetPart ( PART_HEAD ) ;
pack . awPart [ CHR_EQUIPPART_HAIR ] = GetPart ( PART_HAIR ) ;
pack . bMovingSpeed = GetLimitPoint ( POINT_MOV_SPEED ) ;
pack . bAttackSpeed = GetLimitPoint ( POINT_ATT_SPEED ) ;
pack . bStateFlag = m_bAddChrState ;
pack . dwAffectFlag [ 0 ] = m_afAffectFlag . bits [ 0 ] ;
pack . dwAffectFlag [ 1 ] = m_afAffectFlag . bits [ 1 ] ;
pack . dwGuildID = 0 ;
pack . sAlignment = m_iAlignment / 10 ;
pack . bPKMode = m_bPKMode ;
if ( GetGuild ( ) )
pack . dwGuildID = GetGuild ( ) - > GetID ( ) ;
pack . dwMountVnum = GetMountVnum ( ) ;
pack2 = pack ;
pack2 . dwGuildID = 0 ;
pack2 . sAlignment = 0 ;
if ( false )
{
if ( m_bIsObserver ! = true )
{
for ( ENTITY_MAP : : iterator iter = m_map_view . begin ( ) ; iter ! = m_map_view . end ( ) ; iter + + )
{
LPENTITY pEntity = iter - > first ;
if ( pEntity ! = NULL )
{
if ( pEntity - > IsType ( ENTITY_CHARACTER ) = = true )
{
if ( pEntity - > GetDesc ( ) ! = NULL )
{
LPCHARACTER pChar = ( LPCHARACTER ) pEntity ;
if ( GetEmpire ( ) = = pChar - > GetEmpire ( ) | | pChar - > GetGMLevel ( ) > GM_PLAYER )
{
pEntity - > GetDesc ( ) - > Packet ( & pack , sizeof ( pack ) ) ;
}
else
{
pEntity - > GetDesc ( ) - > Packet ( & pack2 , sizeof ( pack2 ) ) ;
}
}
}
else
{
if ( pEntity - > GetDesc ( ) ! = NULL )
{
pEntity - > GetDesc ( ) - > Packet ( & pack , sizeof ( pack ) ) ;
}
}
}
}
}
if ( GetDesc ( ) ! = NULL )
{
GetDesc ( ) - > Packet ( & pack , sizeof ( pack ) ) ;
}
}
else
{
PacketAround ( & pack , sizeof ( pack ) ) ;
}
}
LPCHARACTER CHARACTER : : FindCharacterInView ( const char * c_pszName , bool bFindPCOnly )
{
ENTITY_MAP : : iterator it = m_map_view . begin ( ) ;
for ( ; it ! = m_map_view . end ( ) ; + + it )
{
if ( ! it - > first - > IsType ( ENTITY_CHARACTER ) )
continue ;
LPCHARACTER tch = ( LPCHARACTER ) it - > first ;
if ( bFindPCOnly & & tch - > IsNPC ( ) )
continue ;
if ( ! strcasecmp ( tch - > GetName ( ) , c_pszName ) )
return ( tch ) ;
}
return NULL ;
}
void CHARACTER : : SetPosition ( int pos )
{
if ( pos = = POS_STANDING )
{
REMOVE_BIT ( m_bAddChrState , ADD_CHARACTER_STATE_DEAD ) ;
REMOVE_BIT ( m_pointsInstant . instant_flag , INSTANT_FLAG_STUN ) ;
event_cancel ( & m_pkDeadEvent ) ;
event_cancel ( & m_pkStunEvent ) ;
}
else if ( pos = = POS_DEAD )
SET_BIT ( m_bAddChrState , ADD_CHARACTER_STATE_DEAD ) ;
if ( ! IsStone ( ) )
{
switch ( pos )
{
case POS_FIGHTING :
if ( ! IsState ( m_stateBattle ) )
MonsterLog ( " [BATTLE] <20> ο <EFBFBD> <CEBF> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> " ) ;
GotoState ( m_stateBattle ) ;
break ;
default :
if ( ! IsState ( m_stateIdle ) )
MonsterLog ( " [IDLE] <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> " ) ;
GotoState ( m_stateIdle ) ;
break ;
}
}
m_pointsInstant . position = pos ;
}
void CHARACTER : : Save ( )
{
if ( ! m_bSkipSave )
CHARACTER_MANAGER : : instance ( ) . DelayedSave ( this ) ;
}
void CHARACTER : : CreatePlayerProto ( TPlayerTable & tab )
{
memset ( & tab , 0 , sizeof ( TPlayerTable ) ) ;
if ( GetNewName ( ) . empty ( ) )
{
2022-03-05 19:59:39 +02:00
strncpy ( tab . name , GetName ( ) , sizeof ( tab . name ) ) ;
2022-03-05 12:44:06 +02:00
}
else
{
2022-03-05 19:59:39 +02:00
strncpy ( tab . name , GetNewName ( ) . c_str ( ) , sizeof ( tab . name ) ) ;
2022-03-05 12:44:06 +02:00
}
2022-03-05 19:59:39 +02:00
strncpy ( tab . ip , GetDesc ( ) - > GetHostName ( ) , sizeof ( tab . ip ) ) ;
2022-03-05 12:44:06 +02:00
tab . id = m_dwPlayerID ;
tab . voice = GetPoint ( POINT_VOICE ) ;
tab . level = GetLevel ( ) ;
tab . level_step = GetPoint ( POINT_LEVEL_STEP ) ;
tab . exp = GetExp ( ) ;
tab . gold = GetGold ( ) ;
tab . job = m_points . job ;
tab . part_base = m_pointsInstant . bBasePart ;
tab . skill_group = m_points . skill_group ;
DWORD dwPlayedTime = ( get_dword_time ( ) - m_dwPlayStartTime ) ;
if ( dwPlayedTime > 60000 )
{
if ( GetSectree ( ) & & ! GetSectree ( ) - > IsAttr ( GetX ( ) , GetY ( ) , ATTR_BANPK ) )
{
if ( GetRealAlignment ( ) < 0 )
{
if ( IsEquipUniqueItem ( UNIQUE_ITEM_FASTER_ALIGNMENT_UP_BY_TIME ) )
UpdateAlignment ( 120 * ( dwPlayedTime / 60000 ) ) ;
else
UpdateAlignment ( 60 * ( dwPlayedTime / 60000 ) ) ;
}
else
UpdateAlignment ( 5 * ( dwPlayedTime / 60000 ) ) ;
}
SetRealPoint ( POINT_PLAYTIME , GetRealPoint ( POINT_PLAYTIME ) + dwPlayedTime / 60000 ) ;
ResetPlayTime ( dwPlayedTime % 60000 ) ;
}
tab . playtime = GetRealPoint ( POINT_PLAYTIME ) ;
tab . lAlignment = m_iRealAlignment ;
if ( m_posWarp . x ! = 0 | | m_posWarp . y ! = 0 )
{
tab . x = m_posWarp . x ;
tab . y = m_posWarp . y ;
tab . z = 0 ;
tab . lMapIndex = m_lWarpMapIndex ;
}
else
{
tab . x = GetX ( ) ;
tab . y = GetY ( ) ;
tab . z = GetZ ( ) ;
tab . lMapIndex = GetMapIndex ( ) ;
}
if ( m_lExitMapIndex = = 0 )
{
tab . lExitMapIndex = tab . lMapIndex ;
tab . lExitX = tab . x ;
tab . lExitY = tab . y ;
}
else
{
tab . lExitMapIndex = m_lExitMapIndex ;
tab . lExitX = m_posExit . x ;
tab . lExitY = m_posExit . y ;
}
sys_log ( 0 , " SAVE: %s %dx%d " , GetName ( ) , tab . x , tab . y ) ;
tab . st = GetRealPoint ( POINT_ST ) ;
tab . ht = GetRealPoint ( POINT_HT ) ;
tab . dx = GetRealPoint ( POINT_DX ) ;
tab . iq = GetRealPoint ( POINT_IQ ) ;
tab . stat_point = GetPoint ( POINT_STAT ) ;
tab . skill_point = GetPoint ( POINT_SKILL ) ;
tab . sub_skill_point = GetPoint ( POINT_SUB_SKILL ) ;
tab . horse_skill_point = GetPoint ( POINT_HORSE_SKILL ) ;
tab . stat_reset_count = GetPoint ( POINT_STAT_RESET_COUNT ) ;
tab . hp = GetHP ( ) ;
tab . sp = GetSP ( ) ;
tab . stamina = GetStamina ( ) ;
tab . sRandomHP = m_points . iRandomHP ;
tab . sRandomSP = m_points . iRandomSP ;
for ( int i = 0 ; i < QUICKSLOT_MAX_NUM ; + + i )
tab . quickslot [ i ] = m_quickslot [ i ] ;
if ( m_stMobile . length ( ) & & ! * m_szMobileAuth )
2022-03-05 19:59:39 +02:00
strncpy ( tab . szMobile , m_stMobile . c_str ( ) , sizeof ( tab . szMobile ) ) ;
2022-03-05 12:44:06 +02:00
2022-03-06 17:36:43 +02:00
memcpy ( tab . parts , m_pointsInstant . parts , sizeof ( tab . parts ) ) ;
2022-03-05 12:44:06 +02:00
// REMOVE_REAL_SKILL_LEVLES
2022-03-06 17:36:43 +02:00
memcpy ( tab . skills , m_pSkillLevels , sizeof ( TPlayerSkill ) * SKILL_MAX_NUM ) ;
2022-03-05 12:44:06 +02:00
// END_OF_REMOVE_REAL_SKILL_LEVLES
tab . horse = GetHorseData ( ) ;
}
void CHARACTER : : SaveReal ( )
{
if ( m_bSkipSave )
return ;
if ( ! GetDesc ( ) )
{
sys_err ( " Character::Save : no descriptor when saving (name: %s) " , GetName ( ) ) ;
return ;
}
TPlayerTable table ;
CreatePlayerProto ( table ) ;
db_clientdesc - > DBPacket ( HEADER_GD_PLAYER_SAVE , GetDesc ( ) - > GetHandle ( ) , & table , sizeof ( TPlayerTable ) ) ;
quest : : PC * pkQuestPC = quest : : CQuestManager : : instance ( ) . GetPCForce ( GetPlayerID ( ) ) ;
if ( ! pkQuestPC )
sys_err ( " CHARACTER::Save : null quest::PC pointer! (name %s) " , GetName ( ) ) ;
else
{
pkQuestPC - > Save ( ) ;
}
marriage : : TMarriage * pMarriage = marriage : : CManager : : instance ( ) . Get ( GetPlayerID ( ) ) ;
if ( pMarriage )
pMarriage - > Save ( ) ;
}
void CHARACTER : : FlushDelayedSaveItem ( )
{
// <20> <> <EFBFBD> <EFBFBD> <20> ȵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> ǰ<EFBFBD> <C7B0> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ų<EFBFBD> <C5B2> .
LPITEM item ;
for ( int i = 0 ; i < INVENTORY_AND_EQUIP_SLOT_MAX ; + + i )
if ( ( item = GetInventoryItem ( i ) ) )
ITEM_MANAGER : : instance ( ) . FlushDelayedSave ( item ) ;
}
void CHARACTER : : Disconnect ( const char * c_pszReason )
{
assert ( GetDesc ( ) ! = NULL ) ;
sys_log ( 0 , " DISCONNECT: %s (%s) " , GetName ( ) , c_pszReason ? c_pszReason : " unset " ) ;
if ( GetShop ( ) )
{
GetShop ( ) - > RemoveGuest ( this ) ;
SetShop ( NULL ) ;
}
if ( GetArena ( ) ! = NULL )
{
GetArena ( ) - > OnDisconnect ( GetPlayerID ( ) ) ;
}
if ( GetParty ( ) ! = NULL )
{
GetParty ( ) - > UpdateOfflineState ( GetPlayerID ( ) ) ;
}
marriage : : CManager : : instance ( ) . Logout ( this ) ;
// P2P Logout
TPacketGGLogout p ;
p . bHeader = HEADER_GG_LOGOUT ;
2022-03-05 19:59:39 +02:00
strncpy ( p . szName , GetName ( ) , sizeof ( p . szName ) ) ;
2022-03-05 12:44:06 +02:00
P2P_MANAGER : : instance ( ) . Send ( & p , sizeof ( TPacketGGLogout ) ) ;
char buf [ 51 ] ;
2022-03-12 11:39:41 +02:00
snprintf ( buf , sizeof ( buf ) , " %s %d %d %d %d " ,
GetDesc ( ) - > GetHostName ( ) , GetGold ( ) , g_bChannel , GetMapIndex ( ) , GetAlignment ( ) ) ;
2022-03-05 12:44:06 +02:00
LogManager : : instance ( ) . CharLog ( this , 0 , " LOGOUT " , buf ) ;
if ( LC_IsYMIR ( ) | | LC_IsKorea ( ) | | LC_IsBrazil ( ) )
{
2022-03-12 11:39:41 +02:00
int playTime = GetRealPoint ( POINT_PLAYTIME ) - m_dwLoginPlayTime ;
2022-03-05 12:44:06 +02:00
LogManager : : instance ( ) . LoginLog ( false , GetDesc ( ) - > GetAccountTable ( ) . id , GetPlayerID ( ) , GetLevel ( ) , GetJob ( ) , playTime ) ;
if ( LC_IsBrazil ( ) ! = true )
CPCBangManager : : instance ( ) . Log ( GetDesc ( ) - > GetHostName ( ) , GetPlayerID ( ) , playTime ) ;
}
if ( m_pWarMap )
SetWarMap ( NULL ) ;
if ( m_pWeddingMap )
{
SetWeddingMap ( NULL ) ;
}
if ( GetGuild ( ) )
GetGuild ( ) - > LogoutMember ( this ) ;
quest : : CQuestManager : : instance ( ) . LogoutPC ( this ) ;
if ( GetParty ( ) )
GetParty ( ) - > Unlink ( this ) ;
// <20> <EFBFBD> <D7BE> <EFBFBD> <20> <> <20> <> <EFBFBD> Ӳ<EFBFBD> <D3B2> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> ġ <20> ٰ<EFBFBD> <20> ϱ <EFBFBD>
if ( IsStun ( ) | | IsDead ( ) )
{
DeathPenalty ( 0 ) ;
PointChange ( POINT_HP , 50 - GetHP ( ) ) ;
}
if ( ! CHARACTER_MANAGER : : instance ( ) . FlushDelayedSave ( this ) )
{
SaveReal ( ) ;
}
FlushDelayedSaveItem ( ) ;
SaveAffect ( ) ;
m_bIsLoadedAffect = false ;
m_bSkipSave = true ; // <20> <> <20> <> <EFBFBD> Ŀ<EFBFBD> <C4BF> <EFBFBD> <20> <> <EFBFBD> ̻<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϸ<EFBFBD> <20> ȵȴ<C8B5> .
quest : : CQuestManager : : instance ( ) . DisconnectPC ( this ) ;
CloseSafebox ( ) ;
CloseMall ( ) ;
CPVPManager : : instance ( ) . Disconnect ( this ) ;
CTargetManager : : instance ( ) . Logout ( GetPlayerID ( ) ) ;
MessengerManager : : instance ( ) . Logout ( GetName ( ) ) ;
if ( g_TeenDesc )
{
int offset = 0 ;
char buf [ 245 ] = { 0 } ;
buf [ 0 ] = HEADER_GT_LOGOUT ;
offset + = 1 ;
memset ( buf + offset , 0x00 , 2 ) ;
offset + = 2 ;
TAccountTable & acc_table = GetDesc ( ) - > GetAccountTable ( ) ;
memcpy ( buf + offset , & acc_table . id , 4 ) ;
offset + = 4 ;
g_TeenDesc - > Packet ( buf , offset ) ;
}
if ( GetDesc ( ) )
{
GetDesc ( ) - > BindCharacter ( NULL ) ;
// BindDesc(NULL);
}
M2_DESTROY_CHARACTER ( this ) ;
}
2022-03-12 11:39:41 +02:00
bool CHARACTER : : Show ( int lMapIndex , int x , int y , int z , bool bShowSpawnMotion /* = false */ )
2022-03-05 12:44:06 +02:00
{
LPSECTREE sectree = SECTREE_MANAGER : : instance ( ) . Get ( lMapIndex , x , y ) ;
if ( ! sectree )
{
sys_log ( 0 , " cannot find sectree by %dx%d mapindex %d " , x , y , lMapIndex ) ;
return false ;
}
SetMapIndex ( lMapIndex ) ;
bool bChangeTree = false ;
if ( ! GetSectree ( ) | | GetSectree ( ) ! = sectree )
bChangeTree = true ;
if ( bChangeTree )
{
if ( GetSectree ( ) )
GetSectree ( ) - > RemoveEntity ( this ) ;
ViewCleanup ( ) ;
}
if ( ! IsNPC ( ) )
{
sys_log ( 0 , " SHOW: %s %dx%dx%d " , GetName ( ) , x , y , z ) ;
if ( GetStamina ( ) < GetMaxStamina ( ) )
StartAffectEvent ( ) ;
}
else if ( m_pkMobData )
{
m_pkMobInst - > m_posLastAttacked . x = x ;
m_pkMobInst - > m_posLastAttacked . y = y ;
m_pkMobInst - > m_posLastAttacked . z = z ;
}
if ( bShowSpawnMotion )
{
SET_BIT ( m_bAddChrState , ADD_CHARACTER_STATE_SPAWN ) ;
m_afAffectFlag . Set ( AFF_SPAWN ) ;
}
SetXYZ ( x , y , z ) ;
m_posDest . x = x ;
m_posDest . y = y ;
m_posDest . z = z ;
m_posStart . x = x ;
m_posStart . y = y ;
m_posStart . z = z ;
if ( bChangeTree )
{
EncodeInsertPacket ( this ) ;
sectree - > InsertEntity ( this ) ;
UpdateSectree ( ) ;
}
else
{
ViewReencode ( ) ;
sys_log ( 0 , " in same sectree " ) ;
}
REMOVE_BIT ( m_bAddChrState , ADD_CHARACTER_STATE_SPAWN ) ;
SetValidComboInterval ( 0 ) ;
return true ;
}
// BGM_INFO
struct BGMInfo
{
std : : string name ;
float vol ;
} ;
typedef std : : map < unsigned , BGMInfo > BGMInfoMap ;
static BGMInfoMap gs_bgmInfoMap ;
static bool gs_bgmVolEnable = false ;
void CHARACTER_SetBGMVolumeEnable ( )
{
gs_bgmVolEnable = true ;
sys_log ( 0 , " bgm_info.set_bgm_volume_enable " ) ;
}
void CHARACTER_AddBGMInfo ( unsigned mapIndex , const char * name , float vol )
{
BGMInfo newInfo ;
newInfo . name = name ;
newInfo . vol = vol ;
gs_bgmInfoMap [ mapIndex ] = newInfo ;
sys_log ( 0 , " bgm_info.add_info(%d, '%s', %f) " , mapIndex , name , vol ) ;
}
const BGMInfo & CHARACTER_GetBGMInfo ( unsigned mapIndex )
{
BGMInfoMap : : iterator f = gs_bgmInfoMap . find ( mapIndex ) ;
if ( gs_bgmInfoMap . end ( ) = = f )
{
static BGMInfo s_empty = { " " , 0.0f } ;
return s_empty ;
}
return f - > second ;
}
bool CHARACTER_IsBGMVolumeEnable ( )
{
return gs_bgmVolEnable ;
}
// END_OF_BGM_INFO
void CHARACTER : : MainCharacterPacket ( )
{
const unsigned mapIndex = GetMapIndex ( ) ;
const BGMInfo & bgmInfo = CHARACTER_GetBGMInfo ( mapIndex ) ;
// SUPPORT_BGM
if ( ! bgmInfo . name . empty ( ) )
{
if ( CHARACTER_IsBGMVolumeEnable ( ) )
{
sys_log ( 1 , " bgm_info.play_bgm_vol(%d, name='%s', vol=%f) " , mapIndex , bgmInfo . name . c_str ( ) , bgmInfo . vol ) ;
TPacketGCMainCharacter4_BGM_VOL mainChrPacket ;
mainChrPacket . header = HEADER_GC_MAIN_CHARACTER4_BGM_VOL ;
mainChrPacket . dwVID = m_vid ;
mainChrPacket . wRaceNum = GetRaceNum ( ) ;
mainChrPacket . lx = GetX ( ) ;
mainChrPacket . ly = GetY ( ) ;
mainChrPacket . lz = GetZ ( ) ;
mainChrPacket . empire = GetDesc ( ) - > GetEmpire ( ) ;
mainChrPacket . skill_group = GetSkillGroup ( ) ;
2022-03-05 19:59:39 +02:00
strncpy ( mainChrPacket . szChrName , GetName ( ) , sizeof ( mainChrPacket . szChrName ) ) ;
2022-03-05 12:44:06 +02:00
mainChrPacket . fBGMVol = bgmInfo . vol ;
2022-03-05 19:59:39 +02:00
strncpy ( mainChrPacket . szBGMName , bgmInfo . name . c_str ( ) , sizeof ( mainChrPacket . szBGMName ) ) ;
2022-03-05 12:44:06 +02:00
GetDesc ( ) - > Packet ( & mainChrPacket , sizeof ( TPacketGCMainCharacter4_BGM_VOL ) ) ;
}
else
{
sys_log ( 1 , " bgm_info.play(%d, '%s') " , mapIndex , bgmInfo . name . c_str ( ) ) ;
TPacketGCMainCharacter3_BGM mainChrPacket ;
mainChrPacket . header = HEADER_GC_MAIN_CHARACTER3_BGM ;
mainChrPacket . dwVID = m_vid ;
mainChrPacket . wRaceNum = GetRaceNum ( ) ;
mainChrPacket . lx = GetX ( ) ;
mainChrPacket . ly = GetY ( ) ;
mainChrPacket . lz = GetZ ( ) ;
mainChrPacket . empire = GetDesc ( ) - > GetEmpire ( ) ;
mainChrPacket . skill_group = GetSkillGroup ( ) ;
2022-03-05 19:59:39 +02:00
strncpy ( mainChrPacket . szChrName , GetName ( ) , sizeof ( mainChrPacket . szChrName ) ) ;
strncpy ( mainChrPacket . szBGMName , bgmInfo . name . c_str ( ) , sizeof ( mainChrPacket . szBGMName ) ) ;
2022-03-05 12:44:06 +02:00
GetDesc ( ) - > Packet ( & mainChrPacket , sizeof ( TPacketGCMainCharacter3_BGM ) ) ;
}
//if (m_stMobile.length())
// ChatPacket(CHAT_TYPE_COMMAND, "sms");
}
// END_OF_SUPPORT_BGM
else
{
sys_log ( 0 , " bgm_info.play(%d, DEFAULT_BGM_NAME) " , mapIndex ) ;
TPacketGCMainCharacter pack ;
pack . header = HEADER_GC_MAIN_CHARACTER ;
pack . dwVID = m_vid ;
pack . wRaceNum = GetRaceNum ( ) ;
pack . lx = GetX ( ) ;
pack . ly = GetY ( ) ;
pack . lz = GetZ ( ) ;
pack . empire = GetDesc ( ) - > GetEmpire ( ) ;
pack . skill_group = GetSkillGroup ( ) ;
2022-03-05 19:59:39 +02:00
strncpy ( pack . szName , GetName ( ) , sizeof ( pack . szName ) ) ;
2022-03-05 12:44:06 +02:00
GetDesc ( ) - > Packet ( & pack , sizeof ( TPacketGCMainCharacter ) ) ;
if ( m_stMobile . length ( ) )
ChatPacket ( CHAT_TYPE_COMMAND , " sms " ) ;
}
}
void CHARACTER : : PointsPacket ( )
{
if ( ! GetDesc ( ) )
return ;
TPacketGCPoints pack ;
pack . header = HEADER_GC_CHARACTER_POINTS ;
pack . points [ POINT_LEVEL ] = GetLevel ( ) ;
pack . points [ POINT_EXP ] = GetExp ( ) ;
pack . points [ POINT_NEXT_EXP ] = GetNextExp ( ) ;
pack . points [ POINT_HP ] = GetHP ( ) ;
pack . points [ POINT_MAX_HP ] = GetMaxHP ( ) ;
pack . points [ POINT_SP ] = GetSP ( ) ;
pack . points [ POINT_MAX_SP ] = GetMaxSP ( ) ;
pack . points [ POINT_GOLD ] = GetGold ( ) ;
pack . points [ POINT_STAMINA ] = GetStamina ( ) ;
pack . points [ POINT_MAX_STAMINA ] = GetMaxStamina ( ) ;
for ( int i = POINT_ST ; i < POINT_MAX_NUM ; + + i )
pack . points [ i ] = GetPoint ( i ) ;
GetDesc ( ) - > Packet ( & pack , sizeof ( TPacketGCPoints ) ) ;
}
bool CHARACTER : : ChangeSex ( )
{
int src_race = GetRaceNum ( ) ;
switch ( src_race )
{
case MAIN_RACE_WARRIOR_M :
m_points . job = MAIN_RACE_WARRIOR_W ;
break ;
case MAIN_RACE_WARRIOR_W :
m_points . job = MAIN_RACE_WARRIOR_M ;
break ;
case MAIN_RACE_ASSASSIN_M :
m_points . job = MAIN_RACE_ASSASSIN_W ;
break ;
case MAIN_RACE_ASSASSIN_W :
m_points . job = MAIN_RACE_ASSASSIN_M ;
break ;
case MAIN_RACE_SURA_M :
m_points . job = MAIN_RACE_SURA_W ;
break ;
case MAIN_RACE_SURA_W :
m_points . job = MAIN_RACE_SURA_M ;
break ;
case MAIN_RACE_SHAMAN_M :
m_points . job = MAIN_RACE_SHAMAN_W ;
break ;
case MAIN_RACE_SHAMAN_W :
m_points . job = MAIN_RACE_SHAMAN_M ;
break ;
default :
sys_err ( " CHANGE_SEX: %s unknown race %d " , GetName ( ) , src_race ) ;
return false ;
}
sys_log ( 0 , " CHANGE_SEX: %s (%d -> %d) " , GetName ( ) , src_race , m_points . job ) ;
return true ;
}
WORD CHARACTER : : GetRaceNum ( ) const
{
if ( m_dwPolymorphRace )
return m_dwPolymorphRace ;
if ( m_pkMobData )
return m_pkMobData - > m_table . dwVnum ;
return m_points . job ;
}
void CHARACTER : : SetRace ( BYTE race )
{
if ( race > = MAIN_RACE_MAX_NUM )
{
sys_err ( " CHARACTER::SetRace(name=%s, race=%d).OUT_OF_RACE_RANGE " , GetName ( ) , race ) ;
return ;
}
m_points . job = race ;
}
BYTE CHARACTER : : GetJob ( ) const
{
unsigned race = m_points . job ;
unsigned job ;
if ( RaceToJob ( race , & job ) )
return job ;
sys_err ( " CHARACTER::GetJob(name=%s, race=%d).OUT_OF_RACE_RANGE " , GetName ( ) , race ) ;
return JOB_WARRIOR ;
}
void CHARACTER : : SetLevel ( BYTE level )
{
m_points . level = level ;
if ( IsPC ( ) )
{
if ( level < PK_PROTECT_LEVEL )
SetPKMode ( PK_MODE_PROTECT ) ;
else if ( GetGMLevel ( ) ! = GM_PLAYER )
SetPKMode ( PK_MODE_PROTECT ) ;
else if ( m_bPKMode = = PK_MODE_PROTECT )
SetPKMode ( PK_MODE_PEACE ) ;
}
}
void CHARACTER : : SetEmpire ( BYTE bEmpire )
{
m_bEmpire = bEmpire ;
}
void CHARACTER : : SetPlayerProto ( const TPlayerTable * t )
{
if ( ! GetDesc ( ) | | ! * GetDesc ( ) - > GetHostName ( ) )
sys_err ( " cannot get desc or hostname " ) ;
else
SetGMLevel ( ) ;
m_bCharType = CHAR_TYPE_PC ;
m_dwPlayerID = t - > id ;
m_iAlignment = t - > lAlignment ;
m_iRealAlignment = t - > lAlignment ;
m_points . voice = t - > voice ;
m_points . skill_group = t - > skill_group ;
m_pointsInstant . bBasePart = t - > part_base ;
SetPart ( PART_HAIR , t - > parts [ PART_HAIR ] ) ;
m_points . iRandomHP = t - > sRandomHP ;
m_points . iRandomSP = t - > sRandomSP ;
// REMOVE_REAL_SKILL_LEVLES
if ( m_pSkillLevels )
M2_DELETE_ARRAY ( m_pSkillLevels ) ;
m_pSkillLevels = M2_NEW TPlayerSkill [ SKILL_MAX_NUM ] ;
2022-03-06 17:36:43 +02:00
memcpy ( m_pSkillLevels , t - > skills , sizeof ( TPlayerSkill ) * SKILL_MAX_NUM ) ;
2022-03-05 12:44:06 +02:00
// END_OF_REMOVE_REAL_SKILL_LEVLES
if ( t - > lMapIndex > = 10000 )
{
m_posWarp . x = t - > lExitX ;
m_posWarp . y = t - > lExitY ;
m_lWarpMapIndex = t - > lExitMapIndex ;
}
SetRealPoint ( POINT_PLAYTIME , t - > playtime ) ;
m_dwLoginPlayTime = t - > playtime ;
SetRealPoint ( POINT_ST , t - > st ) ;
SetRealPoint ( POINT_HT , t - > ht ) ;
SetRealPoint ( POINT_DX , t - > dx ) ;
SetRealPoint ( POINT_IQ , t - > iq ) ;
SetPoint ( POINT_ST , t - > st ) ;
SetPoint ( POINT_HT , t - > ht ) ;
SetPoint ( POINT_DX , t - > dx ) ;
SetPoint ( POINT_IQ , t - > iq ) ;
SetPoint ( POINT_STAT , t - > stat_point ) ;
SetPoint ( POINT_SKILL , t - > skill_point ) ;
SetPoint ( POINT_SUB_SKILL , t - > sub_skill_point ) ;
SetPoint ( POINT_HORSE_SKILL , t - > horse_skill_point ) ;
SetPoint ( POINT_STAT_RESET_COUNT , t - > stat_reset_count ) ;
SetPoint ( POINT_LEVEL_STEP , t - > level_step ) ;
SetRealPoint ( POINT_LEVEL_STEP , t - > level_step ) ;
SetRace ( t - > job ) ;
SetLevel ( t - > level ) ;
SetExp ( t - > exp ) ;
SetGold ( t - > gold ) ;
SetMapIndex ( t - > lMapIndex ) ;
SetXYZ ( t - > x , t - > y , t - > z ) ;
ComputePoints ( ) ;
SetHP ( t - > hp ) ;
SetSP ( t - > sp ) ;
SetStamina ( t - > stamina ) ;
//GM<47> ϶<EFBFBD> <20> <> ȣ <EFBFBD> <C8A3> <EFBFBD> <EFBFBD>
if ( ! test_server )
{
if ( GetGMLevel ( ) > GM_LOW_WIZARD )
{
m_afAffectFlag . Set ( AFF_YMIR ) ;
m_bPKMode = PK_MODE_PROTECT ;
}
}
if ( GetLevel ( ) < PK_PROTECT_LEVEL )
m_bPKMode = PK_MODE_PROTECT ;
m_stMobile = t - > szMobile ;
SetHorseData ( t - > horse ) ;
if ( GetHorseLevel ( ) > 0 )
UpdateHorseDataByLogoff ( t - > logoff_interval ) ;
2022-03-06 17:36:43 +02:00
memcpy ( m_aiPremiumTimes , t - > aiPremiumTimes , sizeof ( t - > aiPremiumTimes ) ) ;
2022-03-05 12:44:06 +02:00
m_dwLogOffInterval = t - > logoff_interval ;
sys_log ( 0 , " PLAYER_LOAD: %s PREMIUM %d %d, LOGGOFF_INTERVAL %u PTR: %p " , t - > name , m_aiPremiumTimes [ 0 ] , m_aiPremiumTimes [ 1 ] , t - > logoff_interval , this ) ;
if ( GetGMLevel ( ) ! = GM_PLAYER )
{
LogManager : : instance ( ) . CharLog ( this , GetGMLevel ( ) , " GM_LOGIN " , " " ) ;
sys_log ( 0 , " GM_LOGIN(gmlevel=%d, name=%s(%d), pos=(%d, %d) " , GetGMLevel ( ) , GetName ( ) , GetPlayerID ( ) , GetX ( ) , GetY ( ) ) ;
}
# ifdef __PET_SYSTEM__
// NOTE: <20> ϴ<EFBFBD> ij<> <C4B3> <EFBFBD> Ͱ<EFBFBD> PC<50> <43> <20> <> <EFBFBD> 쿡<EFBFBD> <ECBFA1> PetSystem<65> <6D> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> . <20> <> <EFBFBD> <EFBFBD> <20> ӽŴ<D3BD> <20> <EFBFBD> <DEB8> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> NPC<50> <43> <EFBFBD> <EFBFBD> <20> ϱ <EFBFBD> <20> <> ..
if ( m_petSystem )
{
m_petSystem - > Destroy ( ) ;
delete m_petSystem ;
}
m_petSystem = M2_NEW CPetSystem ( this ) ;
# endif
}
EVENTFUNC ( kill_ore_load_event )
{
char_event_info * info = dynamic_cast < char_event_info * > ( event - > info ) ;
if ( info = = NULL )
{
sys_err ( " kill_ore_load_even> <Factor> Null pointer " ) ;
return 0 ;
}
LPCHARACTER ch = info - > ch ;
if ( ch = = NULL ) { // <Factor>
return 0 ;
}
ch - > m_pkMiningEvent = NULL ;
M2_DESTROY_CHARACTER ( ch ) ;
return 0 ;
}
void CHARACTER : : SetProto ( const CMob * pkMob )
{
if ( m_pkMobInst )
M2_DELETE ( m_pkMobInst ) ;
m_pkMobData = pkMob ;
m_pkMobInst = M2_NEW CMobInstance ;
m_bPKMode = PK_MODE_FREE ;
const TMobTable * t = & m_pkMobData - > m_table ;
m_bCharType = t - > bType ;
SetLevel ( t - > bLevel ) ;
SetEmpire ( t - > bEmpire ) ;
SetExp ( t - > dwExp ) ;
SetRealPoint ( POINT_ST , t - > bStr ) ;
SetRealPoint ( POINT_DX , t - > bDex ) ;
SetRealPoint ( POINT_HT , t - > bCon ) ;
SetRealPoint ( POINT_IQ , t - > bInt ) ;
ComputePoints ( ) ;
SetHP ( GetMaxHP ( ) ) ;
SetSP ( GetMaxSP ( ) ) ;
////////////////////
m_pointsInstant . dwAIFlag = t - > dwAIFlag ;
SetImmuneFlag ( t - > dwImmuneFlag ) ;
AssignTriggers ( t ) ;
ApplyMobAttribute ( t ) ;
if ( IsStone ( ) )
{
DetermineDropMetinStone ( ) ;
}
if ( IsWarp ( ) | | IsGoto ( ) )
{
StartWarpNPCEvent ( ) ;
}
CHARACTER_MANAGER : : instance ( ) . RegisterRaceNumMap ( this ) ;
// XXX X-mas santa hardcoding
if ( GetRaceNum ( ) = = xmas : : MOB_SANTA_VNUM )
{
SetPoint ( POINT_ATT_GRADE_BONUS , 10 ) ;
if ( g_iUseLocale )
SetPoint ( POINT_DEF_GRADE_BONUS , 6 ) ;
else
SetPoint ( POINT_DEF_GRADE_BONUS , 15 ) ;
//<2F> <> Ÿ<EFBFBD> <C5B8>
//m_dwPlayStartTime = get_dword_time() + 10 * 60 * 1000;
//<2F> ż<EFBFBD> <C5BC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
m_dwPlayStartTime = get_dword_time ( ) + 30 * 1000 ;
if ( test_server )
m_dwPlayStartTime = get_dword_time ( ) + 30 * 1000 ;
}
// XXX CTF GuildWar hardcoding
if ( warmap : : IsWarFlag ( GetRaceNum ( ) ) )
{
m_stateIdle . Set ( this , & CHARACTER : : BeginStateEmpty , & CHARACTER : : StateFlag , & CHARACTER : : EndStateEmpty ) ;
m_stateMove . Set ( this , & CHARACTER : : BeginStateEmpty , & CHARACTER : : StateFlag , & CHARACTER : : EndStateEmpty ) ;
m_stateBattle . Set ( this , & CHARACTER : : BeginStateEmpty , & CHARACTER : : StateFlag , & CHARACTER : : EndStateEmpty ) ;
}
if ( warmap : : IsWarFlagBase ( GetRaceNum ( ) ) )
{
m_stateIdle . Set ( this , & CHARACTER : : BeginStateEmpty , & CHARACTER : : StateFlagBase , & CHARACTER : : EndStateEmpty ) ;
m_stateMove . Set ( this , & CHARACTER : : BeginStateEmpty , & CHARACTER : : StateFlagBase , & CHARACTER : : EndStateEmpty ) ;
m_stateBattle . Set ( this , & CHARACTER : : BeginStateEmpty , & CHARACTER : : StateFlagBase , & CHARACTER : : EndStateEmpty ) ;
}
if ( m_bCharType = = CHAR_TYPE_HORSE | |
GetRaceNum ( ) = = 20101 | |
GetRaceNum ( ) = = 20102 | |
GetRaceNum ( ) = = 20103 | |
GetRaceNum ( ) = = 20104 | |
GetRaceNum ( ) = = 20105 | |
GetRaceNum ( ) = = 20106 | |
GetRaceNum ( ) = = 20107 | |
GetRaceNum ( ) = = 20108 | |
GetRaceNum ( ) = = 20109
)
{
m_stateIdle . Set ( this , & CHARACTER : : BeginStateEmpty , & CHARACTER : : StateHorse , & CHARACTER : : EndStateEmpty ) ;
m_stateMove . Set ( this , & CHARACTER : : BeginStateEmpty , & CHARACTER : : StateMove , & CHARACTER : : EndStateEmpty ) ;
m_stateBattle . Set ( this , & CHARACTER : : BeginStateEmpty , & CHARACTER : : StateHorse , & CHARACTER : : EndStateEmpty ) ;
}
// MINING
if ( mining : : IsVeinOfOre ( GetRaceNum ( ) ) )
{
char_event_info * info = AllocEventInfo < char_event_info > ( ) ;
info - > ch = this ;
2022-11-27 14:36:04 +02:00
m_pkMiningEvent = event_create ( kill_ore_load_event , info , PASSES_PER_SEC ( Random : : get ( 7 * 60 , 15 * 60 ) ) ) ;
2022-03-05 12:44:06 +02:00
}
// END_OF_MINING
}
const TMobTable & CHARACTER : : GetMobTable ( ) const
{
return m_pkMobData - > m_table ;
}
bool CHARACTER : : IsRaceFlag ( DWORD dwBit ) const
{
return m_pkMobData ? IS_SET ( m_pkMobData - > m_table . dwRaceFlag , dwBit ) : 0 ;
}
DWORD CHARACTER : : GetMobDamageMin ( ) const
{
return m_pkMobData - > m_table . dwDamageRange [ 0 ] ;
}
DWORD CHARACTER : : GetMobDamageMax ( ) const
{
return m_pkMobData - > m_table . dwDamageRange [ 1 ] ;
}
float CHARACTER : : GetMobDamageMultiply ( ) const
{
float fDamMultiply = GetMobTable ( ) . fDamMultiply ;
if ( IsBerserk ( ) )
fDamMultiply = fDamMultiply * 2.0f ; // BALANCE: <20> <> <EFBFBD> <EFBFBD> ȭ <20> <> <20> ι <EFBFBD>
return fDamMultiply ;
}
DWORD CHARACTER : : GetMobDropItemVnum ( ) const
{
return m_pkMobData - > m_table . dwDropItemVnum ;
}
bool CHARACTER : : IsSummonMonster ( ) const
{
return GetSummonVnum ( ) ! = 0 ;
}
DWORD CHARACTER : : GetSummonVnum ( ) const
{
return m_pkMobData ? m_pkMobData - > m_table . dwSummonVnum : 0 ;
}
DWORD CHARACTER : : GetPolymorphItemVnum ( ) const
{
return m_pkMobData ? m_pkMobData - > m_table . dwPolymorphItemVnum : 0 ;
}
DWORD CHARACTER : : GetMonsterDrainSPPoint ( ) const
{
return m_pkMobData ? m_pkMobData - > m_table . dwDrainSP : 0 ;
}
BYTE CHARACTER : : GetMobRank ( ) const
{
if ( ! m_pkMobData )
return MOB_RANK_KNIGHT ; // PC<50> <43> <20> <> <EFBFBD> <EFBFBD> KNIGHT<48> <54>
return m_pkMobData - > m_table . bRank ;
}
BYTE CHARACTER : : GetMobSize ( ) const
{
if ( ! m_pkMobData )
return MOBSIZE_MEDIUM ;
return m_pkMobData - > m_table . bSize ;
}
WORD CHARACTER : : GetMobAttackRange ( ) const
{
switch ( GetMobBattleType ( ) )
{
case BATTLE_TYPE_RANGE :
case BATTLE_TYPE_MAGIC :
return m_pkMobData - > m_table . wAttackRange + GetPoint ( POINT_BOW_DISTANCE ) ;
default :
return m_pkMobData - > m_table . wAttackRange ;
}
}
BYTE CHARACTER : : GetMobBattleType ( ) const
{
if ( ! m_pkMobData )
return BATTLE_TYPE_MELEE ;
return ( m_pkMobData - > m_table . bBattleType ) ;
}
void CHARACTER : : ComputeBattlePoints ( )
{
if ( IsPolymorphed ( ) )
{
DWORD dwMobVnum = GetPolymorphVnum ( ) ;
const CMob * pMob = CMobManager : : instance ( ) . Get ( dwMobVnum ) ;
int iAtt = 0 ;
int iDef = 0 ;
if ( pMob )
{
iAtt = GetLevel ( ) * 2 + GetPolymorphPoint ( POINT_ST ) * 2 ;
// lev + con
iDef = GetLevel ( ) + GetPolymorphPoint ( POINT_HT ) + pMob - > m_table . wDef ;
}
SetPoint ( POINT_ATT_GRADE , iAtt ) ;
SetPoint ( POINT_DEF_GRADE , iDef ) ;
SetPoint ( POINT_MAGIC_ATT_GRADE , GetPoint ( POINT_ATT_GRADE ) ) ;
SetPoint ( POINT_MAGIC_DEF_GRADE , GetPoint ( POINT_DEF_GRADE ) ) ;
}
else if ( IsPC ( ) )
{
SetPoint ( POINT_ATT_GRADE , 0 ) ;
SetPoint ( POINT_DEF_GRADE , 0 ) ;
SetPoint ( POINT_CLIENT_DEF_GRADE , 0 ) ;
SetPoint ( POINT_MAGIC_ATT_GRADE , GetPoint ( POINT_ATT_GRADE ) ) ;
SetPoint ( POINT_MAGIC_DEF_GRADE , GetPoint ( POINT_DEF_GRADE ) ) ;
//
// <20> ⺻ ATK = 2lev + 2str, <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> 2str<74> <72> <20> ٲ<EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD>
//
int iAtk = GetLevel ( ) * 2 ;
int iStatAtk = 0 ;
switch ( GetJob ( ) )
{
case JOB_WARRIOR :
case JOB_SURA :
iStatAtk = ( 2 * GetPoint ( POINT_ST ) ) ;
break ;
case JOB_ASSASSIN :
iStatAtk = ( 4 * GetPoint ( POINT_ST ) + 2 * GetPoint ( POINT_DX ) ) / 3 ;
break ;
case JOB_SHAMAN :
iStatAtk = ( 4 * GetPoint ( POINT_ST ) + 2 * GetPoint ( POINT_IQ ) ) / 3 ;
break ;
default :
sys_err ( " invalid job %d " , GetJob ( ) ) ;
iStatAtk = ( 2 * GetPoint ( POINT_ST ) ) ;
break ;
}
// <20> <> <EFBFBD> <EFBFBD> Ÿ<> <C5B8> <20> ְ<EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ݷ<EFBFBD> <DDB7> <EFBFBD> ST*2 <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ST*2<> <32> <20> Ѵ <EFBFBD> .
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ߸<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ݷ<EFBFBD> <DDB7> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> ʰ<EFBFBD> <20> ϱ <EFBFBD> <20> <> <EFBFBD> ؼ<EFBFBD> <D8BC> <EFBFBD> .
if ( GetMountVnum ( ) & & iStatAtk < 2 * GetPoint ( POINT_ST ) )
iStatAtk = ( 2 * GetPoint ( POINT_ST ) ) ;
iAtk + = iStatAtk ;
// <20> ¸ <EFBFBD> (<28> <> ) : <20> ˼<EFBFBD> <CBBC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
if ( GetMountVnum ( ) )
{
if ( GetJob ( ) = = JOB_SURA & & GetSkillGroup ( ) = = 1 )
{
iAtk + = ( iAtk * GetHorseLevel ( ) ) / 60 ;
}
else
{
iAtk + = ( iAtk * GetHorseLevel ( ) ) / 30 ;
}
}
//
// ATK Setting
//
iAtk + = GetPoint ( POINT_ATT_GRADE_BONUS ) ;
PointChange ( POINT_ATT_GRADE , iAtk ) ;
// DEF = LEV + CON + ARMOR
int iShowDef = GetLevel ( ) + GetPoint ( POINT_HT ) ; // For Ymir(õ<> <C3B5> )
int iDef = GetLevel ( ) + ( int ) ( GetPoint ( POINT_HT ) / 1.25 ) ; // For Other
int iArmor = 0 ;
LPITEM pkItem ;
for ( int i = 0 ; i < WEAR_MAX_NUM ; + + i )
if ( ( pkItem = GetWear ( i ) ) & & pkItem - > GetType ( ) = = ITEM_ARMOR )
{
if ( pkItem - > GetSubType ( ) = = ARMOR_BODY | | pkItem - > GetSubType ( ) = = ARMOR_HEAD | | pkItem - > GetSubType ( ) = = ARMOR_FOOTS | | pkItem - > GetSubType ( ) = = ARMOR_SHIELD )
{
iArmor + = pkItem - > GetValue ( 1 ) ;
iArmor + = ( 2 * pkItem - > GetValue ( 5 ) ) ;
}
}
// <20> <> Ÿ<> <C5B8> <20> <> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> º<EFBFBD> <C2BA> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
if ( true = = IsHorseRiding ( ) )
{
if ( iArmor < GetHorseArmor ( ) )
iArmor = GetHorseArmor ( ) ;
const char * pHorseName = CHorseNameManager : : instance ( ) . GetHorseName ( GetPlayerID ( ) ) ;
if ( pHorseName ! = NULL & & strlen ( pHorseName ) )
{
iArmor + = 20 ;
}
}
iArmor + = GetPoint ( POINT_DEF_GRADE_BONUS ) ;
iArmor + = GetPoint ( POINT_PARTY_DEFENDER_BONUS ) ;
// INTERNATIONAL_VERSION
if ( LC_IsYMIR ( ) )
{
PointChange ( POINT_DEF_GRADE , iShowDef + iArmor ) ;
}
else
{
PointChange ( POINT_DEF_GRADE , iDef + iArmor ) ;
PointChange ( POINT_CLIENT_DEF_GRADE , ( iShowDef + iArmor ) - GetPoint ( POINT_DEF_GRADE ) ) ;
}
// END_OF_INTERNATIONAL_VERSION
PointChange ( POINT_MAGIC_ATT_GRADE , GetLevel ( ) * 2 + GetPoint ( POINT_IQ ) * 2 + GetPoint ( POINT_MAGIC_ATT_GRADE_BONUS ) ) ;
PointChange ( POINT_MAGIC_DEF_GRADE , GetLevel ( ) + ( GetPoint ( POINT_IQ ) * 3 + GetPoint ( POINT_HT ) ) / 3 + iArmor / 2 + GetPoint ( POINT_MAGIC_DEF_GRADE_BONUS ) ) ;
}
else
{
// 2lev + str * 2
int iAtt = GetLevel ( ) * 2 + GetPoint ( POINT_ST ) * 2 ;
// lev + con
int iDef = GetLevel ( ) + GetPoint ( POINT_HT ) + GetMobTable ( ) . wDef ;
SetPoint ( POINT_ATT_GRADE , iAtt ) ;
SetPoint ( POINT_DEF_GRADE , iDef ) ;
SetPoint ( POINT_MAGIC_ATT_GRADE , GetPoint ( POINT_ATT_GRADE ) ) ;
SetPoint ( POINT_MAGIC_DEF_GRADE , GetPoint ( POINT_DEF_GRADE ) ) ;
}
}
void CHARACTER : : ComputePoints ( )
{
2022-03-12 11:39:41 +02:00
int lStat = GetPoint ( POINT_STAT ) ;
int lStatResetCount = GetPoint ( POINT_STAT_RESET_COUNT ) ;
int lSkillActive = GetPoint ( POINT_SKILL ) ;
int lSkillSub = GetPoint ( POINT_SUB_SKILL ) ;
int lSkillHorse = GetPoint ( POINT_HORSE_SKILL ) ;
int lLevelStep = GetPoint ( POINT_LEVEL_STEP ) ;
2022-03-05 12:44:06 +02:00
2022-03-12 11:39:41 +02:00
int lAttackerBonus = GetPoint ( POINT_PARTY_ATTACKER_BONUS ) ;
int lTankerBonus = GetPoint ( POINT_PARTY_TANKER_BONUS ) ;
int lBufferBonus = GetPoint ( POINT_PARTY_BUFFER_BONUS ) ;
int lSkillMasterBonus = GetPoint ( POINT_PARTY_SKILL_MASTER_BONUS ) ;
int lHasteBonus = GetPoint ( POINT_PARTY_HASTE_BONUS ) ;
int lDefenderBonus = GetPoint ( POINT_PARTY_DEFENDER_BONUS ) ;
2022-03-05 12:44:06 +02:00
2022-03-12 11:39:41 +02:00
int lHPRecovery = GetPoint ( POINT_HP_RECOVERY ) ;
int lSPRecovery = GetPoint ( POINT_SP_RECOVERY ) ;
2022-03-05 12:44:06 +02:00
memset ( m_pointsInstant . points , 0 , sizeof ( m_pointsInstant . points ) ) ;
BuffOnAttr_ClearAll ( ) ;
m_SkillDamageBonus . clear ( ) ;
SetPoint ( POINT_STAT , lStat ) ;
SetPoint ( POINT_SKILL , lSkillActive ) ;
SetPoint ( POINT_SUB_SKILL , lSkillSub ) ;
SetPoint ( POINT_HORSE_SKILL , lSkillHorse ) ;
SetPoint ( POINT_LEVEL_STEP , lLevelStep ) ;
SetPoint ( POINT_STAT_RESET_COUNT , lStatResetCount ) ;
SetPoint ( POINT_ST , GetRealPoint ( POINT_ST ) ) ;
SetPoint ( POINT_HT , GetRealPoint ( POINT_HT ) ) ;
SetPoint ( POINT_DX , GetRealPoint ( POINT_DX ) ) ;
SetPoint ( POINT_IQ , GetRealPoint ( POINT_IQ ) ) ;
SetPart ( PART_MAIN , GetOriginalPart ( PART_MAIN ) ) ;
SetPart ( PART_WEAPON , GetOriginalPart ( PART_WEAPON ) ) ;
SetPart ( PART_HEAD , GetOriginalPart ( PART_HEAD ) ) ;
SetPart ( PART_HAIR , GetOriginalPart ( PART_HAIR ) ) ;
SetPoint ( POINT_PARTY_ATTACKER_BONUS , lAttackerBonus ) ;
SetPoint ( POINT_PARTY_TANKER_BONUS , lTankerBonus ) ;
SetPoint ( POINT_PARTY_BUFFER_BONUS , lBufferBonus ) ;
SetPoint ( POINT_PARTY_SKILL_MASTER_BONUS , lSkillMasterBonus ) ;
SetPoint ( POINT_PARTY_HASTE_BONUS , lHasteBonus ) ;
SetPoint ( POINT_PARTY_DEFENDER_BONUS , lDefenderBonus ) ;
SetPoint ( POINT_HP_RECOVERY , lHPRecovery ) ;
SetPoint ( POINT_SP_RECOVERY , lSPRecovery ) ;
// PC_BANG_ITEM_ADD
SetPoint ( POINT_PC_BANG_EXP_BONUS , 0 ) ;
SetPoint ( POINT_PC_BANG_DROP_BONUS , 0 ) ;
// END_PC_BANG_ITEM_ADD
int iMaxHP , iMaxSP ;
int iMaxStamina ;
if ( IsPC ( ) )
{
// <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> /<2F> <> <EFBFBD> ŷ<EFBFBD>
iMaxHP = JobInitialPoints [ GetJob ( ) ] . max_hp + m_points . iRandomHP + GetPoint ( POINT_HT ) * JobInitialPoints [ GetJob ( ) ] . hp_per_ht ;
iMaxSP = JobInitialPoints [ GetJob ( ) ] . max_sp + m_points . iRandomSP + GetPoint ( POINT_IQ ) * JobInitialPoints [ GetJob ( ) ] . sp_per_iq ;
iMaxStamina = JobInitialPoints [ GetJob ( ) ] . max_stamina + GetPoint ( POINT_HT ) * JobInitialPoints [ GetJob ( ) ] . stamina_per_con ;
{
CSkillProto * pkSk = CSkillManager : : instance ( ) . Get ( SKILL_ADD_HP ) ;
if ( NULL ! = pkSk )
{
pkSk - > SetPointVar ( " k " , 1.0f * GetSkillPower ( SKILL_ADD_HP ) / 100.0f ) ;
iMaxHP + = static_cast < int > ( pkSk - > kPointPoly . Eval ( ) ) ;
}
}
// <20> ⺻ <20> <> <EFBFBD> <EFBFBD>
SetPoint ( POINT_MOV_SPEED , 100 ) ;
SetPoint ( POINT_ATT_SPEED , 100 ) ;
PointChange ( POINT_ATT_SPEED , GetPoint ( POINT_PARTY_HASTE_BONUS ) ) ;
SetPoint ( POINT_CASTING_SPEED , 100 ) ;
}
else
{
iMaxHP = m_pkMobData - > m_table . dwMaxHP ;
iMaxSP = 0 ;
iMaxStamina = 0 ;
SetPoint ( POINT_ATT_SPEED , m_pkMobData - > m_table . sAttackSpeed ) ;
SetPoint ( POINT_MOV_SPEED , m_pkMobData - > m_table . sMovingSpeed ) ;
SetPoint ( POINT_CASTING_SPEED , m_pkMobData - > m_table . sAttackSpeed ) ;
}
if ( IsPC ( ) )
{
// <20> <> Ÿ<> <C5B8> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ⺻ <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> Ⱥ<EFBFBD> <C8BA> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> .
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ̹Ƿ<CCB9> , <20> <> <EFBFBD> <EFBFBD> /<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ü <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
// <20> <> ä<EFBFBD> <C3A4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> ö<C3B6> <20> <> <20> <> <EFBFBD> ̴<EFBFBD> .
if ( GetMountVnum ( ) )
{
if ( GetHorseST ( ) > GetPoint ( POINT_ST ) )
PointChange ( POINT_ST , GetHorseST ( ) - GetPoint ( POINT_ST ) ) ;
if ( GetHorseDX ( ) > GetPoint ( POINT_DX ) )
PointChange ( POINT_DX , GetHorseDX ( ) - GetPoint ( POINT_DX ) ) ;
if ( GetHorseHT ( ) > GetPoint ( POINT_HT ) )
PointChange ( POINT_HT , GetHorseHT ( ) - GetPoint ( POINT_HT ) ) ;
if ( GetHorseIQ ( ) > GetPoint ( POINT_IQ ) )
PointChange ( POINT_IQ , GetHorseIQ ( ) - GetPoint ( POINT_IQ ) ) ;
}
}
ComputeBattlePoints ( ) ;
// <20> ⺻ HP/SP <20> <> <EFBFBD> <EFBFBD>
if ( iMaxHP ! = GetMaxHP ( ) )
{
SetRealPoint ( POINT_MAX_HP , iMaxHP ) ; // <20> ⺻HP<48> <50> RealPoint<6E> <74> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ´ <EFBFBD> .
}
PointChange ( POINT_MAX_HP , 0 ) ;
if ( iMaxSP ! = GetMaxSP ( ) )
{
SetRealPoint ( POINT_MAX_SP , iMaxSP ) ; // <20> ⺻SP<53> <50> RealPoint<6E> <74> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ´ <EFBFBD> .
}
PointChange ( POINT_MAX_SP , 0 ) ;
SetMaxStamina ( iMaxStamina ) ;
m_pointsInstant . dwImmuneFlag = 0 ;
for ( int i = 0 ; i < WEAR_MAX_NUM ; i + + )
{
LPITEM pItem = GetWear ( i ) ;
if ( pItem )
{
pItem - > ModifyPoints ( true ) ;
SET_BIT ( m_pointsInstant . dwImmuneFlag , GetWear ( i ) - > GetImmuneFlag ( ) ) ;
}
}
// <20> <> ȥ<EFBFBD> <C8A5> <20> ý<EFBFBD> <C3BD> <EFBFBD>
// ComputePoints<74> <73> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ɸ<EFBFBD> <C9B8> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> Ӽ<EFBFBD> <D3BC> <EFBFBD> <EFBFBD> <EFBFBD> <20> ʱ<EFBFBD> ȭ<EFBFBD> ϰ<EFBFBD> ,
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <20> <20> <> <EFBFBD> õ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> Ӽ<EFBFBD> <D3BC> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ϱ <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ,
// <20> <> ȥ<EFBFBD> <C8A5> <20> ý<EFBFBD> <C3BD> ۵ <EFBFBD> ActiveDeck<63> <6B> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ȥ<EFBFBD> <C8A5> <EFBFBD> <EFBFBD> <20> Ӽ<EFBFBD> <D3BC> <EFBFBD> <EFBFBD> <EFBFBD> <20> ٽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ѿ<EFBFBD> <20> Ѵ <EFBFBD> .
if ( DragonSoul_IsDeckActivated ( ) )
{
for ( int i = WEAR_MAX_NUM + DS_SLOT_MAX * DragonSoul_GetActiveDeck ( ) ;
i < WEAR_MAX_NUM + DS_SLOT_MAX * ( DragonSoul_GetActiveDeck ( ) + 1 ) ; i + + )
{
LPITEM pItem = GetWear ( i ) ;
if ( pItem )
{
if ( DSManager : : instance ( ) . IsTimeLeftDragonSoul ( pItem ) )
pItem - > ModifyPoints ( true ) ;
}
}
}
if ( GetHP ( ) > GetMaxHP ( ) )
PointChange ( POINT_HP , GetMaxHP ( ) - GetHP ( ) ) ;
if ( GetSP ( ) > GetMaxSP ( ) )
PointChange ( POINT_SP , GetMaxSP ( ) - GetSP ( ) ) ;
ComputeSkillPoints ( ) ;
RefreshAffect ( ) ;
CPetSystem * pPetSystem = GetPetSystem ( ) ;
if ( NULL ! = pPetSystem )
{
pPetSystem - > RefreshBuff ( ) ;
}
for ( TMapBuffOnAttrs : : iterator it = m_map_buff_on_attrs . begin ( ) ; it ! = m_map_buff_on_attrs . end ( ) ; it + + )
{
it - > second - > GiveAllAttributes ( ) ;
}
UpdatePacket ( ) ;
}
// m_dwPlayStartTime<6D> <65> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> milisecond<6E> <64> . <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͺ <EFBFBD> <CDBA> ̽<EFBFBD> <CCBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> д<EFBFBD> <D0B4> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϱ <EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ÷<EFBFBD> <C3B7> ̽ð<CCBD> <C3B0> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> / 60000 <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ϴµ<CFB4> , <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
// <20> <> <20> <> <20> <> <EFBFBD> dwTimeRemain<69> <6E> <EFBFBD> <EFBFBD> <20> ־ <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ǵ<EFBFBD> <C7B5> <EFBFBD> <20> <> <EFBFBD> ־<EFBFBD> <D6BE> <EFBFBD> <20> Ѵ <EFBFBD> .
void CHARACTER : : ResetPlayTime ( DWORD dwTimeRemain )
{
m_dwPlayStartTime = get_dword_time ( ) - dwTimeRemain ;
}
const int aiRecoveryPercents [ 10 ] = { 1 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 } ;
EVENTFUNC ( recovery_event )
{
char_event_info * info = dynamic_cast < char_event_info * > ( event - > info ) ;
if ( info = = NULL )
{
sys_err ( " recovery_event> <Factor> Null pointer " ) ;
return 0 ;
}
LPCHARACTER ch = info - > ch ;
if ( ch = = NULL ) { // <Factor>
return 0 ;
}
if ( ! ch - > IsPC ( ) )
{
//
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ȸ<> <C8B8>
//
if ( ch - > IsAffectFlag ( AFF_POISON ) )
2022-11-27 22:18:08 +02:00
return PASSES_PER_SEC ( std : : max < int > ( 1 , ch - > GetMobTable ( ) . bRegenCycle ) ) ;
2022-03-05 12:44:06 +02:00
if ( 2493 = = ch - > GetMobTable ( ) . dwVnum )
{
int regenPct = BlueDragon_GetRangeFactor ( " hp_regen " , ch - > GetHPPct ( ) ) ;
regenPct + = ch - > GetMobTable ( ) . bRegenPercent ;
for ( int i = 1 ; i < = 4 ; + + i )
{
if ( REGEN_PECT_BONUS = = BlueDragon_GetIndexFactor ( " DragonStone " , i , " effect_type " ) )
{
DWORD dwDragonStoneID = BlueDragon_GetIndexFactor ( " DragonStone " , i , " vnum " ) ;
size_t val = BlueDragon_GetIndexFactor ( " DragonStone " , i , " val " ) ;
size_t cnt = SECTREE_MANAGER : : instance ( ) . GetMonsterCountInMap ( ch - > GetMapIndex ( ) , dwDragonStoneID ) ;
regenPct + = ( val * cnt ) ;
break ;
}
}
2022-11-27 22:18:08 +02:00
ch - > PointChange ( POINT_HP , std : : max ( 1 , ( ch - > GetMaxHP ( ) * regenPct ) / 100 ) ) ;
2022-03-05 12:44:06 +02:00
}
else if ( ! ch - > IsDoor ( ) )
{
2022-11-27 22:18:08 +02:00
ch - > MonsterLog ( " HP_REGEN +%d " , std : : max ( 1 , ( ch - > GetMaxHP ( ) * ch - > GetMobTable ( ) . bRegenPercent ) / 100 ) ) ;
ch - > PointChange ( POINT_HP , std : : max ( 1 , ( ch - > GetMaxHP ( ) * ch - > GetMobTable ( ) . bRegenPercent ) / 100 ) ) ;
2022-03-05 12:44:06 +02:00
}
if ( ch - > GetHP ( ) > = ch - > GetMaxHP ( ) )
{
ch - > m_pkRecoveryEvent = NULL ;
return 0 ;
}
if ( 2493 = = ch - > GetMobTable ( ) . dwVnum )
{
for ( int i = 1 ; i < = 4 ; + + i )
{
if ( REGEN_TIME_BONUS = = BlueDragon_GetIndexFactor ( " DragonStone " , i , " effect_type " ) )
{
DWORD dwDragonStoneID = BlueDragon_GetIndexFactor ( " DragonStone " , i , " vnum " ) ;
size_t val = BlueDragon_GetIndexFactor ( " DragonStone " , i , " val " ) ;
size_t cnt = SECTREE_MANAGER : : instance ( ) . GetMonsterCountInMap ( ch - > GetMapIndex ( ) , dwDragonStoneID ) ;
2022-11-27 22:18:08 +02:00
return PASSES_PER_SEC ( std : : max < int > ( 1 , ( ch - > GetMobTable ( ) . bRegenCycle - ( val * cnt ) ) ) ) ;
2022-03-05 12:44:06 +02:00
}
}
}
2022-11-27 22:18:08 +02:00
return PASSES_PER_SEC ( std : : max < int > ( 1 , ch - > GetMobTable ( ) . bRegenCycle ) ) ;
2022-03-05 12:44:06 +02:00
}
else
{
//
// PC ȸ<> <C8B8>
//
ch - > CheckTarget ( ) ;
//ch->UpdateSectree(); // <20> <> <EFBFBD> ⼭ <20> ̰<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ?
ch - > UpdateKillerMode ( ) ;
if ( ch - > IsAffectFlag ( AFF_POISON ) = = true )
{
// <20> ߵ <EFBFBD> <DFB5> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ڵ<EFBFBD> ȸ<EFBFBD> <C8B8> <20> <> <EFBFBD> <EFBFBD>
// <20> Ĺ<EFBFBD> <C4B9> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ڵ<EFBFBD> ȸ<EFBFBD> <C8B8> <20> <> <EFBFBD> <EFBFBD>
return 3 ;
}
int iSec = ( get_dword_time ( ) - ch - > GetLastMoveTime ( ) ) / 3000 ;
// SP ȸ<> <C8B8> <20> <> ƾ.
// <20> <> <20> ̰ɷ<CCB0> <20> ؼ<EFBFBD> <20> Լ<EFBFBD> <D4BC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> °<EFBFBD> ?!
ch - > DistributeSP ( ch ) ;
if ( ch - > GetMaxHP ( ) < = ch - > GetHP ( ) )
return PASSES_PER_SEC ( 3 ) ;
int iPercent = 0 ;
int iAmount = 0 ;
{
2022-11-27 22:18:08 +02:00
iPercent = aiRecoveryPercents [ std : : min ( 9 , iSec ) ] ;
2022-03-05 12:44:06 +02:00
iAmount = 15 + ( ch - > GetMaxHP ( ) * iPercent ) / 100 ;
}
iAmount + = ( iAmount * ch - > GetPoint ( POINT_HP_REGEN ) ) / 100 ;
sys_log ( 1 , " RECOVERY_EVENT: %s %d HP_REGEN %d HP +%d " , ch - > GetName ( ) , iPercent , ch - > GetPoint ( POINT_HP_REGEN ) , iAmount ) ;
ch - > PointChange ( POINT_HP , iAmount , false ) ;
return PASSES_PER_SEC ( 3 ) ;
}
}
void CHARACTER : : StartRecoveryEvent ( )
{
if ( m_pkRecoveryEvent )
return ;
if ( IsDead ( ) | | IsStun ( ) )
return ;
if ( IsNPC ( ) & & GetHP ( ) > = GetMaxHP ( ) ) // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> ü<> <C3BC> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> Ѵ <EFBFBD> .
return ;
char_event_info * info = AllocEventInfo < char_event_info > ( ) ;
info - > ch = this ;
2022-11-27 22:18:08 +02:00
int iSec = IsPC ( ) ? 3 : ( std : : max < int > ( 1 , GetMobTable ( ) . bRegenCycle ) ) ;
2022-03-05 12:44:06 +02:00
m_pkRecoveryEvent = event_create ( recovery_event , info , PASSES_PER_SEC ( iSec ) ) ;
}
void CHARACTER : : Standup ( )
{
struct packet_position pack_position ;
if ( ! IsPosition ( POS_SITTING ) )
return ;
SetPosition ( POS_STANDING ) ;
sys_log ( 1 , " STANDUP: %s " , GetName ( ) ) ;
pack_position . header = HEADER_GC_CHARACTER_POSITION ;
pack_position . vid = GetVID ( ) ;
pack_position . position = POSITION_GENERAL ;
PacketAround ( & pack_position , sizeof ( pack_position ) ) ;
}
void CHARACTER : : Sitdown ( int is_ground )
{
struct packet_position pack_position ;
if ( IsPosition ( POS_SITTING ) )
return ;
SetPosition ( POS_SITTING ) ;
sys_log ( 1 , " SITDOWN: %s " , GetName ( ) ) ;
pack_position . header = HEADER_GC_CHARACTER_POSITION ;
pack_position . vid = GetVID ( ) ;
pack_position . position = POSITION_SITTING_GROUND ;
PacketAround ( & pack_position , sizeof ( pack_position ) ) ;
}
void CHARACTER : : SetRotation ( float fRot )
{
m_pointsInstant . fRot = fRot ;
}
// x, y <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> .
2022-03-12 11:39:41 +02:00
void CHARACTER : : SetRotationToXY ( int x , int y )
2022-03-05 12:44:06 +02:00
{
SetRotation ( GetDegreeFromPositionXY ( GetX ( ) , GetY ( ) , x , y ) ) ;
}
bool CHARACTER : : CannotMoveByAffect ( ) const
{
return ( IsAffectFlag ( AFF_STUN ) ) ;
}
bool CHARACTER : : CanMove ( ) const
{
if ( CannotMoveByAffect ( ) )
return false ;
if ( GetMyShop ( ) ) // <20> <> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> ¿<EFBFBD> <C2BF> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD>
return false ;
// 0.2<EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̶<EFBFBD> <CCB6> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> .
/*
if ( get_float_time ( ) - m_fSyncTime < 0.2f )
return false ;
*/
return true ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> x, y <20> <> ġ<EFBFBD> <C4A1> <20> ̵<EFBFBD> <20> <> Ų<EFBFBD> <C5B2> .
2022-03-12 11:39:41 +02:00
bool CHARACTER : : Sync ( int x , int y )
2022-03-05 12:44:06 +02:00
{
if ( ! GetSectree ( ) )
return false ;
LPSECTREE new_tree = SECTREE_MANAGER : : instance ( ) . Get ( GetMapIndex ( ) , x , y ) ;
if ( ! new_tree )
{
if ( GetDesc ( ) )
{
sys_err ( " cannot find tree at %d %d (name: %s) " , x , y , GetName ( ) ) ;
GetDesc ( ) - > SetPhase ( PHASE_CLOSE ) ;
}
else
{
sys_err ( " no tree: %s %d %d %d " , GetName ( ) , x , y , GetMapIndex ( ) ) ;
Dead ( ) ;
}
return false ;
}
SetRotationToXY ( x , y ) ;
SetXYZ ( x , y , 0 ) ;
if ( GetDungeon ( ) )
{
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̺<EFBFBD> Ʈ <20> Ӽ<EFBFBD> <20> <> ȭ
int iLastEventAttr = m_iEventAttr ;
m_iEventAttr = new_tree - > GetEventAttribute ( x , y ) ;
if ( m_iEventAttr ! = iLastEventAttr )
{
if ( GetParty ( ) )
{
quest : : CQuestManager : : instance ( ) . AttrOut ( GetParty ( ) - > GetLeaderPID ( ) , this , iLastEventAttr ) ;
quest : : CQuestManager : : instance ( ) . AttrIn ( GetParty ( ) - > GetLeaderPID ( ) , this , m_iEventAttr ) ;
}
else
{
quest : : CQuestManager : : instance ( ) . AttrOut ( GetPlayerID ( ) , this , iLastEventAttr ) ;
quest : : CQuestManager : : instance ( ) . AttrIn ( GetPlayerID ( ) , this , m_iEventAttr ) ;
}
}
}
if ( GetSectree ( ) ! = new_tree )
{
if ( ! IsNPC ( ) )
{
SECTREEID id = new_tree - > GetID ( ) ;
SECTREEID old_id = GetSectree ( ) - > GetID ( ) ;
sys_log ( 0 , " SECTREE DIFFER: %s %dx%d was %dx%d " ,
GetName ( ) ,
id . coord . x ,
id . coord . y ,
old_id . coord . x ,
old_id . coord . y ) ;
}
new_tree - > InsertEntity ( this ) ;
}
return true ;
}
void CHARACTER : : Stop ( )
{
if ( ! IsState ( m_stateIdle ) )
MonsterLog ( " [IDLE] <20> <> <EFBFBD> <EFBFBD> " ) ;
GotoState ( m_stateIdle ) ;
m_posDest . x = m_posStart . x = GetX ( ) ;
m_posDest . y = m_posStart . y = GetY ( ) ;
}
2022-03-12 11:39:41 +02:00
bool CHARACTER : : Goto ( int x , int y )
2022-03-05 12:44:06 +02:00
{
// TODO <20> Ÿ<EFBFBD> üũ <20> ʿ<EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> <20> <> ġ<EFBFBD> <C4A1> <20> ̵<EFBFBD> <CCB5> <EFBFBD> <20> ʿ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> (<28> ڵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> )
if ( GetX ( ) = = x & & GetY ( ) = = y )
return false ;
if ( m_posDest . x = = x & & m_posDest . y = = y )
{
if ( ! IsState ( m_stateMove ) )
{
m_dwStateDuration = 4 ;
GotoState ( m_stateMove ) ;
}
return false ;
}
m_posDest . x = x ;
m_posDest . y = y ;
CalculateMoveDuration ( ) ;
m_dwStateDuration = 4 ;
if ( ! IsState ( m_stateMove ) )
{
MonsterLog ( " [MOVE] %s " , GetVictim ( ) ? " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " : " <EFBFBD> ׳ <EFBFBD> <EFBFBD> ̵<EFBFBD> " ) ;
if ( GetVictim ( ) )
{
//MonsterChat(MONSTER_CHAT_CHASE);
MonsterChat ( MONSTER_CHAT_ATTACK ) ;
}
}
GotoState ( m_stateMove ) ;
return true ;
}
DWORD CHARACTER : : GetMotionMode ( ) const
{
DWORD dwMode = MOTION_MODE_GENERAL ;
if ( IsPolymorphed ( ) )
return dwMode ;
LPITEM pkItem ;
if ( ( pkItem = GetWear ( WEAR_WEAPON ) ) )
{
switch ( pkItem - > GetProto ( ) - > bSubType )
{
case WEAPON_SWORD :
dwMode = MOTION_MODE_ONEHAND_SWORD ;
break ;
case WEAPON_TWO_HANDED :
dwMode = MOTION_MODE_TWOHAND_SWORD ;
break ;
case WEAPON_DAGGER :
dwMode = MOTION_MODE_DUALHAND_SWORD ;
break ;
case WEAPON_BOW :
dwMode = MOTION_MODE_BOW ;
break ;
case WEAPON_BELL :
dwMode = MOTION_MODE_BELL ;
break ;
case WEAPON_FAN :
dwMode = MOTION_MODE_FAN ;
break ;
}
}
return dwMode ;
}
float CHARACTER : : GetMoveMotionSpeed ( ) const
{
DWORD dwMode = GetMotionMode ( ) ;
const CMotion * pkMotion = NULL ;
if ( ! GetMountVnum ( ) )
pkMotion = CMotionManager : : instance ( ) . GetMotion ( GetRaceNum ( ) , MAKE_MOTION_KEY ( dwMode , ( IsWalking ( ) & & IsPC ( ) ) ? MOTION_WALK : MOTION_RUN ) ) ;
else
{
pkMotion = CMotionManager : : instance ( ) . GetMotion ( GetMountVnum ( ) , MAKE_MOTION_KEY ( MOTION_MODE_GENERAL , ( IsWalking ( ) & & IsPC ( ) ) ? MOTION_WALK : MOTION_RUN ) ) ;
if ( ! pkMotion )
pkMotion = CMotionManager : : instance ( ) . GetMotion ( GetRaceNum ( ) , MAKE_MOTION_KEY ( MOTION_MODE_HORSE , ( IsWalking ( ) & & IsPC ( ) ) ? MOTION_WALK : MOTION_RUN ) ) ;
}
if ( pkMotion )
return - pkMotion - > GetAccumVector ( ) . y / pkMotion - > GetDuration ( ) ;
else
{
sys_err ( " cannot find motion (name %s race %d mode %d) " , GetName ( ) , GetRaceNum ( ) , dwMode ) ;
return 300.0f ;
}
}
float CHARACTER : : GetMoveSpeed ( ) const
{
return GetMoveMotionSpeed ( ) * 10000 / CalculateDuration ( GetLimitPoint ( POINT_MOV_SPEED ) , 10000 ) ;
}
void CHARACTER : : CalculateMoveDuration ( )
{
m_posStart . x = GetX ( ) ;
m_posStart . y = GetY ( ) ;
float fDist = DISTANCE_SQRT ( m_posStart . x - m_posDest . x , m_posStart . y - m_posDest . y ) ;
float motionSpeed = GetMoveMotionSpeed ( ) ;
m_dwMoveDuration = CalculateDuration ( GetLimitPoint ( POINT_MOV_SPEED ) ,
( int ) ( ( fDist / motionSpeed ) * 1000.0f ) ) ;
if ( IsNPC ( ) )
sys_log ( 1 , " %s: GOTO: distance %f, spd %u, duration %u, motion speed %f pos %d %d -> %d %d " ,
GetName ( ) , fDist , GetLimitPoint ( POINT_MOV_SPEED ) , m_dwMoveDuration , motionSpeed ,
m_posStart . x , m_posStart . y , m_posDest . x , m_posDest . y ) ;
m_dwMoveStartTime = get_dword_time ( ) ;
}
// x y <20> <> ġ<EFBFBD> <C4A1> <20> ̵<EFBFBD> <20> Ѵ <EFBFBD> . (<28> ̵<EFBFBD> <CCB5> <EFBFBD> <20> <> <20> ִ<EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> Ȯ<> <C8AE> <20> ϰ<EFBFBD> Sync <20> ҵ<DEBC> <D2B5> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ̵<EFBFBD> <20> Ѵ <EFBFBD> )
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> char<61> <72> x, y <20> <> <EFBFBD> <EFBFBD> <20> ٷ<EFBFBD> <20> ٲ<EFBFBD> <D9B2> <EFBFBD> <EFBFBD> <EFBFBD> ,
// Ŭ<> <EFBFBD> <F3BFA1BC> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ġ<EFBFBD> <C4A1> <EFBFBD> <EFBFBD> <20> ٲ<EFBFBD> x, y<> <79> <EFBFBD> <EFBFBD> interpolation<6F> Ѵ <EFBFBD> .
// <20> Ȱų<C8B0> <20> ٴ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> char<61> <72> m_bNowWalking<6E> <67> <20> <EFBFBD> <DEB7> ִ<EFBFBD> .
// Warp<72> <70> <20> ǵ<EFBFBD> <C7B5> <EFBFBD> <20> <> <EFBFBD> ̶<EFBFBD> <CCB6> <EFBFBD> Show<6F> <77> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> .
2022-03-12 11:39:41 +02:00
bool CHARACTER : : Move ( int x , int y )
2022-03-05 12:44:06 +02:00
{
// <20> <> <EFBFBD> <EFBFBD> <20> <> ġ<EFBFBD> <C4A1> <20> ̵<EFBFBD> <CCB5> <EFBFBD> <20> ʿ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> (<28> ڵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> )
if ( GetX ( ) = = x & & GetY ( ) = = y )
return true ;
if ( test_server )
if ( m_bDetailLog )
sys_log ( 0 , " %s position %u %u " , GetName ( ) , x , y ) ;
OnMove ( ) ;
return Sync ( x , y ) ;
}
void CHARACTER : : SendMovePacket ( BYTE bFunc , BYTE bArg , DWORD x , DWORD y , DWORD dwDuration , DWORD dwTime , int iRot )
{
TPacketGCMove pack ;
if ( bFunc = = FUNC_WAIT )
{
x = m_posDest . x ;
y = m_posDest . y ;
dwDuration = m_dwMoveDuration ;
}
EncodeMovePacket ( pack , GetVID ( ) , bFunc , bArg , x , y , dwDuration , dwTime , iRot = = - 1 ? ( int ) GetRotation ( ) / 5 : iRot ) ;
PacketView ( & pack , sizeof ( TPacketGCMove ) , this ) ;
}
int CHARACTER : : GetRealPoint ( BYTE type ) const
{
return m_points . points [ type ] ;
}
void CHARACTER : : SetRealPoint ( BYTE type , int val )
{
m_points . points [ type ] = val ;
}
int CHARACTER : : GetPolymorphPoint ( BYTE type ) const
{
if ( IsPolymorphed ( ) & & ! IsPolyMaintainStat ( ) )
{
DWORD dwMobVnum = GetPolymorphVnum ( ) ;
const CMob * pMob = CMobManager : : instance ( ) . Get ( dwMobVnum ) ;
int iPower = GetPolymorphPower ( ) ;
if ( pMob )
{
switch ( type )
{
case POINT_ST :
if ( GetJob ( ) = = JOB_SHAMAN | | GetJob ( ) = = JOB_SURA & & GetSkillGroup ( ) = = 2 )
return pMob - > m_table . bStr * iPower / 100 + GetPoint ( POINT_IQ ) ;
return pMob - > m_table . bStr * iPower / 100 + GetPoint ( POINT_ST ) ;
case POINT_HT :
return pMob - > m_table . bCon * iPower / 100 + GetPoint ( POINT_HT ) ;
case POINT_IQ :
return pMob - > m_table . bInt * iPower / 100 + GetPoint ( POINT_IQ ) ;
case POINT_DX :
return pMob - > m_table . bDex * iPower / 100 + GetPoint ( POINT_DX ) ;
}
}
}
return GetPoint ( type ) ;
}
int CHARACTER : : GetPoint ( BYTE type ) const
{
if ( type > = POINT_MAX_NUM )
{
sys_err ( " Point type overflow (type %u) " , type ) ;
return 0 ;
}
int val = m_pointsInstant . points [ type ] ;
int max_val = INT_MAX ;
switch ( type )
{
case POINT_STEAL_HP :
case POINT_STEAL_SP :
max_val = 50 ;
break ;
}
if ( val > max_val )
sys_err ( " POINT_ERROR: %s type %d val %d (max: %d) " , GetName ( ) , val , max_val ) ;
return ( val ) ;
}
int CHARACTER : : GetLimitPoint ( BYTE type ) const
{
if ( type > = POINT_MAX_NUM )
{
sys_err ( " Point type overflow (type %u) " , type ) ;
return 0 ;
}
int val = m_pointsInstant . points [ type ] ;
int max_val = INT_MAX ;
int limit = INT_MAX ;
int min_limit = - INT_MAX ;
switch ( type )
{
case POINT_ATT_SPEED :
min_limit = 0 ;
if ( IsPC ( ) )
limit = 170 ;
else
limit = 250 ;
break ;
case POINT_MOV_SPEED :
min_limit = 0 ;
if ( IsPC ( ) )
limit = 200 ;
else
limit = 250 ;
break ;
case POINT_STEAL_HP :
case POINT_STEAL_SP :
limit = 50 ;
max_val = 50 ;
break ;
case POINT_MALL_ATTBONUS :
case POINT_MALL_DEFBONUS :
limit = 20 ;
max_val = 50 ;
break ;
}
if ( val > max_val )
sys_err ( " POINT_ERROR: %s type %d val %d (max: %d) " , GetName ( ) , val , max_val ) ;
if ( val > limit )
val = limit ;
if ( val < min_limit )
val = min_limit ;
return ( val ) ;
}
void CHARACTER : : SetPoint ( BYTE type , int val )
{
if ( type > = POINT_MAX_NUM )
{
sys_err ( " Point type overflow (type %u) " , type ) ;
return ;
}
m_pointsInstant . points [ type ] = val ;
// <20> <> <EFBFBD> <EFBFBD> <20> ̵<EFBFBD> <CCB5> <EFBFBD> <20> <> <20> ȳ<EFBFBD> <C8B3> <EFBFBD> <EFBFBD> ٸ<EFBFBD> <20> ̵<EFBFBD> <20> ð<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ٽ<EFBFBD> <20> ؾ<EFBFBD> <20> Ѵ <EFBFBD> .
if ( type = = POINT_MOV_SPEED & & get_dword_time ( ) < m_dwMoveStartTime + m_dwMoveDuration )
{
CalculateMoveDuration ( ) ;
}
}
INT CHARACTER : : GetAllowedGold ( ) const
{
if ( GetLevel ( ) < = 10 )
return 100000 ;
else if ( GetLevel ( ) < = 20 )
return 500000 ;
else
return 50000000 ;
}
void CHARACTER : : CheckMaximumPoints ( )
{
if ( GetMaxHP ( ) < GetHP ( ) )
PointChange ( POINT_HP , GetMaxHP ( ) - GetHP ( ) ) ;
if ( GetMaxSP ( ) < GetSP ( ) )
PointChange ( POINT_SP , GetMaxSP ( ) - GetSP ( ) ) ;
}
void CHARACTER : : PointChange ( BYTE type , int amount , bool bAmount , bool bBroadcast )
{
int val = 0 ;
//sys_log(0, "PointChange %d %d | %d -> %d cHP %d mHP %d", type, amount, GetPoint(type), GetPoint(type)+amount, GetHP(), GetMaxHP());
switch ( type )
{
case POINT_NONE :
return ;
case POINT_LEVEL :
if ( ( GetLevel ( ) + amount ) > gPlayerMaxLevel )
return ;
SetLevel ( GetLevel ( ) + amount ) ;
val = GetLevel ( ) ;
sys_log ( 0 , " LEVELUP: %s %d NEXT EXP %d " , GetName ( ) , GetLevel ( ) , GetNextExp ( ) ) ;
PointChange ( POINT_NEXT_EXP , GetNextExp ( ) , false ) ;
if ( amount )
{
quest : : CQuestManager : : instance ( ) . LevelUp ( GetPlayerID ( ) ) ;
LogManager : : instance ( ) . LevelLog ( this , val , GetRealPoint ( POINT_PLAYTIME ) + ( get_dword_time ( ) - m_dwPlayStartTime ) / 60000 ) ;
if ( GetGuild ( ) )
{
GetGuild ( ) - > LevelChange ( GetPlayerID ( ) , GetLevel ( ) ) ;
}
if ( GetParty ( ) )
{
GetParty ( ) - > RequestSetMemberLevel ( GetPlayerID ( ) , GetLevel ( ) ) ;
}
}
break ;
case POINT_NEXT_EXP :
val = GetNextExp ( ) ;
bAmount = false ; // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> bAmount<6E> <74> false <20> <> <EFBFBD> <EFBFBD> <20> Ѵ <EFBFBD> .
break ;
case POINT_EXP :
{
DWORD exp = GetExp ( ) ;
DWORD next_exp = GetNextExp ( ) ;
// û<> ҳ⺸ȣ
if ( LC_IsNewCIBN ( ) )
{
if ( IsOverTime ( OT_NONE ) )
{
dev_log ( LOG_DEB0 , " <EXP_LOG> %s = NONE " , GetName ( ) ) ;
}
else if ( IsOverTime ( OT_3HOUR ) )
{
amount = ( amount / 2 ) ;
dev_log ( LOG_DEB0 , " <EXP_LOG> %s = 3HOUR " , GetName ( ) ) ;
}
else if ( IsOverTime ( OT_5HOUR ) )
{
amount = 0 ;
dev_log ( LOG_DEB0 , " <EXP_LOG> %s = 5HOUR " , GetName ( ) ) ;
}
}
// exp<78> <70> 0 <20> <> <EFBFBD> Ϸ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ʵ<EFBFBD> <CAB5> <EFBFBD> <20> Ѵ <EFBFBD>
if ( amount < 0 & & exp < - amount )
{
sys_log ( 1 , " %s AMOUNT < 0 %d, CUR EXP: %d " , GetName ( ) , - amount , exp ) ;
amount = - exp ;
SetExp ( exp + amount ) ;
val = GetExp ( ) ;
}
else
{
if ( gPlayerMaxLevel < = GetLevel ( ) )
return ;
if ( test_server )
ChatPacket ( CHAT_TYPE_INFO , " You have gained %d exp. " , amount ) ;
DWORD iExpBalance = 0 ;
// <20> <> <EFBFBD> <EFBFBD> <20> <> !
if ( exp + amount > = next_exp )
{
iExpBalance = ( exp + amount ) - next_exp ;
amount = next_exp - exp ;
SetExp ( 0 ) ;
exp = next_exp ;
}
else
{
SetExp ( exp + amount ) ;
exp = GetExp ( ) ;
}
DWORD q = DWORD ( next_exp / 4.0f ) ;
int iLevStep = GetRealPoint ( POINT_LEVEL_STEP ) ;
// iLevStep<65> <70> 4 <20> ̻<EFBFBD> <CCBB> ̸<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ö<EFBFBD> <C3B6> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ϲ Ƿ<CFB9> <20> <> <EFBFBD> <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̴<EFBFBD> .
if ( iLevStep > = 4 )
{
sys_err ( " %s LEVEL_STEP bigger than 4! (%d) " , GetName ( ) , iLevStep ) ;
iLevStep = 4 ;
}
if ( exp > = next_exp & & iLevStep < 4 )
{
for ( int i = 0 ; i < 4 - iLevStep ; + + i )
PointChange ( POINT_LEVEL_STEP , 1 , false , true ) ;
}
else if ( exp > = q * 3 & & iLevStep < 3 )
{
for ( int i = 0 ; i < 3 - iLevStep ; + + i )
PointChange ( POINT_LEVEL_STEP , 1 , false , true ) ;
}
else if ( exp > = q * 2 & & iLevStep < 2 )
{
for ( int i = 0 ; i < 2 - iLevStep ; + + i )
PointChange ( POINT_LEVEL_STEP , 1 , false , true ) ;
}
else if ( exp > = q & & iLevStep < 1 )
PointChange ( POINT_LEVEL_STEP , 1 ) ;
if ( iExpBalance )
{
PointChange ( POINT_EXP , iExpBalance ) ;
}
val = GetExp ( ) ;
}
}
break ;
case POINT_LEVEL_STEP :
if ( amount > 0 )
{
val = GetPoint ( POINT_LEVEL_STEP ) + amount ;
switch ( val )
{
case 1 :
case 2 :
case 3 :
//if (GetLevel() < 100) PointChange(POINT_STAT, 1);
if ( GetLevel ( ) < 91 ) PointChange ( POINT_STAT , 1 ) ;
break ;
case 4 :
{
2022-11-27 14:36:04 +02:00
int iHP = Random : : get ( JobInitialPoints [ GetJob ( ) ] . hp_per_lv_begin , JobInitialPoints [ GetJob ( ) ] . hp_per_lv_end ) ;
int iSP = Random : : get ( JobInitialPoints [ GetJob ( ) ] . sp_per_lv_begin , JobInitialPoints [ GetJob ( ) ] . sp_per_lv_end ) ;
2022-03-05 12:44:06 +02:00
m_points . iRandomHP + = iHP ;
m_points . iRandomSP + = iSP ;
if ( GetSkillGroup ( ) )
{
if ( GetLevel ( ) > = 5 )
PointChange ( POINT_SKILL , 1 ) ;
if ( GetLevel ( ) > = 9 )
PointChange ( POINT_SUB_SKILL , 1 ) ;
}
PointChange ( POINT_MAX_HP , iHP ) ;
PointChange ( POINT_MAX_SP , iSP ) ;
PointChange ( POINT_LEVEL , 1 , false , true ) ;
val = 0 ;
}
break ;
}
if ( GetLevel ( ) < = 10 )
AutoGiveItem ( 27001 , 2 ) ;
else if ( GetLevel ( ) < = 30 )
AutoGiveItem ( 27002 , 2 ) ;
else
{
AutoGiveItem ( 27002 , 2 ) ;
// AutoGiveItem(27003, 2);
}
PointChange ( POINT_HP , GetMaxHP ( ) - GetHP ( ) ) ;
PointChange ( POINT_SP , GetMaxSP ( ) - GetSP ( ) ) ;
PointChange ( POINT_STAMINA , GetMaxStamina ( ) - GetStamina ( ) ) ;
SetPoint ( POINT_LEVEL_STEP , val ) ;
SetRealPoint ( POINT_LEVEL_STEP , val ) ;
Save ( ) ;
}
else
val = GetPoint ( POINT_LEVEL_STEP ) ;
break ;
case POINT_HP :
{
if ( IsDead ( ) | | IsStun ( ) )
return ;
int prev_hp = GetHP ( ) ;
2022-11-27 22:18:08 +02:00
amount = std : : min ( GetMaxHP ( ) - GetHP ( ) , amount ) ;
2022-03-05 12:44:06 +02:00
SetHP ( GetHP ( ) + amount ) ;
val = GetHP ( ) ;
BroadcastTargetPacket ( ) ;
if ( GetParty ( ) & & IsPC ( ) & & val ! = prev_hp )
GetParty ( ) - > SendPartyInfoOneToAll ( this ) ;
}
break ;
case POINT_SP :
{
if ( IsDead ( ) | | IsStun ( ) )
return ;
2022-11-27 22:18:08 +02:00
amount = std : : min ( GetMaxSP ( ) - GetSP ( ) , amount ) ;
2022-03-05 12:44:06 +02:00
SetSP ( GetSP ( ) + amount ) ;
val = GetSP ( ) ;
}
break ;
case POINT_STAMINA :
{
if ( IsDead ( ) | | IsStun ( ) )
return ;
int prev_val = GetStamina ( ) ;
2022-11-27 22:18:08 +02:00
amount = std : : min ( GetMaxStamina ( ) - GetStamina ( ) , amount ) ;
2022-03-05 12:44:06 +02:00
SetStamina ( GetStamina ( ) + amount ) ;
val = GetStamina ( ) ;
if ( val = = 0 )
{
// Stamina<6E> <61> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> !
SetNowWalking ( true ) ;
}
else if ( prev_val = = 0 )
{
// <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ̳<D7B9> <CCB3> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
ResetWalking ( ) ;
}
if ( amount < 0 & & val ! = 0 ) // <20> <> <EFBFBD> Ҵ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ʴ´ <CAB4> .
return ;
}
break ;
case POINT_MAX_HP :
{
SetPoint ( type , GetPoint ( type ) + amount ) ;
//SetMaxHP(GetMaxHP() + amount);
// <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> = (<28> ⺻ <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> + <20> ߰<EFBFBD> ) * <20> ִ<EFBFBD> <D6B4> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> %
int hp = GetRealPoint ( POINT_MAX_HP ) ;
2022-11-27 22:18:08 +02:00
int add_hp = std : : min ( 3500 , hp * GetPoint ( POINT_MAX_HP_PCT ) / 100 ) ;
2022-03-05 12:44:06 +02:00
add_hp + = GetPoint ( POINT_MAX_HP ) ;
add_hp + = GetPoint ( POINT_PARTY_TANKER_BONUS ) ;
SetMaxHP ( hp + add_hp ) ;
val = GetMaxHP ( ) ;
}
break ;
case POINT_MAX_SP :
{
SetPoint ( type , GetPoint ( type ) + amount ) ;
//SetMaxSP(GetMaxSP() + amount);
// <20> ִ<EFBFBD> <20> <> <EFBFBD> ŷ<EFBFBD> = (<28> ⺻ <20> ִ<EFBFBD> <20> <> <EFBFBD> ŷ<EFBFBD> + <20> ߰<EFBFBD> ) * <20> ִ<EFBFBD> <D6B4> <EFBFBD> <EFBFBD> ŷ<EFBFBD> %
int sp = GetRealPoint ( POINT_MAX_SP ) ;
2022-11-27 22:18:08 +02:00
int add_sp = std : : min ( 800 , sp * GetPoint ( POINT_MAX_SP_PCT ) / 100 ) ;
2022-03-05 12:44:06 +02:00
add_sp + = GetPoint ( POINT_MAX_SP ) ;
add_sp + = GetPoint ( POINT_PARTY_SKILL_MASTER_BONUS ) ;
SetMaxSP ( sp + add_sp ) ;
val = GetMaxSP ( ) ;
}
break ;
case POINT_MAX_HP_PCT :
SetPoint ( type , GetPoint ( type ) + amount ) ;
val = GetPoint ( type ) ;
PointChange ( POINT_MAX_HP , 0 ) ;
break ;
case POINT_MAX_SP_PCT :
SetPoint ( type , GetPoint ( type ) + amount ) ;
val = GetPoint ( type ) ;
PointChange ( POINT_MAX_SP , 0 ) ;
break ;
case POINT_MAX_STAMINA :
SetMaxStamina ( GetMaxStamina ( ) + amount ) ;
val = GetMaxStamina ( ) ;
break ;
case POINT_GOLD :
{
const int64_t nTotalMoney = static_cast < int64_t > ( GetGold ( ) ) + static_cast < int64_t > ( amount ) ;
if ( GOLD_MAX < = nTotalMoney )
{
sys_err ( " [OVERFLOW_GOLD] OriGold %d AddedGold %d id %u Name %s " , GetGold ( ) , amount , GetPlayerID ( ) , GetName ( ) ) ;
LogManager : : instance ( ) . CharLog ( this , GetGold ( ) + amount , " OVERFLOW_GOLD " , " " ) ;
return ;
}
// û<> ҳ⺸ȣ
if ( LC_IsNewCIBN ( ) & & amount > 0 )
{
if ( IsOverTime ( OT_NONE ) )
{
dev_log ( LOG_DEB0 , " <GOLD_LOG> %s = NONE " , GetName ( ) ) ;
}
else if ( IsOverTime ( OT_3HOUR ) )
{
amount = ( amount / 2 ) ;
dev_log ( LOG_DEB0 , " <GOLD_LOG> %s = 3HOUR " , GetName ( ) ) ;
}
else if ( IsOverTime ( OT_5HOUR ) )
{
amount = 0 ;
dev_log ( LOG_DEB0 , " <GOLD_LOG> %s = 5HOUR " , GetName ( ) ) ;
}
}
SetGold ( GetGold ( ) + amount ) ;
val = GetGold ( ) ;
}
break ;
case POINT_SKILL :
case POINT_STAT :
case POINT_SUB_SKILL :
case POINT_STAT_RESET_COUNT :
case POINT_HORSE_SKILL :
SetPoint ( type , GetPoint ( type ) + amount ) ;
val = GetPoint ( type ) ;
SetRealPoint ( type , val ) ;
break ;
case POINT_DEF_GRADE :
SetPoint ( type , GetPoint ( type ) + amount ) ;
val = GetPoint ( type ) ;
PointChange ( POINT_CLIENT_DEF_GRADE , amount ) ;
break ;
case POINT_CLIENT_DEF_GRADE :
SetPoint ( type , GetPoint ( type ) + amount ) ;
val = GetPoint ( type ) ;
break ;
case POINT_ST :
case POINT_HT :
case POINT_DX :
case POINT_IQ :
case POINT_HP_REGEN :
case POINT_SP_REGEN :
case POINT_ATT_SPEED :
case POINT_ATT_GRADE :
case POINT_MOV_SPEED :
case POINT_CASTING_SPEED :
case POINT_MAGIC_ATT_GRADE :
case POINT_MAGIC_DEF_GRADE :
case POINT_BOW_DISTANCE :
case POINT_HP_RECOVERY :
case POINT_SP_RECOVERY :
case POINT_ATTBONUS_HUMAN : // 42 <20> ΰ<EFBFBD> <CEB0> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
case POINT_ATTBONUS_ANIMAL : // 43 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> % <20> <> <EFBFBD> <EFBFBD>
case POINT_ATTBONUS_ORC : // 44 <20> <> <EFBFBD> Ϳ <EFBFBD> <CDBF> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> % <20> <> <EFBFBD> <EFBFBD>
case POINT_ATTBONUS_MILGYO : // 45 <20> б <EFBFBD> <D0B1> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> % <20> <> <EFBFBD> <EFBFBD>
case POINT_ATTBONUS_UNDEAD : // 46 <20> <> ü<EFBFBD> <C3BC> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> % <20> <> <EFBFBD> <EFBFBD>
case POINT_ATTBONUS_DEVIL : // 47 <20> <> <EFBFBD> <EFBFBD> (<28> Ǹ<EFBFBD> )<29> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> % <20> <> <EFBFBD> <EFBFBD>
case POINT_ATTBONUS_MONSTER :
case POINT_ATTBONUS_SURA :
case POINT_ATTBONUS_ASSASSIN :
case POINT_ATTBONUS_WARRIOR :
case POINT_ATTBONUS_SHAMAN :
case POINT_POISON_PCT :
case POINT_STUN_PCT :
case POINT_SLOW_PCT :
case POINT_BLOCK :
case POINT_DODGE :
case POINT_CRITICAL_PCT :
case POINT_RESIST_CRITICAL :
case POINT_PENETRATE_PCT :
case POINT_RESIST_PENETRATE :
case POINT_CURSE_PCT :
case POINT_STEAL_HP : // 48 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
case POINT_STEAL_SP : // 49 <20> <> <EFBFBD> ŷ<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
case POINT_MANA_BURN_PCT : // 50 <20> <> <EFBFBD> <EFBFBD> <20> <>
case POINT_DAMAGE_SP_RECOVER : // 51 <20> <> <EFBFBD> ݴ<EFBFBD> <DDB4> <EFBFBD> <20> <> <20> <> <EFBFBD> ŷ<EFBFBD> ȸ<> <C8B8> Ȯ<> <C8AE>
case POINT_RESIST_NORMAL_DAMAGE :
case POINT_RESIST_SWORD :
case POINT_RESIST_TWOHAND :
case POINT_RESIST_DAGGER :
case POINT_RESIST_BELL :
case POINT_RESIST_FAN :
case POINT_RESIST_BOW :
case POINT_RESIST_FIRE :
case POINT_RESIST_ELEC :
case POINT_RESIST_MAGIC :
case POINT_RESIST_WIND :
case POINT_RESIST_ICE :
case POINT_RESIST_EARTH :
case POINT_RESIST_DARK :
case POINT_REFLECT_MELEE : // 67 <20> <> <EFBFBD> <EFBFBD> <20> ݻ<EFBFBD>
case POINT_REFLECT_CURSE : // 68 <20> <> <EFBFBD> <EFBFBD> <20> ݻ<EFBFBD>
case POINT_POISON_REDUCE : // 69 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
case POINT_KILL_SP_RECOVER : // 70 <20> <> <20> Ҹ<EFBFBD> <D2B8> <EFBFBD> MP ȸ<> <C8B8>
case POINT_KILL_HP_RECOVERY : // 75
case POINT_HIT_HP_RECOVERY :
case POINT_HIT_SP_RECOVERY :
case POINT_MANASHIELD :
case POINT_ATT_BONUS :
case POINT_DEF_BONUS :
case POINT_SKILL_DAMAGE_BONUS :
case POINT_NORMAL_HIT_DAMAGE_BONUS :
// DEPEND_BONUS_ATTRIBUTES
case POINT_SKILL_DEFEND_BONUS :
case POINT_NORMAL_HIT_DEFEND_BONUS :
SetPoint ( type , GetPoint ( type ) + amount ) ;
val = GetPoint ( type ) ;
break ;
// END_OF_DEPEND_BONUS_ATTRIBUTES
case POINT_PARTY_ATTACKER_BONUS :
case POINT_PARTY_TANKER_BONUS :
case POINT_PARTY_BUFFER_BONUS :
case POINT_PARTY_SKILL_MASTER_BONUS :
case POINT_PARTY_HASTE_BONUS :
case POINT_PARTY_DEFENDER_BONUS :
case POINT_RESIST_WARRIOR :
case POINT_RESIST_ASSASSIN :
case POINT_RESIST_SURA :
case POINT_RESIST_SHAMAN :
SetPoint ( type , GetPoint ( type ) + amount ) ;
val = GetPoint ( type ) ;
break ;
case POINT_MALL_ATTBONUS :
case POINT_MALL_DEFBONUS :
case POINT_MALL_EXPBONUS :
case POINT_MALL_ITEMBONUS :
case POINT_MALL_GOLDBONUS :
case POINT_MELEE_MAGIC_ATT_BONUS_PER :
if ( GetPoint ( type ) + amount > 100 )
{
sys_err ( " MALL_BONUS exceeded over 100!! point type: %d name: %s amount %d " , type , GetName ( ) , amount ) ;
amount = 100 - GetPoint ( type ) ;
}
SetPoint ( type , GetPoint ( type ) + amount ) ;
val = GetPoint ( type ) ;
break ;
// PC_BANG_ITEM_ADD
case POINT_PC_BANG_EXP_BONUS :
case POINT_PC_BANG_DROP_BONUS :
case POINT_RAMADAN_CANDY_BONUS_EXP :
SetPoint ( type , amount ) ;
val = GetPoint ( type ) ;
break ;
// END_PC_BANG_ITEM_ADD
case POINT_EXP_DOUBLE_BONUS : // 71
case POINT_GOLD_DOUBLE_BONUS : // 72
case POINT_ITEM_DROP_BONUS : // 73
case POINT_POTION_BONUS : // 74
if ( GetPoint ( type ) + amount > 100 )
{
sys_err ( " BONUS exceeded over 100!! point type: %d name: %s amount %d " , type , GetName ( ) , amount ) ;
amount = 100 - GetPoint ( type ) ;
}
SetPoint ( type , GetPoint ( type ) + amount ) ;
val = GetPoint ( type ) ;
break ;
case POINT_IMMUNE_STUN : // 76
SetPoint ( type , GetPoint ( type ) + amount ) ;
val = GetPoint ( type ) ;
if ( val )
{
SET_BIT ( m_pointsInstant . dwImmuneFlag , IMMUNE_STUN ) ;
}
else
{
REMOVE_BIT ( m_pointsInstant . dwImmuneFlag , IMMUNE_STUN ) ;
}
break ;
case POINT_IMMUNE_SLOW : // 77
SetPoint ( type , GetPoint ( type ) + amount ) ;
val = GetPoint ( type ) ;
if ( val )
{
SET_BIT ( m_pointsInstant . dwImmuneFlag , IMMUNE_SLOW ) ;
}
else
{
REMOVE_BIT ( m_pointsInstant . dwImmuneFlag , IMMUNE_SLOW ) ;
}
break ;
case POINT_IMMUNE_FALL : // 78
SetPoint ( type , GetPoint ( type ) + amount ) ;
val = GetPoint ( type ) ;
if ( val )
{
SET_BIT ( m_pointsInstant . dwImmuneFlag , IMMUNE_FALL ) ;
}
else
{
REMOVE_BIT ( m_pointsInstant . dwImmuneFlag , IMMUNE_FALL ) ;
}
break ;
case POINT_ATT_GRADE_BONUS :
SetPoint ( type , GetPoint ( type ) + amount ) ;
PointChange ( POINT_ATT_GRADE , amount ) ;
val = GetPoint ( type ) ;
break ;
case POINT_DEF_GRADE_BONUS :
SetPoint ( type , GetPoint ( type ) + amount ) ;
PointChange ( POINT_DEF_GRADE , amount ) ;
val = GetPoint ( type ) ;
break ;
case POINT_MAGIC_ATT_GRADE_BONUS :
SetPoint ( type , GetPoint ( type ) + amount ) ;
PointChange ( POINT_MAGIC_ATT_GRADE , amount ) ;
val = GetPoint ( type ) ;
break ;
case POINT_MAGIC_DEF_GRADE_BONUS :
SetPoint ( type , GetPoint ( type ) + amount ) ;
PointChange ( POINT_MAGIC_DEF_GRADE , amount ) ;
val = GetPoint ( type ) ;
break ;
case POINT_VOICE :
case POINT_EMPIRE_POINT :
//sys_err("CHARACTER::PointChange: %s: point cannot be changed. use SetPoint instead (type: %d)", GetName(), type);
val = GetRealPoint ( type ) ;
break ;
case POINT_POLYMORPH :
SetPoint ( type , GetPoint ( type ) + amount ) ;
val = GetPoint ( type ) ;
SetPolymorph ( val ) ;
break ;
case POINT_MOUNT :
SetPoint ( type , GetPoint ( type ) + amount ) ;
val = GetPoint ( type ) ;
MountVnum ( val ) ;
break ;
case POINT_ENERGY :
case POINT_COSTUME_ATTR_BONUS :
{
int old_val = GetPoint ( type ) ;
SetPoint ( type , old_val + amount ) ;
val = GetPoint ( type ) ;
BuffOnAttr_ValueChange ( type , old_val , val ) ;
}
break ;
default :
sys_err ( " CHARACTER::PointChange: %s: unknown point change type %d " , GetName ( ) , type ) ;
return ;
}
switch ( type )
{
case POINT_LEVEL :
case POINT_ST :
case POINT_DX :
case POINT_IQ :
case POINT_HT :
ComputeBattlePoints ( ) ;
break ;
case POINT_MAX_HP :
case POINT_MAX_SP :
case POINT_MAX_STAMINA :
break ;
}
if ( type = = POINT_HP & & amount = = 0 )
return ;
if ( GetDesc ( ) )
{
2022-03-21 10:27:28 +02:00
TPacketGCPointChange pack ;
2022-03-05 12:44:06 +02:00
pack . header = HEADER_GC_CHARACTER_POINT_CHANGE ;
pack . dwVID = m_vid ;
pack . type = type ;
pack . value = val ;
if ( bAmount )
pack . amount = amount ;
else
pack . amount = 0 ;
if ( ! bBroadcast )
2022-03-21 10:27:28 +02:00
GetDesc ( ) - > Packet ( & pack , sizeof ( TPacketGCPointChange ) ) ;
2022-03-05 12:44:06 +02:00
else
PacketAround ( & pack , sizeof ( pack ) ) ;
}
}
void CHARACTER : : ApplyPoint ( BYTE bApplyType , int iVal )
{
switch ( bApplyType )
{
case APPLY_NONE : // 0
break ; ;
case APPLY_CON :
PointChange ( POINT_HT , iVal ) ;
PointChange ( POINT_MAX_HP , ( iVal * JobInitialPoints [ GetJob ( ) ] . hp_per_ht ) ) ;
PointChange ( POINT_MAX_STAMINA , ( iVal * JobInitialPoints [ GetJob ( ) ] . stamina_per_con ) ) ;
break ;
case APPLY_INT :
PointChange ( POINT_IQ , iVal ) ;
PointChange ( POINT_MAX_SP , ( iVal * JobInitialPoints [ GetJob ( ) ] . sp_per_iq ) ) ;
break ;
case APPLY_SKILL :
// SKILL_DAMAGE_BONUS
{
// <20> ֻ<EFBFBD> <D6BB> <EFBFBD> <20> <> Ʈ <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 8<> <38> Ʈ vnum, 9<> <39> Ʈ add, 15<31> <35> Ʈ change
// 00000000 00000000 00000000 00000000
// ^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
// vnum ^ add change
BYTE bSkillVnum = ( BYTE ) ( ( ( DWORD ) iVal ) > > 24 ) ;
int iAdd = iVal & 0x00800000 ;
int iChange = iVal & 0x007fffff ;
sys_log ( 1 , " APPLY_SKILL skill %d add? %d change %d " , bSkillVnum , iAdd ? 1 : 0 , iChange ) ;
if ( 0 = = iAdd )
iChange = - iChange ;
2022-03-06 00:01:03 +02:00
std : : unordered_map < BYTE , int > : : iterator iter = m_SkillDamageBonus . find ( bSkillVnum ) ;
2022-03-05 12:44:06 +02:00
if ( iter = = m_SkillDamageBonus . end ( ) )
m_SkillDamageBonus . insert ( std : : make_pair ( bSkillVnum , iChange ) ) ;
else
iter - > second + = iChange ;
}
// END_OF_SKILL_DAMAGE_BONUS
break ;
case APPLY_STR :
case APPLY_DEX :
case APPLY_MAX_HP :
case APPLY_MAX_SP :
case APPLY_MAX_HP_PCT :
case APPLY_MAX_SP_PCT :
case APPLY_ATT_SPEED :
case APPLY_MOV_SPEED :
case APPLY_CAST_SPEED :
case APPLY_HP_REGEN :
case APPLY_SP_REGEN :
case APPLY_POISON_PCT :
case APPLY_STUN_PCT :
case APPLY_SLOW_PCT :
case APPLY_CRITICAL_PCT :
case APPLY_PENETRATE_PCT :
case APPLY_ATTBONUS_HUMAN :
case APPLY_ATTBONUS_ANIMAL :
case APPLY_ATTBONUS_ORC :
case APPLY_ATTBONUS_MILGYO :
case APPLY_ATTBONUS_UNDEAD :
case APPLY_ATTBONUS_DEVIL :
case APPLY_ATTBONUS_WARRIOR : // 59
case APPLY_ATTBONUS_ASSASSIN : // 60
case APPLY_ATTBONUS_SURA : // 61
case APPLY_ATTBONUS_SHAMAN : // 62
case APPLY_ATTBONUS_MONSTER : // 63
case APPLY_STEAL_HP :
case APPLY_STEAL_SP :
case APPLY_MANA_BURN_PCT :
case APPLY_DAMAGE_SP_RECOVER :
case APPLY_BLOCK :
case APPLY_DODGE :
case APPLY_RESIST_SWORD :
case APPLY_RESIST_TWOHAND :
case APPLY_RESIST_DAGGER :
case APPLY_RESIST_BELL :
case APPLY_RESIST_FAN :
case APPLY_RESIST_BOW :
case APPLY_RESIST_FIRE :
case APPLY_RESIST_ELEC :
case APPLY_RESIST_MAGIC :
case APPLY_RESIST_WIND :
case APPLY_RESIST_ICE :
case APPLY_RESIST_EARTH :
case APPLY_RESIST_DARK :
case APPLY_REFLECT_MELEE :
case APPLY_REFLECT_CURSE :
case APPLY_ANTI_CRITICAL_PCT :
case APPLY_ANTI_PENETRATE_PCT :
case APPLY_POISON_REDUCE :
case APPLY_KILL_SP_RECOVER :
case APPLY_EXP_DOUBLE_BONUS :
case APPLY_GOLD_DOUBLE_BONUS :
case APPLY_ITEM_DROP_BONUS :
case APPLY_POTION_BONUS :
case APPLY_KILL_HP_RECOVER :
case APPLY_IMMUNE_STUN :
case APPLY_IMMUNE_SLOW :
case APPLY_IMMUNE_FALL :
case APPLY_BOW_DISTANCE :
case APPLY_ATT_GRADE_BONUS :
case APPLY_DEF_GRADE_BONUS :
case APPLY_MAGIC_ATT_GRADE :
case APPLY_MAGIC_DEF_GRADE :
case APPLY_CURSE_PCT :
case APPLY_MAX_STAMINA :
case APPLY_MALL_ATTBONUS :
case APPLY_MALL_DEFBONUS :
case APPLY_MALL_EXPBONUS :
case APPLY_MALL_ITEMBONUS :
case APPLY_MALL_GOLDBONUS :
case APPLY_SKILL_DAMAGE_BONUS :
case APPLY_NORMAL_HIT_DAMAGE_BONUS :
// DEPEND_BONUS_ATTRIBUTES
case APPLY_SKILL_DEFEND_BONUS :
case APPLY_NORMAL_HIT_DEFEND_BONUS :
// END_OF_DEPEND_BONUS_ATTRIBUTES
case APPLY_PC_BANG_EXP_BONUS :
case APPLY_PC_BANG_DROP_BONUS :
case APPLY_RESIST_WARRIOR :
case APPLY_RESIST_ASSASSIN :
case APPLY_RESIST_SURA :
case APPLY_RESIST_SHAMAN :
case APPLY_ENERGY : // 82 <20> <> <EFBFBD> <EFBFBD>
case APPLY_DEF_GRADE : // 83 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> . DEF_GRADE_BONUS<55> <53> Ŭ<> <EFBFBD> <20> ι <EFBFBD> <CEB9> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ǵ<EFBFBD> <C7B5> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> (...)<29> <> <20> ִ<EFBFBD> .
case APPLY_COSTUME_ATTR_BONUS : // 84 <20> ڽ<EFBFBD> Ƭ <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ۿ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> Ӽ<EFBFBD> ġ <20> <> <EFBFBD> ʽ <EFBFBD>
case APPLY_MAGIC_ATTBONUS_PER : // 85 <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ݷ<EFBFBD> +x%
case APPLY_MELEE_MAGIC_ATTBONUS_PER : // 86 <20> <> <EFBFBD> <EFBFBD> + <20> и<EFBFBD> <20> <> <EFBFBD> ݷ<EFBFBD> +x%
PointChange ( aApplyInfo [ bApplyType ] . bPointType , iVal ) ;
break ;
default :
sys_err ( " Unknown apply type %d name %s " , bApplyType , GetName ( ) ) ;
break ;
}
}
void CHARACTER : : MotionPacketEncode ( BYTE motion , LPCHARACTER victim , struct packet_motion * packet )
{
packet - > header = HEADER_GC_MOTION ;
packet - > vid = m_vid ;
packet - > motion = motion ;
if ( victim )
packet - > victim_vid = victim - > GetVID ( ) ;
else
packet - > victim_vid = 0 ;
}
void CHARACTER : : Motion ( BYTE motion , LPCHARACTER victim )
{
struct packet_motion pack_motion ;
MotionPacketEncode ( motion , victim , & pack_motion ) ;
PacketAround ( & pack_motion , sizeof ( struct packet_motion ) ) ;
}
EVENTFUNC ( save_event )
{
char_event_info * info = dynamic_cast < char_event_info * > ( event - > info ) ;
if ( info = = NULL )
{
sys_err ( " save_event> <Factor> Null pointer " ) ;
return 0 ;
}
LPCHARACTER ch = info - > ch ;
if ( ch = = NULL ) { // <Factor>
return 0 ;
}
sys_log ( 1 , " SAVE_EVENT: %s " , ch - > GetName ( ) ) ;
ch - > Save ( ) ;
ch - > FlushDelayedSaveItem ( ) ;
return ( save_event_second_cycle ) ;
}
void CHARACTER : : StartSaveEvent ( )
{
if ( m_pkSaveEvent )
return ;
char_event_info * info = AllocEventInfo < char_event_info > ( ) ;
info - > ch = this ;
m_pkSaveEvent = event_create ( save_event , info , save_event_second_cycle ) ;
}
void CHARACTER : : MonsterLog ( const char * format , . . . )
{
if ( ! test_server )
return ;
if ( IsPC ( ) )
return ;
char chatbuf [ CHAT_MAX_LEN + 1 ] ;
int len = snprintf ( chatbuf , sizeof ( chatbuf ) , " %u) " , ( DWORD ) GetVID ( ) ) ;
if ( len < 0 | | len > = ( int ) sizeof ( chatbuf ) )
len = sizeof ( chatbuf ) - 1 ;
va_list args ;
va_start ( args , format ) ;
int len2 = vsnprintf ( chatbuf + len , sizeof ( chatbuf ) - len , format , args ) ;
if ( len2 < 0 | | len2 > = ( int ) sizeof ( chatbuf ) - len )
len + = ( sizeof ( chatbuf ) - len ) - 1 ;
else
len + = len2 ;
// \0 <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
+ + len ;
va_end ( args ) ;
TPacketGCChat pack_chat ;
pack_chat . header = HEADER_GC_CHAT ;
pack_chat . size = sizeof ( TPacketGCChat ) + len ;
pack_chat . type = CHAT_TYPE_TALKING ;
pack_chat . id = ( DWORD ) GetVID ( ) ;
pack_chat . bEmpire = 0 ;
TEMP_BUFFER buf ;
buf . write ( & pack_chat , sizeof ( TPacketGCChat ) ) ;
buf . write ( chatbuf , len ) ;
CHARACTER_MANAGER : : instance ( ) . PacketMonsterLog ( this , buf . read_peek ( ) , buf . size ( ) ) ;
}
void CHARACTER : : ChatPacket ( BYTE type , const char * format , . . . )
{
LPDESC d = GetDesc ( ) ;
if ( ! d | | ! format )
return ;
char chatbuf [ CHAT_MAX_LEN + 1 ] ;
va_list args ;
va_start ( args , format ) ;
int len = vsnprintf ( chatbuf , sizeof ( chatbuf ) , format , args ) ;
va_end ( args ) ;
struct packet_chat pack_chat ;
pack_chat . header = HEADER_GC_CHAT ;
pack_chat . size = sizeof ( struct packet_chat ) + len ;
pack_chat . type = type ;
pack_chat . id = 0 ;
pack_chat . bEmpire = d - > GetEmpire ( ) ;
TEMP_BUFFER buf ;
buf . write ( & pack_chat , sizeof ( struct packet_chat ) ) ;
buf . write ( chatbuf , len ) ;
d - > Packet ( buf . read_peek ( ) , buf . size ( ) ) ;
if ( type = = CHAT_TYPE_COMMAND & & test_server )
sys_log ( 0 , " SEND_COMMAND %s %s " , GetName ( ) , chatbuf ) ;
}
// MINING
void CHARACTER : : mining_take ( )
{
m_pkMiningEvent = NULL ;
}
void CHARACTER : : mining_cancel ( )
{
if ( m_pkMiningEvent )
{
sys_log ( 0 , " XXX MINING CANCEL " ) ;
event_cancel ( & m_pkMiningEvent ) ;
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " ä<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ߴ <EFBFBD> <DFB4> Ͽ<EFBFBD> <CFBF> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
}
}
void CHARACTER : : mining ( LPCHARACTER chLoad )
{
if ( m_pkMiningEvent )
{
mining_cancel ( ) ;
return ;
}
if ( ! chLoad )
return ;
if ( mining : : GetRawOreFromLoad ( chLoad - > GetRaceNum ( ) ) = = 0 )
return ;
LPITEM pick = GetWear ( WEAR_WEAPON ) ;
if ( ! pick | | pick - > GetType ( ) ! = ITEM_PICK )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> ̸<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϼ<EFBFBD> <CFBC> <EFBFBD> ." ) ) ;
return ;
}
2022-11-27 14:36:04 +02:00
int count = Random : : get ( 5 , 15 ) ; // <20> <> <EFBFBD> <EFBFBD> Ƚ<> <C8BD> , <20> <> <20> <> <EFBFBD> ۴<EFBFBD> 2<> <32>
2022-03-05 12:44:06 +02:00
// ä<> <C3A4> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
TPacketGCDigMotion p ;
p . header = HEADER_GC_DIG_MOTION ;
p . vid = GetVID ( ) ;
p . target_vid = chLoad - > GetVID ( ) ;
p . count = count ;
PacketAround ( & p , sizeof ( p ) ) ;
m_pkMiningEvent = mining : : CreateMiningEvent ( this , chLoad , count ) ;
}
// END_OF_MINING
void CHARACTER : : fishing ( )
{
if ( m_pkFishingEvent )
{
fishing_take ( ) ;
return ;
}
// <20> <> <EFBFBD> <EFBFBD> <20> Ӽ<EFBFBD> <D3BC> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ø<EFBFBD> <20> õ<EFBFBD> <C3B5> Ѵ <EFBFBD> ?
{
LPSECTREE_MAP pkSectreeMap = SECTREE_MANAGER : : instance ( ) . GetMap ( GetMapIndex ( ) ) ;
int x = GetX ( ) ;
int y = GetY ( ) ;
LPSECTREE tree = pkSectreeMap - > Find ( x , y ) ;
DWORD dwAttr = tree - > GetAttribute ( x , y ) ;
if ( IS_SET ( dwAttr , ATTR_BLOCK ) )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> <EFBFBD> ø<EFBFBD> <20> <> <20> <> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ƴմϴ<D5B4> " ) ) ;
return ;
}
}
LPITEM rod = GetWear ( WEAR_WEAPON ) ;
// <20> <> <EFBFBD> ô<EFBFBD> <20> <> <EFBFBD> <EFBFBD>
if ( ! rod | | rod - > GetType ( ) ! = ITEM_ROD )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> <EFBFBD> ô븦 <20> <> <EFBFBD> <EFBFBD> <20> ϼ<EFBFBD> <CFBC> <EFBFBD> ." ) ) ;
return ;
}
if ( 0 = = rod - > GetSocket ( 2 ) )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> ̳<EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ּ<EFBFBD> <D6BC> <EFBFBD> ." ) ) ;
return ;
}
float fx , fy ;
GetDeltaByDegree ( GetRotation ( ) , 400.0f , & fx , & fy ) ;
m_pkFishingEvent = fishing : : CreateFishingEvent ( this ) ;
}
void CHARACTER : : fishing_take ( )
{
LPITEM rod = GetWear ( WEAR_WEAPON ) ;
if ( rod & & rod - > GetType ( ) = = ITEM_ROD )
{
using fishing : : fishing_event_info ;
if ( m_pkFishingEvent )
{
struct fishing_event_info * info = dynamic_cast < struct fishing_event_info * > ( m_pkFishingEvent - > info ) ;
if ( info )
fishing : : Take ( info , this ) ;
}
}
else
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> <EFBFBD> ô밡 <20> ƴ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ø<EFBFBD> <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> !" ) ) ;
}
event_cancel ( & m_pkFishingEvent ) ;
}
bool CHARACTER : : StartStateMachine ( int iNextPulse )
{
if ( CHARACTER_MANAGER : : instance ( ) . AddToStateList ( this ) )
{
m_dwNextStatePulse = thecore_heart - > pulse + iNextPulse ;
return true ;
}
return false ;
}
void CHARACTER : : StopStateMachine ( )
{
CHARACTER_MANAGER : : instance ( ) . RemoveFromStateList ( this ) ;
}
void CHARACTER : : UpdateStateMachine ( DWORD dwPulse )
{
if ( dwPulse < m_dwNextStatePulse )
return ;
if ( IsDead ( ) )
return ;
Update ( ) ;
m_dwNextStatePulse = dwPulse + m_dwStateDuration ;
}
void CHARACTER : : SetNextStatePulse ( int iNextPulse )
{
CHARACTER_MANAGER : : instance ( ) . AddToStateList ( this ) ;
m_dwNextStatePulse = iNextPulse ;
if ( iNextPulse < 10 )
MonsterLog ( " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ·ξ<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " ) ;
}
// ij<> <C4B3> <EFBFBD> <EFBFBD> <20> ν <EFBFBD> <CEBD> Ͻ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ʈ <20> Լ<EFBFBD> .
void CHARACTER : : UpdateCharacter ( DWORD dwPulse )
{
CFSM : : Update ( ) ;
}
void CHARACTER : : SetShop ( LPSHOP pkShop )
{
if ( ( m_pkShop = pkShop ) )
SET_BIT ( m_pointsInstant . instant_flag , INSTANT_FLAG_SHOP ) ;
else
{
REMOVE_BIT ( m_pointsInstant . instant_flag , INSTANT_FLAG_SHOP ) ;
SetShopOwner ( NULL ) ;
}
}
void CHARACTER : : SetExchange ( CExchange * pkExchange )
{
m_pkExchange = pkExchange ;
}
void CHARACTER : : SetPart ( BYTE bPartPos , WORD wVal )
{
assert ( bPartPos < PART_MAX_NUM ) ;
m_pointsInstant . parts [ bPartPos ] = wVal ;
}
WORD CHARACTER : : GetPart ( BYTE bPartPos ) const
{
assert ( bPartPos < PART_MAX_NUM ) ;
return m_pointsInstant . parts [ bPartPos ] ;
}
WORD CHARACTER : : GetOriginalPart ( BYTE bPartPos ) const
{
switch ( bPartPos )
{
case PART_MAIN :
if ( ! IsPC ( ) ) // PC<50> <43> <20> ƴ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> Ʈ<EFBFBD> <C6AE> <20> ״<EFBFBD> <D7B4> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
return GetPart ( PART_MAIN ) ;
else
return m_pointsInstant . bBasePart ;
case PART_HAIR :
return GetPart ( PART_HAIR ) ;
default :
return 0 ;
}
}
BYTE CHARACTER : : GetCharType ( ) const
{
return m_bCharType ;
}
bool CHARACTER : : SetSyncOwner ( LPCHARACTER ch , bool bRemoveFromList )
{
// TRENT_MONSTER
if ( IS_SET ( m_pointsInstant . dwAIFlag , AIFLAG_NOMOVE ) )
return false ;
// END_OF_TRENT_MONSTER
if ( ch = = this )
{
sys_err ( " SetSyncOwner owner == this (%p) " , this ) ;
return false ;
}
if ( ! ch )
{
if ( bRemoveFromList & & m_pkChrSyncOwner )
{
m_pkChrSyncOwner - > m_kLst_pkChrSyncOwned . remove ( this ) ;
}
if ( m_pkChrSyncOwner )
sys_log ( 1 , " SyncRelease %s %p from %s " , GetName ( ) , this , m_pkChrSyncOwner - > GetName ( ) ) ;
// <20> <> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ʹ <EFBFBD> NULL<4C> <4C> <20> <> <EFBFBD> õǾ<C3B5> <C7BE> <EFBFBD> <20> Ѵ <EFBFBD> .
m_pkChrSyncOwner = NULL ;
}
else
{
if ( ! IsSyncOwner ( ch ) )
return false ;
// <20> Ÿ<EFBFBD> <C5B8> <EFBFBD> 200 <20> ̻<EFBFBD> <CCBB> ̸<EFBFBD> SyncOwner<65> <72> <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> .
if ( DISTANCE_APPROX ( GetX ( ) - ch - > GetX ( ) , GetY ( ) - ch - > GetY ( ) ) > 250 )
{
sys_log ( 1 , " SetSyncOwner distance over than 250 %s %s " , GetName ( ) , ch - > GetName ( ) ) ;
// SyncOwner<65> <72> <20> <> <EFBFBD> <EFBFBD> Owner<65> <72> ǥ<> <C7A5> <EFBFBD> Ѵ <EFBFBD> .
if ( m_pkChrSyncOwner = = ch )
return true ;
return false ;
}
if ( m_pkChrSyncOwner ! = ch )
{
if ( m_pkChrSyncOwner )
{
sys_log ( 1 , " SyncRelease %s %p from %s " , GetName ( ) , this , m_pkChrSyncOwner - > GetName ( ) ) ;
m_pkChrSyncOwner - > m_kLst_pkChrSyncOwned . remove ( this ) ;
}
m_pkChrSyncOwner = ch ;
m_pkChrSyncOwner - > m_kLst_pkChrSyncOwned . push_back ( this ) ;
// SyncOwner<65> <72> <20> ٲ<EFBFBD> <D9B2> <EFBFBD> LastSyncTime<6D> <65> <20> ʱ<EFBFBD> ȭ<EFBFBD> Ѵ <EFBFBD> .
static const timeval zero_tv = { 0 , 0 } ;
SetLastSyncTime ( zero_tv ) ;
sys_log ( 1 , " SetSyncOwner set %s %p to %s " , GetName ( ) , this , ch - > GetName ( ) ) ;
}
m_fSyncTime = get_float_time ( ) ;
}
// TODO: Sync Owner<65> <72> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> Ŷ<EFBFBD> <C5B6> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> ,
// <20> <> <EFBFBD> <EFBFBD> ȭ <20> <> <20> ð<EFBFBD> <C3B0> <EFBFBD> 3<> <33> <20> ̻<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ǯ<> <C7AE> <EFBFBD> ִ<EFBFBD> <20> <> Ŷ<EFBFBD> <C5B6>
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ϸ<EFBFBD> <20> <> Ŷ<EFBFBD> <C5B6> <20> <> <EFBFBD> <EFBFBD> <20> <> <20> ִ<EFBFBD> .
TPacketGCOwnership pack ;
pack . bHeader = HEADER_GC_OWNERSHIP ;
pack . dwOwnerVID = ch ? ch - > GetVID ( ) : 0 ;
pack . dwVictimVID = GetVID ( ) ;
PacketAround ( & pack , sizeof ( TPacketGCOwnership ) ) ;
return true ;
}
struct FuncClearSync
{
void operator ( ) ( LPCHARACTER ch )
{
assert ( ch ! = NULL ) ;
ch - > SetSyncOwner ( NULL , false ) ; // false <20> ÷<EFBFBD> <C3B7> <EFBFBD> <20> ؾ<EFBFBD> for_each <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> .
}
} ;
void CHARACTER : : ClearSync ( )
{
SetSyncOwner ( NULL ) ;
// <20> Ʒ <EFBFBD> for_each<63> <68> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> m_pkChrSyncOwner<65> <72> <20> <> <EFBFBD> <EFBFBD> <20> ڵ<EFBFBD> <DAB5> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> NULL<4C> <4C> <20> Ѵ <EFBFBD> .
std : : for_each ( m_kLst_pkChrSyncOwned . begin ( ) , m_kLst_pkChrSyncOwned . end ( ) , FuncClearSync ( ) ) ;
m_kLst_pkChrSyncOwned . clear ( ) ;
}
bool CHARACTER : : IsSyncOwner ( LPCHARACTER ch ) const
{
if ( m_pkChrSyncOwner = = ch )
return true ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> ȭ <20> <> <20> ð<EFBFBD> <C3B0> <EFBFBD> 3<> <33> <20> ̻<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ٸ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ƹ<EFBFBD> <C6B9> <EFBFBD> <EFBFBD> Ե<EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> . <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ƹ<EFBFBD> <C6B9> <EFBFBD> SyncOwner<65> ̹Ƿ<CCB9> true <20> <> <EFBFBD> <EFBFBD>
if ( get_float_time ( ) - m_fSyncTime > = 3.0f )
return true ;
return false ;
}
void CHARACTER : : SetParty ( LPPARTY pkParty )
{
if ( pkParty = = m_pkParty )
return ;
if ( pkParty & & m_pkParty )
sys_err ( " %s is trying to reassigning party (current %p, new party %p) " , GetName ( ) , get_pointer ( m_pkParty ) , get_pointer ( pkParty ) ) ;
sys_log ( 1 , " PARTY set to %p " , get_pointer ( pkParty ) ) ;
//if (m_pkDungeon && IsPC())
//SetDungeon(NULL);
m_pkParty = pkParty ;
if ( IsPC ( ) )
{
if ( m_pkParty )
SET_BIT ( m_bAddChrState , ADD_CHARACTER_STATE_PARTY ) ;
else
REMOVE_BIT ( m_bAddChrState , ADD_CHARACTER_STATE_PARTY ) ;
UpdatePacket ( ) ;
}
}
// PARTY_JOIN_BUG_FIX
/// <20> <> Ƽ <20> <> <EFBFBD> <EFBFBD> event <20> <> <EFBFBD> <EFBFBD>
EVENTINFO ( TPartyJoinEventInfo )
{
DWORD dwGuestPID ; ///< <20> <> Ƽ <EFBFBD> <C6BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ij<> <C4B3> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> PID
DWORD dwLeaderPID ; ///< <20> <> Ƽ <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> PID
TPartyJoinEventInfo ( )
: dwGuestPID ( 0 )
, dwLeaderPID ( 0 )
{
}
} ;
EVENTFUNC ( party_request_event )
{
TPartyJoinEventInfo * info = dynamic_cast < TPartyJoinEventInfo * > ( event - > info ) ;
if ( info = = NULL )
{
sys_err ( " party_request_event> <Factor> Null pointer " ) ;
return 0 ;
}
LPCHARACTER ch = CHARACTER_MANAGER : : instance ( ) . FindByPID ( info - > dwGuestPID ) ;
if ( ch )
{
sys_log ( 0 , " PartyRequestEvent %s " , ch - > GetName ( ) ) ;
ch - > ChatPacket ( CHAT_TYPE_COMMAND , " PartyRequestDenied " ) ;
ch - > SetPartyRequestEvent ( NULL ) ;
}
return 0 ;
}
bool CHARACTER : : RequestToParty ( LPCHARACTER leader )
{
if ( leader - > GetParty ( ) )
leader = leader - > GetParty ( ) - > GetLeaderCharacter ( ) ;
if ( ! leader )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> Ƽ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> °<EFBFBD> <20> ƴ϶<C6B4> <CFB6> <EFBFBD> <20> <> û<EFBFBD> <C3BB> <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ." ) ) ;
return false ;
}
if ( m_pkPartyRequestEvent )
return false ;
if ( ! IsPC ( ) | | ! leader - > IsPC ( ) )
return false ;
if ( leader - > IsBlockMode ( BLOCK_PARTY_REQUEST ) )
return false ;
PartyJoinErrCode errcode = IsPartyJoinableCondition ( leader , this ) ;
switch ( errcode )
{
case PERR_NONE :
break ;
case PERR_SERVER :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ƽ <20> <> <EFBFBD> <EFBFBD> ó<> <C3B3> <EFBFBD> <EFBFBD> <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return false ;
case PERR_DIFFEMPIRE :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> ٸ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ƽ <EFBFBD> <C6BC> <20> ̷<EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return false ;
case PERR_DUNGEON :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> <EFBFBD> <EFBFBD> <20> ȿ<EFBFBD> <C8BF> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ƽ <20> ʴ븦 <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return false ;
case PERR_OBSERVER :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> 忡<EFBFBD> <E5BFA1> <20> <> Ƽ <20> ʴ븦 <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return false ;
case PERR_LVBOUNDARY :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > -30 ~ +30 <20> <> <EFBFBD> <EFBFBD> <20> ̳<EFBFBD> <CCB3> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> 游 <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> ֽ<EFBFBD> <D6BD> ϴ<EFBFBD> . " ) ) ;
return false ;
case PERR_LOWLEVEL :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> Ƽ <EFBFBD> <C6BC> <20> ְ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> 30<33> <30> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return false ;
case PERR_HILEVEL :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> Ƽ <EFBFBD> <C6BC> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> 30<33> <30> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return false ;
case PERR_ALREADYJOIN :
return false ;
case PERR_PARTYISFULL :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> <20> ̻<EFBFBD> <20> <> Ƽ <EFBFBD> <C6BC> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return false ;
default :
sys_err ( " Do not process party join error(%d) " , errcode ) ;
return false ;
}
TPartyJoinEventInfo * info = AllocEventInfo < TPartyJoinEventInfo > ( ) ;
info - > dwGuestPID = GetPlayerID ( ) ;
info - > dwLeaderPID = leader - > GetPlayerID ( ) ;
SetPartyRequestEvent ( event_create ( party_request_event , info , PASSES_PER_SEC ( 10 ) ) ) ;
leader - > ChatPacket ( CHAT_TYPE_COMMAND , " PartyRequest %u " , ( DWORD ) GetVID ( ) ) ;
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " %s <20> Կ<EFBFBD> <D4BF> <EFBFBD> <20> <> Ƽ <EFBFBD> <C6BC> <EFBFBD> <EFBFBD> <20> <> û<EFBFBD> <C3BB> <20> ߽<EFBFBD> <DFBD> ϴ<EFBFBD> . " ) , leader - > GetName ( ) ) ;
return true ;
}
void CHARACTER : : DenyToParty ( LPCHARACTER member )
{
sys_log ( 1 , " DenyToParty %s member %s %p " , GetName ( ) , member - > GetName ( ) , get_pointer ( member - > m_pkPartyRequestEvent ) ) ;
if ( ! member - > m_pkPartyRequestEvent )
return ;
TPartyJoinEventInfo * info = dynamic_cast < TPartyJoinEventInfo * > ( member - > m_pkPartyRequestEvent - > info ) ;
if ( ! info )
{
sys_err ( " CHARACTER::DenyToParty> <Factor> Null pointer " ) ;
return ;
}
if ( info - > dwGuestPID ! = member - > GetPlayerID ( ) )
return ;
if ( info - > dwLeaderPID ! = GetPlayerID ( ) )
return ;
event_cancel ( & member - > m_pkPartyRequestEvent ) ;
member - > ChatPacket ( CHAT_TYPE_COMMAND , " PartyRequestDenied " ) ;
}
void CHARACTER : : AcceptToParty ( LPCHARACTER member )
{
sys_log ( 1 , " AcceptToParty %s member %s %p " , GetName ( ) , member - > GetName ( ) , get_pointer ( member - > m_pkPartyRequestEvent ) ) ;
if ( ! member - > m_pkPartyRequestEvent )
return ;
TPartyJoinEventInfo * info = dynamic_cast < TPartyJoinEventInfo * > ( member - > m_pkPartyRequestEvent - > info ) ;
if ( ! info )
{
sys_err ( " CHARACTER::AcceptToParty> <Factor> Null pointer " ) ;
return ;
}
if ( info - > dwGuestPID ! = member - > GetPlayerID ( ) )
return ;
if ( info - > dwLeaderPID ! = GetPlayerID ( ) )
return ;
event_cancel ( & member - > m_pkPartyRequestEvent ) ;
if ( ! GetParty ( ) )
member - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ƽ <EFBFBD> <C6BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ʽ <EFBFBD> <CABD> ϴ<EFBFBD> ." ) ) ;
else
{
if ( GetPlayerID ( ) ! = GetParty ( ) - > GetLeaderPID ( ) )
return ;
PartyJoinErrCode errcode = IsPartyJoinableCondition ( this , member ) ;
switch ( errcode )
{
case PERR_NONE : member - > PartyJoin ( this ) ; return ;
case PERR_SERVER : member - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ƽ <20> <> <EFBFBD> <EFBFBD> ó<> <C3B3> <EFBFBD> <EFBFBD> <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ; break ;
case PERR_DUNGEON : member - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> <EFBFBD> <EFBFBD> <20> ȿ<EFBFBD> <C8BF> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ƽ <20> ʴ븦 <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ; break ;
case PERR_OBSERVER : member - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> 忡<EFBFBD> <E5BFA1> <20> <> Ƽ <20> ʴ븦 <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ; break ;
case PERR_LVBOUNDARY : member - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > -30 ~ +30 <20> <> <EFBFBD> <EFBFBD> <20> ̳<EFBFBD> <CCB3> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> 游 <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> ֽ<EFBFBD> <D6BD> ϴ<EFBFBD> . " ) ) ; break ;
case PERR_LOWLEVEL : member - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> Ƽ <EFBFBD> <C6BC> <20> ְ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> 30<33> <30> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ; break ;
case PERR_HILEVEL : member - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> Ƽ <EFBFBD> <C6BC> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> 30<33> <30> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ; break ;
case PERR_ALREADYJOIN : break ;
case PERR_PARTYISFULL : {
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> <20> ̻<EFBFBD> <20> <> Ƽ <EFBFBD> <C6BC> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
member - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> Ƽ <EFBFBD> <C6BC> <20> ο <EFBFBD> <CEBF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ʰ<EFBFBD> <CAB0> Ͽ<EFBFBD> <20> <> Ƽ <EFBFBD> <C6BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
break ;
}
default : sys_err ( " Do not process party join error(%d) " , errcode ) ;
}
}
member - > ChatPacket ( CHAT_TYPE_COMMAND , " PartyRequestDenied " ) ;
}
/**
* <EFBFBD> <EFBFBD> Ƽ <EFBFBD> ʴ <EFBFBD> event callback <EFBFBD> Լ <EFBFBD> .
* event <EFBFBD> <EFBFBD> <EFBFBD> ߵ <EFBFBD> <EFBFBD> ϸ <EFBFBD> <EFBFBD> ʴ <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ó <EFBFBD> <EFBFBD> <EFBFBD> Ѵ <EFBFBD> .
*/
EVENTFUNC ( party_invite_event )
{
TPartyJoinEventInfo * pInfo = dynamic_cast < TPartyJoinEventInfo * > ( event - > info ) ;
if ( pInfo = = NULL )
{
sys_err ( " party_invite_event> <Factor> Null pointer " ) ;
return 0 ;
}
LPCHARACTER pchInviter = CHARACTER_MANAGER : : instance ( ) . FindByPID ( pInfo - > dwLeaderPID ) ;
if ( pchInviter )
{
sys_log ( 1 , " PartyInviteEvent %s " , pchInviter - > GetName ( ) ) ;
pchInviter - > PartyInviteDeny ( pInfo - > dwGuestPID ) ;
}
return 0 ;
}
void CHARACTER : : PartyInvite ( LPCHARACTER pchInvitee )
{
if ( GetParty ( ) & & GetParty ( ) - > GetLeaderPID ( ) ! = GetPlayerID ( ) )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> Ƽ <EFBFBD> <C6BC> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
}
else if ( pchInvitee - > IsBlockMode ( BLOCK_PARTY_INVITE ) )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > %s <20> <> <EFBFBD> <EFBFBD> <20> <> Ƽ <20> ź<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Դϴ<D4B4> . " ) , pchInvitee - > GetName ( ) ) ;
return ;
}
PartyJoinErrCode errcode = IsPartyJoinableCondition ( this , pchInvitee ) ;
switch ( errcode )
{
case PERR_NONE :
break ;
case PERR_SERVER :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ƽ <20> <> <EFBFBD> <EFBFBD> ó<> <C3B3> <EFBFBD> <EFBFBD> <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
case PERR_DIFFEMPIRE :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> ٸ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ƽ <EFBFBD> <C6BC> <20> ̷<EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
case PERR_DUNGEON :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> <EFBFBD> <EFBFBD> <20> ȿ<EFBFBD> <C8BF> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ƽ <20> ʴ븦 <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
case PERR_OBSERVER :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> 忡<EFBFBD> <E5BFA1> <20> <> Ƽ <20> ʴ븦 <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
case PERR_LVBOUNDARY :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > -30 ~ +30 <20> <> <EFBFBD> <EFBFBD> <20> ̳<EFBFBD> <CCB3> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> 游 <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> ֽ<EFBFBD> <D6BD> ϴ<EFBFBD> . " ) ) ;
return ;
case PERR_LOWLEVEL :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> Ƽ <EFBFBD> <C6BC> <20> ְ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> 30<33> <30> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
case PERR_HILEVEL :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> Ƽ <EFBFBD> <C6BC> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> 30<33> <30> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
case PERR_ALREADYJOIN :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> ̹<EFBFBD> %s<> <73> <EFBFBD> <EFBFBD> <20> <> Ƽ <EFBFBD> <C6BC> <20> <> <EFBFBD> <EFBFBD> <20> ֽ<EFBFBD> <D6BD> ϴ<EFBFBD> . " ) , pchInvitee - > GetName ( ) ) ;
return ;
case PERR_PARTYISFULL :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> <20> ̻<EFBFBD> <20> <> Ƽ <EFBFBD> <C6BC> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
default :
sys_err ( " Do not process party join error(%d) " , errcode ) ;
return ;
}
if ( m_PartyInviteEventMap . end ( ) ! = m_PartyInviteEventMap . find ( pchInvitee - > GetPlayerID ( ) ) )
return ;
//
// EventMap <20> <> <20> ̺<EFBFBD> Ʈ <20> ߰<EFBFBD>
//
TPartyJoinEventInfo * info = AllocEventInfo < TPartyJoinEventInfo > ( ) ;
info - > dwGuestPID = pchInvitee - > GetPlayerID ( ) ;
info - > dwLeaderPID = GetPlayerID ( ) ;
m_PartyInviteEventMap . insert ( EventMap : : value_type ( pchInvitee - > GetPlayerID ( ) , event_create ( party_invite_event , info , PASSES_PER_SEC ( 10 ) ) ) ) ;
//
// <20> ʴ<EFBFBD> <20> <EFBFBD> character <20> <> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <20> <> Ŷ <20> <> <EFBFBD> <EFBFBD>
//
TPacketGCPartyInvite p ;
p . header = HEADER_GC_PARTY_INVITE ;
p . leader_vid = GetVID ( ) ;
pchInvitee - > GetDesc ( ) - > Packet ( & p , sizeof ( p ) ) ;
}
void CHARACTER : : PartyInviteAccept ( LPCHARACTER pchInvitee )
{
EventMap : : iterator itFind = m_PartyInviteEventMap . find ( pchInvitee - > GetPlayerID ( ) ) ;
if ( itFind = = m_PartyInviteEventMap . end ( ) )
{
sys_log ( 1 , " PartyInviteAccept from not invited character(%s) " , pchInvitee - > GetName ( ) ) ;
return ;
}
event_cancel ( & itFind - > second ) ;
m_PartyInviteEventMap . erase ( itFind ) ;
if ( GetParty ( ) & & GetParty ( ) - > GetLeaderPID ( ) ! = GetPlayerID ( ) )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> Ƽ <EFBFBD> <C6BC> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
}
PartyJoinErrCode errcode = IsPartyJoinableMutableCondition ( this , pchInvitee ) ;
switch ( errcode )
{
case PERR_NONE :
break ;
case PERR_SERVER :
pchInvitee - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ƽ <20> <> <EFBFBD> <EFBFBD> ó<> <C3B3> <EFBFBD> <EFBFBD> <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
case PERR_DUNGEON :
pchInvitee - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> <EFBFBD> <EFBFBD> <20> ȿ<EFBFBD> <C8BF> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> Ƽ <20> ʴ뿡 <20> <> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
case PERR_OBSERVER :
pchInvitee - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> 忡<EFBFBD> <E5BFA1> <20> <> Ƽ <20> ʴ븦 <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
case PERR_LVBOUNDARY :
pchInvitee - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > -30 ~ +30 <20> <> <EFBFBD> <EFBFBD> <20> ̳<EFBFBD> <CCB3> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> 游 <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> ֽ<EFBFBD> <D6BD> ϴ<EFBFBD> . " ) ) ;
return ;
case PERR_LOWLEVEL :
pchInvitee - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> Ƽ <EFBFBD> <C6BC> <20> ְ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> 30<33> <30> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
case PERR_HILEVEL :
pchInvitee - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> Ƽ <EFBFBD> <C6BC> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> 30<33> <30> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
case PERR_ALREADYJOIN :
pchInvitee - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> Ƽ <20> ʴ뿡 <20> <> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
case PERR_PARTYISFULL :
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> <20> ̻<EFBFBD> <20> <> Ƽ <EFBFBD> <C6BC> <EFBFBD> <EFBFBD> <20> ʴ<EFBFBD> <CAB4> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
pchInvitee - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > <20> <> Ƽ <EFBFBD> <C6BC> <20> ο <EFBFBD> <CEBF> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ʰ<EFBFBD> <CAB0> Ͽ<EFBFBD> <20> <> Ƽ <EFBFBD> <C6BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
default :
sys_err ( " ignore party join error(%d) " , errcode ) ;
return ;
}
//
// <20> <> Ƽ <20> <> <EFBFBD> <EFBFBD> ó<> <C3B3>
//
if ( GetParty ( ) )
pchInvitee - > PartyJoin ( this ) ;
else
{
LPPARTY pParty = CPartyManager : : instance ( ) . CreateParty ( this ) ;
pParty - > Join ( pchInvitee - > GetPlayerID ( ) ) ;
pParty - > Link ( pchInvitee ) ;
pParty - > SendPartyInfoAllToOne ( this ) ;
}
}
void CHARACTER : : PartyInviteDeny ( DWORD dwPID )
{
EventMap : : iterator itFind = m_PartyInviteEventMap . find ( dwPID ) ;
if ( itFind = = m_PartyInviteEventMap . end ( ) )
{
sys_log ( 1 , " PartyInviteDeny to not exist event(inviter PID: %d, invitee PID: %d) " , GetPlayerID ( ) , dwPID ) ;
return ;
}
event_cancel ( & itFind - > second ) ;
m_PartyInviteEventMap . erase ( itFind ) ;
LPCHARACTER pchInvitee = CHARACTER_MANAGER : : instance ( ) . FindByPID ( dwPID ) ;
if ( pchInvitee )
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > %s<> <73> <EFBFBD> <EFBFBD> <20> <> Ƽ <20> ʴ븦 <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϼ̽<CFBC> <CCBD> ϴ<EFBFBD> . " ) , pchInvitee - > GetName ( ) ) ;
}
void CHARACTER : : PartyJoin ( LPCHARACTER pLeader )
{
pLeader - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > %s<> <73> <EFBFBD> <EFBFBD> <20> <> Ƽ <EFBFBD> <C6BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϼ̽<CFBC> <CCBD> ϴ<EFBFBD> . " ) , GetName ( ) ) ;
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <<3C> <> Ƽ > %s<> <73> <EFBFBD> <EFBFBD> <20> <> Ƽ <EFBFBD> <C6BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϼ̽<CFBC> <CCBD> ϴ<EFBFBD> . " ) , pLeader - > GetName ( ) ) ;
pLeader - > GetParty ( ) - > Join ( GetPlayerID ( ) ) ;
pLeader - > GetParty ( ) - > Link ( this ) ;
}
CHARACTER : : PartyJoinErrCode CHARACTER : : IsPartyJoinableCondition ( const LPCHARACTER pchLeader , const LPCHARACTER pchGuest )
{
if ( pchLeader - > GetEmpire ( ) ! = pchGuest - > GetEmpire ( ) )
return PERR_DIFFEMPIRE ;
return IsPartyJoinableMutableCondition ( pchLeader , pchGuest ) ;
}
static bool __party_can_join_by_level ( LPCHARACTER leader , LPCHARACTER quest )
{
int level_limit = 30 ;
if ( LC_IsCanada ( ) )
level_limit = 15 ;
else if ( LC_IsBrazil ( ) = = true )
{
level_limit = 10 ;
}
else
level_limit = 30 ;
return ( abs ( leader - > GetLevel ( ) - quest - > GetLevel ( ) ) < = level_limit ) ;
}
CHARACTER : : PartyJoinErrCode CHARACTER : : IsPartyJoinableMutableCondition ( const LPCHARACTER pchLeader , const LPCHARACTER pchGuest )
{
if ( ! CPartyManager : : instance ( ) . IsEnablePCParty ( ) )
return PERR_SERVER ;
else if ( pchLeader - > GetDungeon ( ) )
return PERR_DUNGEON ;
else if ( pchGuest - > IsObserverMode ( ) )
return PERR_OBSERVER ;
else if ( false = = __party_can_join_by_level ( pchLeader , pchGuest ) )
return PERR_LVBOUNDARY ;
else if ( pchGuest - > GetParty ( ) )
return PERR_ALREADYJOIN ;
else if ( pchLeader - > GetParty ( ) )
{
if ( pchLeader - > GetParty ( ) - > GetMemberCount ( ) = = PARTY_MAX_MEMBER )
return PERR_PARTYISFULL ;
}
return PERR_NONE ;
}
// END_OF_PARTY_JOIN_BUG_FIX
void CHARACTER : : SetDungeon ( LPDUNGEON pkDungeon )
{
if ( pkDungeon & & m_pkDungeon )
sys_err ( " %s is trying to reassigning dungeon (current %p, new party %p) " , GetName ( ) , get_pointer ( m_pkDungeon ) , get_pointer ( pkDungeon ) ) ;
if ( m_pkDungeon = = pkDungeon ) {
return ;
}
if ( m_pkDungeon )
{
if ( IsPC ( ) )
{
if ( GetParty ( ) )
m_pkDungeon - > DecPartyMember ( GetParty ( ) , this ) ;
else
m_pkDungeon - > DecMember ( this ) ;
}
else if ( IsMonster ( ) | | IsStone ( ) )
{
m_pkDungeon - > DecMonster ( ) ;
}
}
m_pkDungeon = pkDungeon ;
if ( pkDungeon )
{
sys_log ( 0 , " %s DUNGEON set to %p, PARTY is %p " , GetName ( ) , get_pointer ( pkDungeon ) , get_pointer ( m_pkParty ) ) ;
if ( IsPC ( ) )
{
if ( GetParty ( ) )
m_pkDungeon - > IncPartyMember ( GetParty ( ) , this ) ;
else
m_pkDungeon - > IncMember ( this ) ;
}
else if ( IsMonster ( ) | | IsStone ( ) )
{
m_pkDungeon - > IncMonster ( ) ;
}
}
}
void CHARACTER : : SetWarMap ( CWarMap * pWarMap )
{
if ( m_pWarMap )
m_pWarMap - > DecMember ( this ) ;
m_pWarMap = pWarMap ;
if ( m_pWarMap )
m_pWarMap - > IncMember ( this ) ;
}
void CHARACTER : : SetWeddingMap ( marriage : : WeddingMap * pMap )
{
if ( m_pWeddingMap )
m_pWeddingMap - > DecMember ( this ) ;
m_pWeddingMap = pMap ;
if ( m_pWeddingMap )
m_pWeddingMap - > IncMember ( this ) ;
}
void CHARACTER : : SetRegen ( LPREGEN pkRegen )
{
m_pkRegen = pkRegen ;
if ( pkRegen ! = NULL ) {
regen_id_ = pkRegen - > id ;
}
m_fRegenAngle = GetRotation ( ) ;
m_posRegen = GetXYZ ( ) ;
}
bool CHARACTER : : OnIdle ( )
{
return false ;
}
void CHARACTER : : OnMove ( bool bIsAttack )
{
m_dwLastMoveTime = get_dword_time ( ) ;
if ( bIsAttack )
{
m_dwLastAttackTime = m_dwLastMoveTime ;
if ( IsAffectFlag ( AFF_REVIVE_INVISIBLE ) )
RemoveAffect ( AFFECT_REVIVE_INVISIBLE ) ;
if ( IsAffectFlag ( AFF_EUNHYUNG ) )
{
RemoveAffect ( SKILL_EUNHYUNG ) ;
SetAffectedEunhyung ( ) ;
}
else
{
ClearAffectedEunhyung ( ) ;
}
/*if (IsAffectFlag(AFF_JEONSIN))
RemoveAffect ( SKILL_JEONSINBANGEO ) ; */
}
/*if (IsAffectFlag(AFF_GUNGON))
RemoveAffect ( SKILL_GUNGON ) ; */
// MINING
mining_cancel ( ) ;
// END_OF_MINING
}
void CHARACTER : : OnClick ( LPCHARACTER pkChrCauser )
{
if ( ! pkChrCauser )
{
sys_err ( " OnClick %s by NULL " , GetName ( ) ) ;
return ;
}
DWORD vid = GetVID ( ) ;
sys_log ( 0 , " OnClick %s[vnum %d ServerUniqueID %d, pid %d] by %s " , GetName ( ) , GetRaceNum ( ) , vid , GetPlayerID ( ) , pkChrCauser - > GetName ( ) ) ;
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ·<EFBFBD> <20> <> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> .
{
// <20> <> , <20> ڽ<EFBFBD> <DABD> <EFBFBD> <20> ڽ<EFBFBD> <DABD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŭ<> <C5AC> <EFBFBD> <EFBFBD> <20> <> <20> ִ<EFBFBD> .
if ( pkChrCauser - > GetMyShop ( ) & & pkChrCauser ! = this )
{
sys_err ( " OnClick Fail (%s->%s) - pc has shop " , pkChrCauser - > GetName ( ) , GetName ( ) ) ;
return ;
}
}
// <20> <> ȯ<EFBFBD> <C8AF> <EFBFBD> ϶<EFBFBD> <20> <> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> .
{
if ( pkChrCauser - > GetExchange ( ) )
{
sys_err ( " OnClick Fail (%s->%s) - pc is exchanging " , pkChrCauser - > GetName ( ) , GetName ( ) ) ;
return ;
}
}
if ( IsPC ( ) )
{
// Ÿ<> <C5B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> PC<50> <43> <20> <> <EFBFBD> <EFBFBD> Ŭ<> <C5AC> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> Ʈ<EFBFBD> <C6AE> ó<> <C3B3> <EFBFBD> ϵ<EFBFBD> <CFB5> <EFBFBD> <20> մϴ<D5B4> .
if ( ! CTargetManager : : instance ( ) . GetTargetInfo ( pkChrCauser - > GetPlayerID ( ) , TARGET_TYPE_VID , GetVID ( ) ) )
{
// 2005.03.17.myevan.Ÿ<> <C5B8> <EFBFBD> <EFBFBD> <20> ƴ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> ó<> <C3B3> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ۵ <EFBFBD> <DBB5> <EFBFBD> Ų<EFBFBD> <C5B2> .
if ( GetMyShop ( ) )
{
if ( pkChrCauser - > IsDead ( ) = = true ) return ;
//PREVENT_TRADE_WINDOW
if ( pkChrCauser = = this ) // <20> ڱ<EFBFBD> <DAB1> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
{
if ( ( GetExchange ( ) | | IsOpenSafebox ( ) | | GetShopOwner ( ) ) | | IsCubeOpen ( ) )
{
pkChrCauser - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> ٸ<EFBFBD> <20> ŷ<EFBFBD> <C5B7> <EFBFBD> (â<> <C3A2> ,<2C> <> ȯ,<2C> <> <EFBFBD> <EFBFBD> )<29> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> λ<EFBFBD> <CEBB> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ." ) ) ;
return ;
}
}
else // <20> ٸ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ŭ<> <C5AC> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
{
// Ŭ<> <C5AC> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ȯ/â<> <C3A2> /<2F> <> <EFBFBD> λ<EFBFBD> <CEBB> <EFBFBD> /<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> ̿<EFBFBD> <CCBF> <EFBFBD> <EFBFBD> ̶<EFBFBD> <CCB6> <EFBFBD> <20> Ұ<EFBFBD>
if ( ( pkChrCauser - > GetExchange ( ) | | pkChrCauser - > IsOpenSafebox ( ) | | pkChrCauser - > GetMyShop ( ) | | pkChrCauser - > GetShopOwner ( ) ) | | pkChrCauser - > IsCubeOpen ( ) )
{
pkChrCauser - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> ٸ<EFBFBD> <20> ŷ<EFBFBD> <C5B7> <EFBFBD> (â<> <C3A2> ,<2C> <> ȯ,<2C> <> <EFBFBD> <EFBFBD> )<29> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> λ<EFBFBD> <CEBB> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ." ) ) ;
return ;
}
// Ŭ<> <C5AC> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ȯ/â<> <C3A2> /<2F> <> <EFBFBD> <EFBFBD> <EFBFBD> ̿<EFBFBD> <CCBF> <EFBFBD> <EFBFBD> ̶<EFBFBD> <CCB6> <EFBFBD> <20> Ұ<EFBFBD>
//if ((GetExchange() || IsOpenSafebox() || GetShopOwner()))
if ( ( GetExchange ( ) | | IsOpenSafebox ( ) | | IsCubeOpen ( ) ) )
{
pkChrCauser - > ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ٸ<EFBFBD> <20> ŷ<EFBFBD> <C5B7> <EFBFBD> <20> ϰ<EFBFBD> <20> ִ<EFBFBD> <20> <> <EFBFBD> Դϴ<D4B4> ." ) ) ;
return ;
}
}
//END_PREVENT_TRADE_WINDOW
if ( pkChrCauser - > GetShop ( ) )
{
pkChrCauser - > GetShop ( ) - > RemoveGuest ( pkChrCauser ) ;
pkChrCauser - > SetShop ( NULL ) ;
}
GetMyShop ( ) - > AddGuest ( pkChrCauser , GetVID ( ) , false ) ;
pkChrCauser - > SetShopOwner ( this ) ;
return ;
}
if ( test_server )
sys_err ( " %s.OnClickFailure(%s) - target is PC " , pkChrCauser - > GetName ( ) , GetName ( ) ) ;
return ;
}
}
// û<> ҳ<EFBFBD> <D2B3> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> Ʈ <20> <> <EFBFBD> <EFBFBD>
if ( LC_IsNewCIBN ( ) )
{
if ( pkChrCauser - > IsOverTime ( OT_3HOUR ) )
{
sys_log ( 0 , " Teen OverTime : name = %s, hour = %d) " , pkChrCauser - > GetName ( ) , 3 ) ;
return ;
}
else if ( pkChrCauser - > IsOverTime ( OT_5HOUR ) )
{
sys_log ( 0 , " Teen OverTime : name = %s, hour = %d) " , pkChrCauser - > GetName ( ) , 5 ) ;
return ;
}
}
pkChrCauser - > SetQuestNPCID ( GetVID ( ) ) ;
if ( quest : : CQuestManager : : instance ( ) . Click ( pkChrCauser - > GetPlayerID ( ) , this ) )
{
return ;
}
// NPC <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> : <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <>
if ( ! IsPC ( ) )
{
if ( ! m_triggerOnClick . pFunc )
{
// NPC Ʈ<> <C6AE> <EFBFBD> <EFBFBD> <20> ý<EFBFBD> <C3BD> <EFBFBD> <20> α <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
//sys_err("%s.OnClickFailure(%s) : triggerOnClick.pFunc is EMPTY(pid=%d)",
// pkChrCauser->GetName(),
// GetName(),
// pkChrCauser->GetPlayerID());
return ;
}
m_triggerOnClick . pFunc ( this , pkChrCauser ) ;
}
}
BYTE CHARACTER : : GetGMLevel ( ) const
{
if ( test_server )
return GM_IMPLEMENTOR ;
return m_pointsInstant . gm_level ;
}
void CHARACTER : : SetGMLevel ( )
{
if ( GetDesc ( ) )
{
m_pointsInstant . gm_level = gm_get_level ( GetName ( ) , GetDesc ( ) - > GetHostName ( ) , GetDesc ( ) - > GetAccountTable ( ) . login ) ;
}
else
{
m_pointsInstant . gm_level = GM_PLAYER ;
}
}
BOOL CHARACTER : : IsGM ( ) const
{
if ( m_pointsInstant . gm_level ! = GM_PLAYER )
return true ;
if ( test_server )
return true ;
return false ;
}
void CHARACTER : : SetStone ( LPCHARACTER pkChrStone )
{
m_pkChrStone = pkChrStone ;
if ( m_pkChrStone )
{
if ( pkChrStone - > m_set_pkChrSpawnedBy . find ( this ) = = pkChrStone - > m_set_pkChrSpawnedBy . end ( ) )
pkChrStone - > m_set_pkChrSpawnedBy . insert ( this ) ;
}
}
struct FuncDeadSpawnedByStone
{
void operator ( ) ( LPCHARACTER ch )
{
ch - > Dead ( NULL ) ;
ch - > SetStone ( NULL ) ;
}
} ;
void CHARACTER : : ClearStone ( )
{
if ( ! m_set_pkChrSpawnedBy . empty ( ) )
{
// <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ų <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ͵<EFBFBD> <CDB5> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> δ<EFBFBD> .
FuncDeadSpawnedByStone f ;
std : : for_each ( m_set_pkChrSpawnedBy . begin ( ) , m_set_pkChrSpawnedBy . end ( ) , f ) ;
m_set_pkChrSpawnedBy . clear ( ) ;
}
if ( ! m_pkChrStone )
return ;
m_pkChrStone - > m_set_pkChrSpawnedBy . erase ( this ) ;
m_pkChrStone = NULL ;
}
void CHARACTER : : ClearTarget ( )
{
if ( m_pkChrTarget )
{
m_pkChrTarget - > m_set_pkChrTargetedBy . erase ( this ) ;
m_pkChrTarget = NULL ;
}
TPacketGCTarget p ;
p . header = HEADER_GC_TARGET ;
p . dwVID = 0 ;
p . bHPPercent = 0 ;
CHARACTER_SET : : iterator it = m_set_pkChrTargetedBy . begin ( ) ;
while ( it ! = m_set_pkChrTargetedBy . end ( ) )
{
LPCHARACTER pkChr = * ( it + + ) ;
pkChr - > m_pkChrTarget = NULL ;
if ( ! pkChr - > GetDesc ( ) )
{
sys_err ( " %s %p does not have desc " , pkChr - > GetName ( ) , get_pointer ( pkChr ) ) ;
abort ( ) ;
}
pkChr - > GetDesc ( ) - > Packet ( & p , sizeof ( TPacketGCTarget ) ) ;
}
m_set_pkChrTargetedBy . clear ( ) ;
}
void CHARACTER : : SetTarget ( LPCHARACTER pkChrTarget )
{
if ( m_pkChrTarget = = pkChrTarget )
return ;
// CASTLE
if ( IS_CASTLE_MAP ( GetMapIndex ( ) ) & & ! IsGM ( ) )
return ;
// CASTLE
if ( m_pkChrTarget )
m_pkChrTarget - > m_set_pkChrTargetedBy . erase ( this ) ;
m_pkChrTarget = pkChrTarget ;
TPacketGCTarget p ;
p . header = HEADER_GC_TARGET ;
if ( m_pkChrTarget )
{
m_pkChrTarget - > m_set_pkChrTargetedBy . insert ( this ) ;
p . dwVID = m_pkChrTarget - > GetVID ( ) ;
if ( m_pkChrTarget - > IsPC ( ) & & ! m_pkChrTarget - > IsPolymorphed ( ) | | m_pkChrTarget - > GetMaxHP ( ) < = 0 )
p . bHPPercent = 0 ;
else
{
if ( m_pkChrTarget - > GetRaceNum ( ) = = 20101 | |
m_pkChrTarget - > GetRaceNum ( ) = = 20102 | |
m_pkChrTarget - > GetRaceNum ( ) = = 20103 | |
m_pkChrTarget - > GetRaceNum ( ) = = 20104 | |
m_pkChrTarget - > GetRaceNum ( ) = = 20105 | |
m_pkChrTarget - > GetRaceNum ( ) = = 20106 | |
m_pkChrTarget - > GetRaceNum ( ) = = 20107 | |
m_pkChrTarget - > GetRaceNum ( ) = = 20108 | |
m_pkChrTarget - > GetRaceNum ( ) = = 20109 )
{
LPCHARACTER owner = m_pkChrTarget - > GetVictim ( ) ;
if ( owner )
{
int iHorseHealth = owner - > GetHorseHealth ( ) ;
int iHorseMaxHealth = owner - > GetHorseMaxHealth ( ) ;
if ( iHorseMaxHealth )
2022-11-27 22:18:08 +02:00
p . bHPPercent = std : : clamp ( iHorseHealth * 100 / iHorseMaxHealth , 0 , 100 ) ;
2022-03-05 12:44:06 +02:00
else
p . bHPPercent = 100 ;
}
else
p . bHPPercent = 100 ;
}
else
2022-11-27 22:18:08 +02:00
p . bHPPercent = std : : clamp ( ( m_pkChrTarget - > GetHP ( ) * 100 ) / m_pkChrTarget - > GetMaxHP ( ) , 0 , 100 ) ;
2022-03-05 12:44:06 +02:00
}
}
else
{
p . dwVID = 0 ;
p . bHPPercent = 0 ;
}
GetDesc ( ) - > Packet ( & p , sizeof ( TPacketGCTarget ) ) ;
}
void CHARACTER : : BroadcastTargetPacket ( )
{
if ( m_set_pkChrTargetedBy . empty ( ) )
return ;
TPacketGCTarget p ;
p . header = HEADER_GC_TARGET ;
p . dwVID = GetVID ( ) ;
if ( IsPC ( ) )
p . bHPPercent = 0 ;
else
2022-11-27 22:18:08 +02:00
p . bHPPercent = std : : clamp ( ( GetHP ( ) * 100 ) / GetMaxHP ( ) , 0 , 100 ) ;
2022-03-05 12:44:06 +02:00
CHARACTER_SET : : iterator it = m_set_pkChrTargetedBy . begin ( ) ;
while ( it ! = m_set_pkChrTargetedBy . end ( ) )
{
LPCHARACTER pkChr = * it + + ;
if ( ! pkChr - > GetDesc ( ) )
{
sys_err ( " %s %p does not have desc " , pkChr - > GetName ( ) , get_pointer ( pkChr ) ) ;
abort ( ) ;
}
pkChr - > GetDesc ( ) - > Packet ( & p , sizeof ( TPacketGCTarget ) ) ;
}
}
void CHARACTER : : CheckTarget ( )
{
if ( ! m_pkChrTarget )
return ;
if ( DISTANCE_APPROX ( GetX ( ) - m_pkChrTarget - > GetX ( ) , GetY ( ) - m_pkChrTarget - > GetY ( ) ) > = 4800 )
SetTarget ( NULL ) ;
}
2022-03-12 11:39:41 +02:00
void CHARACTER : : SetWarpLocation ( int lMapIndex , int x , int y )
2022-03-05 12:44:06 +02:00
{
m_posWarp . x = x * 100 ;
m_posWarp . y = y * 100 ;
m_lWarpMapIndex = lMapIndex ;
}
void CHARACTER : : SaveExitLocation ( )
{
m_posExit = GetXYZ ( ) ;
m_lExitMapIndex = GetMapIndex ( ) ;
}
void CHARACTER : : ExitToSavedLocation ( )
{
sys_log ( 0 , " ExitToSavedLocation " ) ;
WarpSet ( m_posWarp . x , m_posWarp . y , m_lWarpMapIndex ) ;
m_posExit . x = m_posExit . y = m_posExit . z = 0 ;
m_lExitMapIndex = 0 ;
}
// fixme
// <20> <> <EFBFBD> ݱ<EFBFBD> <DDB1> <EFBFBD> privateMapIndex <20> <> <20> <> <EFBFBD> <EFBFBD> <20> <> <20> ε<EFBFBD> <CEB5> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> üũ <20> ϴ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ܺο <DCBA> <CEBF> <EFBFBD> <20> ϰ<EFBFBD> ,
// <20> ٸ<EFBFBD> <D9B8> <EFBFBD> warpset<65> <74> <20> ҷ<EFBFBD> <D2B7> µ<EFBFBD>
// <20> ̸<EFBFBD> warpset <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> .
2022-03-12 11:39:41 +02:00
bool CHARACTER : : WarpSet ( int x , int y , int lPrivateMapIndex )
2022-03-05 12:44:06 +02:00
{
if ( ! IsPC ( ) )
return false ;
2022-03-12 11:39:41 +02:00
LONG lAddr ;
int lMapIndex ;
2022-03-05 12:44:06 +02:00
WORD wPort ;
if ( ! CMapLocation : : instance ( ) . Get ( x , y , lMapIndex , lAddr , wPort ) )
{
sys_err ( " cannot find map location index %d x %d y %d name %s " , lMapIndex , x , y , GetName ( ) ) ;
return false ;
}
//Send Supplementary Data Block if new map requires security packages in loading this map
{
2022-03-12 11:39:41 +02:00
LONG lCurAddr ;
int lCurMapIndex = 0 ;
2022-03-05 12:44:06 +02:00
WORD wCurPort ;
CMapLocation : : instance ( ) . Get ( GetX ( ) , GetY ( ) , lCurMapIndex , lCurAddr , wCurPort ) ;
//do not send SDB files if char is in the same map
if ( lCurMapIndex ! = lMapIndex )
{
const TMapRegion * rMapRgn = SECTREE_MANAGER : : instance ( ) . GetMapRegion ( lMapIndex ) ;
{
DESC_MANAGER : : instance ( ) . SendClientPackageSDBToLoadMap ( GetDesc ( ) , rMapRgn - > strMapName . c_str ( ) ) ;
}
}
}
if ( lPrivateMapIndex > = 10000 )
{
if ( lPrivateMapIndex / 10000 ! = lMapIndex )
{
sys_err ( " Invalid map inedx %d, must be child of %d " , lPrivateMapIndex , lMapIndex ) ;
return false ;
}
lMapIndex = lPrivateMapIndex ;
}
Stop ( ) ;
Save ( ) ;
if ( GetSectree ( ) )
{
GetSectree ( ) - > RemoveEntity ( this ) ;
ViewCleanup ( ) ;
EncodeRemovePacket ( this ) ;
}
m_lWarpMapIndex = lMapIndex ;
m_posWarp . x = x ;
m_posWarp . y = y ;
sys_log ( 0 , " WarpSet %s %d %d current map %d target map %d " , GetName ( ) , x , y , GetMapIndex ( ) , lMapIndex ) ;
TPacketGCWarp p ;
p . bHeader = HEADER_GC_WARP ;
p . lX = x ;
p . lY = y ;
p . lAddr = lAddr ;
p . wPort = wPort ;
GetDesc ( ) - > Packet ( & p , sizeof ( TPacketGCWarp ) ) ;
//if (!LC_IsNewCIBN())
{
char buf [ 256 ] ;
2022-03-12 11:39:41 +02:00
snprintf ( buf , sizeof ( buf ) , " %s MapIdx %d DestMapIdx%d DestX%d DestY%d Empire%d " , GetName ( ) , GetMapIndex ( ) , lPrivateMapIndex , x , y , GetEmpire ( ) ) ;
2022-03-05 12:44:06 +02:00
LogManager : : instance ( ) . CharLog ( this , 0 , " WARP " , buf ) ;
}
return true ;
}
void CHARACTER : : WarpEnd ( )
{
if ( test_server )
sys_log ( 0 , " WarpEnd %s " , GetName ( ) ) ;
if ( m_posWarp . x = = 0 & & m_posWarp . y = = 0 )
return ;
int index = m_lWarpMapIndex ;
if ( index > 10000 )
index / = 10000 ;
if ( ! map_allow_find ( index ) )
{
// <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϱ <EFBFBD> <20> <> <20> <> ǥ<EFBFBD> <C7A5> <20> ǵ<EFBFBD> <C7B5> <EFBFBD> <EFBFBD> <EFBFBD> .
sys_err ( " location %d %d not allowed to login this server " , m_posWarp . x , m_posWarp . y ) ;
GetDesc ( ) - > SetPhase ( PHASE_CLOSE ) ;
return ;
}
sys_log ( 0 , " WarpEnd %s %d %u %u " , GetName ( ) , m_lWarpMapIndex , m_posWarp . x , m_posWarp . y ) ;
Show ( m_lWarpMapIndex , m_posWarp . x , m_posWarp . y , 0 ) ;
Stop ( ) ;
m_lWarpMapIndex = 0 ;
m_posWarp . x = m_posWarp . y = m_posWarp . z = 0 ;
{
// P2P Login
TPacketGGLogin p ;
p . bHeader = HEADER_GG_LOGIN ;
2022-03-05 19:59:39 +02:00
strncpy ( p . szName , GetName ( ) , sizeof ( p . szName ) ) ;
2022-03-05 12:44:06 +02:00
p . dwPID = GetPlayerID ( ) ;
p . bEmpire = GetEmpire ( ) ;
p . lMapIndex = SECTREE_MANAGER : : instance ( ) . GetMapIndex ( GetX ( ) , GetY ( ) ) ;
p . bChannel = g_bChannel ;
P2P_MANAGER : : instance ( ) . Send ( & p , sizeof ( TPacketGGLogin ) ) ;
}
}
bool CHARACTER : : Return ( )
{
if ( ! IsNPC ( ) )
return false ;
int x , y ;
/*
float fDist = DISTANCE_SQRT ( m_pkMobData - > m_posLastAttacked . x - GetX ( ) , m_pkMobData - > m_posLastAttacked . y - GetY ( ) ) ;
float fx , fy ;
GetDeltaByDegree ( GetRotation ( ) , fDist , & fx , & fy ) ;
x = GetX ( ) + ( int ) fx ;
y = GetY ( ) + ( int ) fy ;
*/
SetVictim ( NULL ) ;
x = m_pkMobInst - > m_posLastAttacked . x ;
y = m_pkMobInst - > m_posLastAttacked . y ;
SetRotationToXY ( x , y ) ;
if ( ! Goto ( x , y ) )
return false ;
SendMovePacket ( FUNC_WAIT , 0 , 0 , 0 , 0 ) ;
if ( test_server )
sys_log ( 0 , " %s %p <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> ư<EFBFBD> <C6B0> <EFBFBD> ! %d %d " , GetName ( ) , this , x , y ) ;
if ( GetParty ( ) )
GetParty ( ) - > SendMessage ( this , PM_RETURN , x , y ) ;
return true ;
}
bool CHARACTER : : Follow ( LPCHARACTER pkChr , float fMinDistance )
{
if ( IsPC ( ) )
{
sys_err ( " CHARACTER::Follow : PC cannot use this method " , GetName ( ) ) ;
return false ;
}
// TRENT_MONSTER
if ( IS_SET ( m_pointsInstant . dwAIFlag , AIFLAG_NOMOVE ) )
{
if ( pkChr - > IsPC ( ) ) // <20> Ѿư<D1BE> <C6B0> <EFBFBD> <20> <> <EFBFBD> 밡 PC<50> <43> <20> <>
{
// If i'm in a party. I must obey party leader's AI.
if ( ! GetParty ( ) | | ! GetParty ( ) - > GetLeader ( ) | | GetParty ( ) - > GetLeader ( ) = = this )
{
if ( get_dword_time ( ) - m_pkMobInst - > m_dwLastAttackedTime > = 15000 ) // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ݹ<EFBFBD> <DDB9> <EFBFBD> <EFBFBD> <EFBFBD> 15<31> ʰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
{
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> 50<35> <30> <EFBFBD> <EFBFBD> <20> ̻<EFBFBD> <20> <> <EFBFBD> ̳<EFBFBD> <CCB3> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> ư<EFBFBD> <C6B0> <EFBFBD> .
if ( m_pkMobData - > m_table . wAttackRange < DISTANCE_APPROX ( pkChr - > GetX ( ) - GetX ( ) , pkChr - > GetY ( ) - GetY ( ) ) )
if ( Return ( ) )
return true ;
}
}
}
return false ;
}
// END_OF_TRENT_MONSTER
2022-03-12 11:39:41 +02:00
int x = pkChr - > GetX ( ) ;
int y = pkChr - > GetY ( ) ;
2022-03-05 12:44:06 +02:00
if ( pkChr - > IsPC ( ) ) // <20> Ѿư<D1BE> <C6B0> <EFBFBD> <20> <> <EFBFBD> 밡 PC<50> <43> <20> <>
{
// If i'm in a party. I must obey party leader's AI.
if ( ! GetParty ( ) | | ! GetParty ( ) - > GetLeader ( ) | | GetParty ( ) - > GetLeader ( ) = = this )
{
if ( get_dword_time ( ) - m_pkMobInst - > m_dwLastAttackedTime > = 15000 ) // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ݹ<EFBFBD> <DDB9> <EFBFBD> <EFBFBD> <EFBFBD> 15<31> ʰ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
{
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> 50<35> <30> <EFBFBD> <EFBFBD> <20> ̻<EFBFBD> <20> <> <EFBFBD> ̳<EFBFBD> <CCB3> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϰ<EFBFBD> <20> <> <EFBFBD> ư<EFBFBD> <C6B0> <EFBFBD> .
if ( 5000 < DISTANCE_APPROX ( m_pkMobInst - > m_posLastAttacked . x - GetX ( ) , m_pkMobInst - > m_posLastAttacked . y - GetY ( ) ) )
if ( Return ( ) )
return true ;
}
}
}
if ( IsGuardNPC ( ) )
{
if ( 5000 < DISTANCE_APPROX ( m_pkMobInst - > m_posLastAttacked . x - GetX ( ) , m_pkMobInst - > m_posLastAttacked . y - GetY ( ) ) )
if ( Return ( ) )
return true ;
}
if ( pkChr - > IsState ( pkChr - > m_stateMove ) & &
GetMobBattleType ( ) ! = BATTLE_TYPE_RANGE & &
GetMobBattleType ( ) ! = BATTLE_TYPE_MAGIC & &
false = = IsPet ( ) )
{
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̵<EFBFBD> <CCB5> <EFBFBD> <EFBFBD> ̸<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ̵<EFBFBD> <CCB5> <EFBFBD> <20> Ѵ <EFBFBD>
// <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ӵ<EFBFBD> <D3B5> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ÿ<EFBFBD> <C5B8> κ<EFBFBD> <CEBA> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ð<EFBFBD> <C3B0> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <>
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> ð<EFBFBD> <C3B0> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̵<EFBFBD> <CCB5> Ѵ ٰ<D1B4> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ͽ<EFBFBD> <20> ű<EFBFBD> <C5B1> <EFBFBD> <20> ̵<EFBFBD> <CCB5> Ѵ <EFBFBD> .
float rot = pkChr - > GetRotation ( ) ;
float rot_delta = GetDegreeDelta ( rot , GetDegreeFromPositionXY ( GetX ( ) , GetY ( ) , pkChr - > GetX ( ) , pkChr - > GetY ( ) ) ) ;
float yourSpeed = pkChr - > GetMoveSpeed ( ) ;
float mySpeed = GetMoveSpeed ( ) ;
float fDist = DISTANCE_SQRT ( x - GetX ( ) , y - GetY ( ) ) ;
float fFollowSpeed = mySpeed - yourSpeed * cos ( rot_delta * M_PI / 180 ) ;
if ( fFollowSpeed > = 0.1f )
{
float fMeetTime = fDist / fFollowSpeed ;
float fYourMoveEstimateX , fYourMoveEstimateY ;
if ( fMeetTime * yourSpeed < = 100000.0f )
{
GetDeltaByDegree ( pkChr - > GetRotation ( ) , fMeetTime * yourSpeed , & fYourMoveEstimateX , & fYourMoveEstimateY ) ;
2022-03-12 11:39:41 +02:00
x + = ( int ) fYourMoveEstimateX ;
y + = ( int ) fYourMoveEstimateY ;
2022-03-05 12:44:06 +02:00
float fDistNew = sqrt ( ( ( double ) x - GetX ( ) ) * ( x - GetX ( ) ) + ( ( double ) y - GetY ( ) ) * ( y - GetY ( ) ) ) ;
if ( fDist < fDistNew )
{
2022-03-12 11:39:41 +02:00
x = ( int ) ( GetX ( ) + ( x - GetX ( ) ) * fDist / fDistNew ) ;
y = ( int ) ( GetY ( ) + ( y - GetY ( ) ) * fDist / fDistNew ) ;
2022-03-05 12:44:06 +02:00
}
}
}
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ġ<EFBFBD> <C4A1> <20> ٶ<EFBFBD> <D9B6> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ѵ <EFBFBD> .
SetRotationToXY ( x , y ) ;
float fDist = DISTANCE_SQRT ( x - GetX ( ) , y - GetY ( ) ) ;
if ( fDist < = fMinDistance )
return false ;
float fx , fy ;
if ( IsChangeAttackPosition ( pkChr ) & & GetMobRank ( ) < MOB_RANK_BOSS )
{
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ֺ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̵<EFBFBD>
SetChangeAttackPositionTime ( ) ;
int retry = 16 ;
int dx , dy ;
int rot = ( int ) GetDegreeFromPositionXY ( x , y , GetX ( ) , GetY ( ) ) ;
while ( - - retry )
{
if ( fDist < 500.0f )
2022-11-27 14:36:04 +02:00
GetDeltaByDegree ( ( rot + Random : : get ( - 90 , 90 ) + Random : : get ( - 90 , 90 ) ) % 360 , fMinDistance , & fx , & fy ) ;
2022-03-05 12:44:06 +02:00
else
2022-11-27 14:36:04 +02:00
GetDeltaByDegree ( Random : : get ( 0 , 359 ) , fMinDistance , & fx , & fy ) ;
2022-03-05 12:44:06 +02:00
dx = x + ( int ) fx ;
dy = y + ( int ) fy ;
LPSECTREE tree = SECTREE_MANAGER : : instance ( ) . Get ( GetMapIndex ( ) , dx , dy ) ;
if ( NULL = = tree )
break ;
if ( 0 = = ( tree - > GetAttribute ( dx , dy ) & ( ATTR_BLOCK | ATTR_OBJECT ) ) )
break ;
}
//sys_log(0, "<22> <> ó <20> <> <EFBFBD> <EFBFBD> <20> ̵<EFBFBD> %s retry %d", GetName(), retry);
if ( ! Goto ( dx , dy ) )
return false ;
}
else
{
// <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
float fDistToGo = fDist - fMinDistance ;
GetDeltaByDegree ( GetRotation ( ) , fDistToGo , & fx , & fy ) ;
//sys_log(0, "<22> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̵<EFBFBD> %s", GetName());
if ( ! Goto ( GetX ( ) + ( int ) fx , GetY ( ) + ( int ) fy ) )
return false ;
}
SendMovePacket ( FUNC_WAIT , 0 , 0 , 0 , 0 ) ;
//MonsterLog("<22> Ѿư<D1BE> <C6B0> <EFBFBD> ; %s", pkChr->GetName());
return true ;
}
float CHARACTER : : GetDistanceFromSafeboxOpen ( ) const
{
return DISTANCE_APPROX ( GetX ( ) - m_posSafeboxOpen . x , GetY ( ) - m_posSafeboxOpen . y ) ;
}
void CHARACTER : : SetSafeboxOpenPosition ( )
{
m_posSafeboxOpen = GetXYZ ( ) ;
}
CSafebox * CHARACTER : : GetSafebox ( ) const
{
return m_pkSafebox ;
}
void CHARACTER : : ReqSafeboxLoad ( const char * pszPassword )
{
if ( ! * pszPassword | | strlen ( pszPassword ) > SAFEBOX_PASSWORD_MAX_LEN )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <â<> <C3A2> > <20> ߸<EFBFBD> <DFB8> <EFBFBD> <20> <> ȣ <EFBFBD> <C8A3> <20> Է<EFBFBD> <D4B7> ϼ̽<CFBC> <CCBD> ϴ<EFBFBD> . " ) ) ;
return ;
}
else if ( m_pkSafebox )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <â<> <C3A2> > â<> <C3A2> <EFBFBD> <EFBFBD> <20> ̹<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ֽ<EFBFBD> <D6BD> ϴ<EFBFBD> . " ) ) ;
return ;
}
int iPulse = thecore_pulse ( ) ;
if ( iPulse - GetSafeboxLoadTime ( ) < PASSES_PER_SEC ( 10 ) )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <â<> <C3A2> > â<> <C3A2> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> 10<31> <30> <20> ȿ<EFBFBD> <C8BF> <EFBFBD> <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
}
else if ( GetDistanceFromSafeboxOpen ( ) > 1000 )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <â<> <C3A2> > <20> Ÿ<EFBFBD> <C5B8> <EFBFBD> <20> ־ â<> <C3A2> <EFBFBD> <EFBFBD> <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) ) ;
return ;
}
else if ( m_bOpeningSafebox )
{
sys_log ( 0 , " Overlapped safebox load request from %s " , GetName ( ) ) ;
return ;
}
SetSafeboxLoadTime ( ) ;
m_bOpeningSafebox = true ;
TSafeboxLoadPacket p ;
p . dwID = GetDesc ( ) - > GetAccountTable ( ) . id ;
2022-03-05 19:59:39 +02:00
strncpy ( p . szLogin , GetDesc ( ) - > GetAccountTable ( ) . login , sizeof ( p . szLogin ) ) ;
strncpy ( p . szPassword , pszPassword , sizeof ( p . szPassword ) ) ;
2022-03-05 12:44:06 +02:00
db_clientdesc - > DBPacket ( HEADER_GD_SAFEBOX_LOAD , GetDesc ( ) - > GetHandle ( ) , & p , sizeof ( p ) ) ;
}
void CHARACTER : : LoadSafebox ( int iSize , DWORD dwGold , int iItemCount , TPlayerItem * pItems )
{
bool bLoaded = false ;
//PREVENT_TRADE_WINDOW
SetOpenSafebox ( true ) ;
//END_PREVENT_TRADE_WINDOW
if ( m_pkSafebox )
bLoaded = true ;
if ( ! m_pkSafebox )
m_pkSafebox = M2_NEW CSafebox ( this , iSize , dwGold ) ;
else
m_pkSafebox - > ChangeSize ( iSize ) ;
m_iSafeboxSize = iSize ;
TPacketCGSafeboxSize p ;
p . bHeader = HEADER_GC_SAFEBOX_SIZE ;
p . bSize = iSize ;
GetDesc ( ) - > Packet ( & p , sizeof ( TPacketCGSafeboxSize ) ) ;
if ( ! bLoaded )
{
for ( int i = 0 ; i < iItemCount ; + + i , + + pItems )
{
if ( ! m_pkSafebox - > IsValidPosition ( pItems - > pos ) )
continue ;
LPITEM item = ITEM_MANAGER : : instance ( ) . CreateItem ( pItems - > vnum , pItems - > count , pItems - > id ) ;
if ( ! item )
{
sys_err ( " cannot create item vnum %d id %u (name: %s) " , pItems - > vnum , pItems - > id , GetName ( ) ) ;
continue ;
}
item - > SetSkipSave ( true ) ;
item - > SetSockets ( pItems - > alSockets ) ;
item - > SetAttributes ( pItems - > aAttr ) ;
if ( ! m_pkSafebox - > Add ( pItems - > pos , item ) )
{
M2_DESTROY_ITEM ( item ) ;
}
else
item - > SetSkipSave ( false ) ;
}
}
}
void CHARACTER : : ChangeSafeboxSize ( BYTE bSize )
{
//if (!m_pkSafebox)
//return;
TPacketCGSafeboxSize p ;
p . bHeader = HEADER_GC_SAFEBOX_SIZE ;
p . bSize = bSize ;
GetDesc ( ) - > Packet ( & p , sizeof ( TPacketCGSafeboxSize ) ) ;
if ( m_pkSafebox )
m_pkSafebox - > ChangeSize ( bSize ) ;
m_iSafeboxSize = bSize ;
}
void CHARACTER : : CloseSafebox ( )
{
if ( ! m_pkSafebox )
return ;
//PREVENT_TRADE_WINDOW
SetOpenSafebox ( false ) ;
//END_PREVENT_TRADE_WINDOW
m_pkSafebox - > Save ( ) ;
M2_DELETE ( m_pkSafebox ) ;
m_pkSafebox = NULL ;
ChatPacket ( CHAT_TYPE_COMMAND , " CloseSafebox " ) ;
SetSafeboxLoadTime ( ) ;
m_bOpeningSafebox = false ;
Save ( ) ;
}
CSafebox * CHARACTER : : GetMall ( ) const
{
return m_pkMall ;
}
void CHARACTER : : LoadMall ( int iItemCount , TPlayerItem * pItems )
{
bool bLoaded = false ;
if ( m_pkMall )
bLoaded = true ;
if ( ! m_pkMall )
m_pkMall = M2_NEW CSafebox ( this , 3 * SAFEBOX_PAGE_SIZE , 0 ) ;
else
m_pkMall - > ChangeSize ( 3 * SAFEBOX_PAGE_SIZE ) ;
m_pkMall - > SetWindowMode ( MALL ) ;
TPacketCGSafeboxSize p ;
p . bHeader = HEADER_GC_MALL_OPEN ;
p . bSize = 3 * SAFEBOX_PAGE_SIZE ;
GetDesc ( ) - > Packet ( & p , sizeof ( TPacketCGSafeboxSize ) ) ;
if ( ! bLoaded )
{
for ( int i = 0 ; i < iItemCount ; + + i , + + pItems )
{
if ( ! m_pkMall - > IsValidPosition ( pItems - > pos ) )
continue ;
LPITEM item = ITEM_MANAGER : : instance ( ) . CreateItem ( pItems - > vnum , pItems - > count , pItems - > id ) ;
if ( ! item )
{
sys_err ( " cannot create item vnum %d id %u (name: %s) " , pItems - > vnum , pItems - > id , GetName ( ) ) ;
continue ;
}
item - > SetSkipSave ( true ) ;
item - > SetSockets ( pItems - > alSockets ) ;
item - > SetAttributes ( pItems - > aAttr ) ;
if ( ! m_pkMall - > Add ( pItems - > pos , item ) )
M2_DESTROY_ITEM ( item ) ;
else
item - > SetSkipSave ( false ) ;
}
}
}
void CHARACTER : : CloseMall ( )
{
if ( ! m_pkMall )
return ;
m_pkMall - > Save ( ) ;
M2_DELETE ( m_pkMall ) ;
m_pkMall = NULL ;
ChatPacket ( CHAT_TYPE_COMMAND , " CloseMall " ) ;
}
bool CHARACTER : : BuildUpdatePartyPacket ( TPacketGCPartyUpdate & out )
{
if ( ! GetParty ( ) )
return false ;
memset ( & out , 0 , sizeof ( out ) ) ;
out . header = HEADER_GC_PARTY_UPDATE ;
out . pid = GetPlayerID ( ) ;
2022-11-27 22:18:08 +02:00
out . percent_hp = std : : clamp ( GetHP ( ) * 100 / GetMaxHP ( ) , 0 , 100 ) ;
2022-03-05 12:44:06 +02:00
out . role = GetParty ( ) - > GetRole ( GetPlayerID ( ) ) ;
sys_log ( 1 , " PARTY %s role is %d " , GetName ( ) , out . role ) ;
LPCHARACTER l = GetParty ( ) - > GetLeaderCharacter ( ) ;
if ( l & & DISTANCE_APPROX ( GetX ( ) - l - > GetX ( ) , GetY ( ) - l - > GetY ( ) ) < PARTY_DEFAULT_RANGE )
{
if ( g_iUseLocale )
out . affects [ 0 ] = GetParty ( ) - > GetPartyBonusExpPercent ( ) ;
else
out . affects [ 0 ] = GetParty ( ) - > GetExpBonusPercent ( ) ;
out . affects [ 1 ] = GetPoint ( POINT_PARTY_ATTACKER_BONUS ) ;
out . affects [ 2 ] = GetPoint ( POINT_PARTY_TANKER_BONUS ) ;
out . affects [ 3 ] = GetPoint ( POINT_PARTY_BUFFER_BONUS ) ;
out . affects [ 4 ] = GetPoint ( POINT_PARTY_SKILL_MASTER_BONUS ) ;
out . affects [ 5 ] = GetPoint ( POINT_PARTY_HASTE_BONUS ) ;
out . affects [ 6 ] = GetPoint ( POINT_PARTY_DEFENDER_BONUS ) ;
}
return true ;
}
int CHARACTER : : GetLeadershipSkillLevel ( ) const
{
return GetSkillLevel ( SKILL_LEADERSHIP ) ;
}
void CHARACTER : : QuerySafeboxSize ( )
{
if ( m_iSafeboxSize = = - 1 )
{
DBManager : : instance ( ) . ReturnQuery ( QID_SAFEBOX_SIZE ,
GetPlayerID ( ) ,
NULL ,
" SELECT size FROM safebox%s WHERE account_id = %u " ,
get_table_postfix ( ) ,
GetDesc ( ) - > GetAccountTable ( ) . id ) ;
}
}
void CHARACTER : : SetSafeboxSize ( int iSize )
{
sys_log ( 1 , " SetSafeboxSize: %s %d " , GetName ( ) , iSize ) ;
m_iSafeboxSize = iSize ;
DBManager : : instance ( ) . Query ( " UPDATE safebox%s SET size = %d WHERE account_id = %u " , get_table_postfix ( ) , iSize / SAFEBOX_PAGE_SIZE , GetDesc ( ) - > GetAccountTable ( ) . id ) ;
}
int CHARACTER : : GetSafeboxSize ( ) const
{
return m_iSafeboxSize ;
}
void CHARACTER : : SetNowWalking ( bool bWalkFlag )
{
//if (m_bNowWalking != bWalkFlag || IsNPC())
if ( m_bNowWalking ! = bWalkFlag )
{
if ( bWalkFlag )
{
m_bNowWalking = true ;
m_dwWalkStartTime = get_dword_time ( ) ;
}
else
{
m_bNowWalking = false ;
}
//if (m_bNowWalking)
{
TPacketGCWalkMode p ;
p . vid = GetVID ( ) ;
p . header = HEADER_GC_WALK_MODE ;
p . mode = m_bNowWalking ? WALKMODE_WALK : WALKMODE_RUN ;
PacketView ( & p , sizeof ( p ) ) ;
}
if ( IsNPC ( ) )
{
if ( m_bNowWalking )
MonsterLog ( " <EFBFBD> ȴ´ <EFBFBD> " ) ;
else
MonsterLog ( " <EFBFBD> ڴ<EFBFBD> " ) ;
}
//sys_log(0, "%s is now %s", GetName(), m_bNowWalking?"walking.":"running.");
}
}
void CHARACTER : : StartStaminaConsume ( )
{
if ( m_bStaminaConsume )
return ;
PointChange ( POINT_STAMINA , 0 ) ;
m_bStaminaConsume = true ;
//ChatPacket(CHAT_TYPE_COMMAND, "StartStaminaConsume %d %d", STAMINA_PER_STEP * passes_per_sec, GetStamina());
if ( IsStaminaHalfConsume ( ) )
ChatPacket ( CHAT_TYPE_COMMAND , " StartStaminaConsume %d %d " , STAMINA_PER_STEP * passes_per_sec / 2 , GetStamina ( ) ) ;
else
ChatPacket ( CHAT_TYPE_COMMAND , " StartStaminaConsume %d %d " , STAMINA_PER_STEP * passes_per_sec , GetStamina ( ) ) ;
}
void CHARACTER : : StopStaminaConsume ( )
{
if ( ! m_bStaminaConsume )
return ;
PointChange ( POINT_STAMINA , 0 ) ;
m_bStaminaConsume = false ;
ChatPacket ( CHAT_TYPE_COMMAND , " StopStaminaConsume %d " , GetStamina ( ) ) ;
}
bool CHARACTER : : IsStaminaConsume ( ) const
{
return m_bStaminaConsume ;
}
bool CHARACTER : : IsStaminaHalfConsume ( ) const
{
return IsEquipUniqueItem ( UNIQUE_ITEM_HALF_STAMINA ) ;
}
void CHARACTER : : ResetStopTime ( )
{
m_dwStopTime = get_dword_time ( ) ;
}
DWORD CHARACTER : : GetStopTime ( ) const
{
return m_dwStopTime ;
}
void CHARACTER : : ResetPoint ( int iLv )
{
BYTE bJob = GetJob ( ) ;
PointChange ( POINT_LEVEL , iLv - GetLevel ( ) ) ;
SetRealPoint ( POINT_ST , JobInitialPoints [ bJob ] . st ) ;
SetPoint ( POINT_ST , GetRealPoint ( POINT_ST ) ) ;
SetRealPoint ( POINT_HT , JobInitialPoints [ bJob ] . ht ) ;
SetPoint ( POINT_HT , GetRealPoint ( POINT_HT ) ) ;
SetRealPoint ( POINT_DX , JobInitialPoints [ bJob ] . dx ) ;
SetPoint ( POINT_DX , GetRealPoint ( POINT_DX ) ) ;
SetRealPoint ( POINT_IQ , JobInitialPoints [ bJob ] . iq ) ;
SetPoint ( POINT_IQ , GetRealPoint ( POINT_IQ ) ) ;
2022-11-27 14:36:04 +02:00
SetRandomHP ( ( iLv - 1 ) * Random : : get ( JobInitialPoints [ GetJob ( ) ] . hp_per_lv_begin , JobInitialPoints [ GetJob ( ) ] . hp_per_lv_end ) ) ;
SetRandomSP ( ( iLv - 1 ) * Random : : get ( JobInitialPoints [ GetJob ( ) ] . sp_per_lv_begin , JobInitialPoints [ GetJob ( ) ] . sp_per_lv_end ) ) ;
2022-03-05 12:44:06 +02:00
2022-11-27 22:18:08 +02:00
//PointChange(POINT_STAT, ((std::clamp(iLv, 1, 99) - 1) * 3) + GetPoint(POINT_LEVEL_STEP) - GetPoint(POINT_STAT));
PointChange ( POINT_STAT , ( ( std : : clamp ( iLv , 1 , 90 ) - 1 ) * 3 ) + GetPoint ( POINT_LEVEL_STEP ) - GetPoint ( POINT_STAT ) ) ;
2022-03-05 12:44:06 +02:00
ComputePoints ( ) ;
// ȸ<> <C8B8>
PointChange ( POINT_HP , GetMaxHP ( ) - GetHP ( ) ) ;
PointChange ( POINT_SP , GetMaxSP ( ) - GetSP ( ) ) ;
PointsPacket ( ) ;
LogManager : : instance ( ) . CharLog ( this , 0 , " RESET_POINT " , " " ) ;
}
bool CHARACTER : : IsChangeAttackPosition ( LPCHARACTER target ) const
{
if ( ! IsNPC ( ) )
return true ;
DWORD dwChangeTime = AI_CHANGE_ATTACK_POISITION_TIME_NEAR ;
if ( DISTANCE_APPROX ( GetX ( ) - target - > GetX ( ) , GetY ( ) - target - > GetY ( ) ) >
AI_CHANGE_ATTACK_POISITION_DISTANCE + GetMobAttackRange ( ) )
dwChangeTime = AI_CHANGE_ATTACK_POISITION_TIME_FAR ;
return get_dword_time ( ) - m_dwLastChangeAttackPositionTime > dwChangeTime ;
}
void CHARACTER : : GiveRandomSkillBook ( )
{
LPITEM item = AutoGiveItem ( 50300 ) ;
if ( NULL ! = item )
{
BYTE bJob = 0 ;
2022-11-27 14:36:04 +02:00
if ( ! Random : : get < bool > ( ) )
2022-03-05 12:44:06 +02:00
bJob = GetJob ( ) + 1 ;
DWORD dwSkillVnum = 0 ;
do
{
2022-11-27 14:36:04 +02:00
dwSkillVnum = Random : : get ( 1 , 111 ) ;
2022-03-05 12:44:06 +02:00
const CSkillProto * pkSk = CSkillManager : : instance ( ) . Get ( dwSkillVnum ) ;
if ( NULL = = pkSk )
continue ;
if ( bJob & & bJob ! = pkSk - > dwType )
continue ;
break ;
} while ( true ) ;
item - > SetSocket ( 0 , dwSkillVnum ) ;
}
}
void CHARACTER : : ReviveInvisible ( int iDur )
{
AddAffect ( AFFECT_REVIVE_INVISIBLE , POINT_NONE , 0 , AFF_REVIVE_INVISIBLE , iDur , 0 , true ) ;
}
void CHARACTER : : ToggleMonsterLog ( )
{
m_bMonsterLog = ! m_bMonsterLog ;
if ( m_bMonsterLog )
{
CHARACTER_MANAGER : : instance ( ) . RegisterForMonsterLog ( this ) ;
}
else
{
CHARACTER_MANAGER : : instance ( ) . UnregisterForMonsterLog ( this ) ;
}
}
void CHARACTER : : SetGuild ( CGuild * pGuild )
{
if ( m_pGuild ! = pGuild )
{
m_pGuild = pGuild ;
UpdatePacket ( ) ;
}
}
void CHARACTER : : SendGreetMessage ( )
{
typeof ( DBManager : : instance ( ) . GetGreetMessage ( ) ) v = DBManager : : instance ( ) . GetGreetMessage ( ) ;
for ( itertype ( v ) it = v . begin ( ) ; it ! = v . end ( ) ; + + it )
{
ChatPacket ( CHAT_TYPE_NOTICE , it - > c_str ( ) ) ;
}
}
void CHARACTER : : BeginStateEmpty ( )
{
MonsterLog ( " ! " ) ;
}
void CHARACTER : : EffectPacket ( int enumEffectType )
{
TPacketGCSpecialEffect p ;
p . header = HEADER_GC_SEPCIAL_EFFECT ;
p . type = enumEffectType ;
p . vid = GetVID ( ) ;
PacketAround ( & p , sizeof ( TPacketGCSpecialEffect ) ) ;
}
void CHARACTER : : SpecificEffectPacket ( const char filename [ MAX_EFFECT_FILE_NAME ] )
{
TPacketGCSpecificEffect p ;
p . header = HEADER_GC_SPECIFIC_EFFECT ;
p . vid = GetVID ( ) ;
memcpy ( p . effect_file , filename , MAX_EFFECT_FILE_NAME ) ;
PacketAround ( & p , sizeof ( TPacketGCSpecificEffect ) ) ;
}
void CHARACTER : : MonsterChat ( BYTE bMonsterChatType )
{
if ( IsPC ( ) )
return ;
char sbuf [ 256 + 1 ] ;
if ( IsMonster ( ) )
{
2022-11-27 14:36:04 +02:00
if ( Random : : get ( 0 , 60 ) )
2022-03-05 12:44:06 +02:00
return ;
snprintf ( sbuf , sizeof ( sbuf ) ,
" (locale.monster_chat[%i] and locale.monster_chat[%i][%d] or '') " ,
2022-11-27 14:36:04 +02:00
GetRaceNum ( ) , GetRaceNum ( ) , bMonsterChatType * 3 + Random : : get ( 1 , 3 ) ) ;
2022-03-05 12:44:06 +02:00
}
else
{
if ( bMonsterChatType ! = MONSTER_CHAT_WAIT )
return ;
if ( IsGuardNPC ( ) )
{
2022-11-27 14:36:04 +02:00
if ( Random : : get ( 0 , 6 ) )
2022-03-05 12:44:06 +02:00
return ;
}
else
{
2022-11-27 14:36:04 +02:00
if ( Random : : get ( 0 , 30 ) )
2022-03-05 12:44:06 +02:00
return ;
}
snprintf ( sbuf , sizeof ( sbuf ) , " (locale.monster_chat[%i] and locale.monster_chat[%i][number(1, table.getn(locale.monster_chat[%i]))] or '') " , GetRaceNum ( ) , GetRaceNum ( ) , GetRaceNum ( ) ) ;
}
std : : string text = quest : : ScriptToString ( sbuf ) ;
if ( text . empty ( ) )
return ;
struct packet_chat pack_chat ;
pack_chat . header = HEADER_GC_CHAT ;
pack_chat . size = sizeof ( struct packet_chat ) + text . size ( ) + 1 ;
pack_chat . type = CHAT_TYPE_TALKING ;
pack_chat . id = GetVID ( ) ;
pack_chat . bEmpire = 0 ;
TEMP_BUFFER buf ;
buf . write ( & pack_chat , sizeof ( struct packet_chat ) ) ;
buf . write ( text . c_str ( ) , text . size ( ) + 1 ) ;
PacketAround ( buf . read_peek ( ) , buf . size ( ) ) ;
}
void CHARACTER : : SetQuestNPCID ( DWORD vid )
{
m_dwQuestNPCVID = vid ;
}
LPCHARACTER CHARACTER : : GetQuestNPC ( ) const
{
return CHARACTER_MANAGER : : instance ( ) . Find ( m_dwQuestNPCVID ) ;
}
void CHARACTER : : SetQuestItemPtr ( LPITEM item )
{
m_pQuestItem = item ;
}
void CHARACTER : : ClearQuestItemPtr ( )
{
m_pQuestItem = NULL ;
}
LPITEM CHARACTER : : GetQuestItemPtr ( ) const
{
return m_pQuestItem ;
}
LPDUNGEON CHARACTER : : GetDungeonForce ( ) const
{
if ( m_lWarpMapIndex > 10000 )
return CDungeonManager : : instance ( ) . FindByMapIndex ( m_lWarpMapIndex ) ;
return m_pkDungeon ;
}
void CHARACTER : : SetBlockMode ( BYTE bFlag )
{
m_pointsInstant . bBlockMode = bFlag ;
ChatPacket ( CHAT_TYPE_COMMAND , " setblockmode %d " , m_pointsInstant . bBlockMode ) ;
SetQuestFlag ( " game_option.block_exchange " , bFlag & BLOCK_EXCHANGE ? 1 : 0 ) ;
SetQuestFlag ( " game_option.block_party_invite " , bFlag & BLOCK_PARTY_INVITE ? 1 : 0 ) ;
SetQuestFlag ( " game_option.block_guild_invite " , bFlag & BLOCK_GUILD_INVITE ? 1 : 0 ) ;
SetQuestFlag ( " game_option.block_whisper " , bFlag & BLOCK_WHISPER ? 1 : 0 ) ;
SetQuestFlag ( " game_option.block_messenger_invite " , bFlag & BLOCK_MESSENGER_INVITE ? 1 : 0 ) ;
SetQuestFlag ( " game_option.block_party_request " , bFlag & BLOCK_PARTY_REQUEST ? 1 : 0 ) ;
}
void CHARACTER : : SetBlockModeForce ( BYTE bFlag )
{
m_pointsInstant . bBlockMode = bFlag ;
ChatPacket ( CHAT_TYPE_COMMAND , " setblockmode %d " , m_pointsInstant . bBlockMode ) ;
}
bool CHARACTER : : IsGuardNPC ( ) const
{
return IsNPC ( ) & & ( GetRaceNum ( ) = = 11000 | | GetRaceNum ( ) = = 11002 | | GetRaceNum ( ) = = 11004 ) ;
}
int CHARACTER : : GetPolymorphPower ( ) const
{
if ( test_server )
{
int value = quest : : CQuestManager : : instance ( ) . GetEventFlag ( " poly " ) ;
if ( value )
return value ;
}
2022-11-27 22:18:08 +02:00
return aiPolymorphPowerByLevel [ std : : clamp ( GetSkillLevel ( SKILL_POLYMORPH ) , 0 , 40 ) ] ;
2022-03-05 12:44:06 +02:00
}
void CHARACTER : : SetPolymorph ( DWORD dwRaceNum , bool bMaintainStat )
{
if ( dwRaceNum < JOB_MAX_NUM )
{
dwRaceNum = 0 ;
bMaintainStat = false ;
}
if ( m_dwPolymorphRace = = dwRaceNum )
return ;
m_bPolyMaintainStat = bMaintainStat ;
m_dwPolymorphRace = dwRaceNum ;
sys_log ( 0 , " POLYMORPH: %s race %u " , GetName ( ) , dwRaceNum ) ;
if ( dwRaceNum ! = 0 )
StopRiding ( ) ;
SET_BIT ( m_bAddChrState , ADD_CHARACTER_STATE_SPAWN ) ;
m_afAffectFlag . Set ( AFF_SPAWN ) ;
ViewReencode ( ) ;
REMOVE_BIT ( m_bAddChrState , ADD_CHARACTER_STATE_SPAWN ) ;
if ( ! bMaintainStat )
{
PointChange ( POINT_ST , 0 ) ;
PointChange ( POINT_DX , 0 ) ;
PointChange ( POINT_IQ , 0 ) ;
PointChange ( POINT_HT , 0 ) ;
}
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ¿<EFBFBD> <C2BF> <EFBFBD> <20> ״<EFBFBD> <20> <> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ǯ<> <C7AE> <EFBFBD> <EFBFBD> <20> Ǵµ<C7B4>
// <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> ķ<EFBFBD> valid combo interval<61> <6C> <20> ٸ<EFBFBD> <D9B8> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
// Combo <20> <> <20> Ǵ<EFBFBD> Hacker<65> <72> <20> ν <EFBFBD> <CEBD> ϴ<EFBFBD> <20> <> <EFBFBD> 찡 <20> ִ<EFBFBD> .
// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> Ǯ<> ų<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ϰ<EFBFBD> <20> Ǹ<EFBFBD> ,
// valid combo interval<61> <6C> reset<65> Ѵ <EFBFBD> .
SetValidComboInterval ( 0 ) ;
SetComboSequence ( 0 ) ;
ComputeBattlePoints ( ) ;
}
int CHARACTER : : GetQuestFlag ( const std : : string & flag ) const
{
quest : : CQuestManager & q = quest : : CQuestManager : : instance ( ) ;
quest : : PC * pPC = q . GetPC ( GetPlayerID ( ) ) ;
return pPC - > GetFlag ( flag ) ;
}
void CHARACTER : : SetQuestFlag ( const std : : string & flag , int value )
{
quest : : CQuestManager & q = quest : : CQuestManager : : instance ( ) ;
quest : : PC * pPC = q . GetPC ( GetPlayerID ( ) ) ;
pPC - > SetFlag ( flag , value ) ;
}
void CHARACTER : : DetermineDropMetinStone ( )
{
const int METIN_STONE_NUM = 14 ;
static DWORD c_adwMetin [ METIN_STONE_NUM ] =
{
28030 ,
28031 ,
28032 ,
28033 ,
28034 ,
28035 ,
28036 ,
28037 ,
28038 ,
28039 ,
28040 ,
28041 ,
28042 ,
28043 ,
} ;
DWORD stone_num = GetRaceNum ( ) ;
int idx = std : : lower_bound ( aStoneDrop , aStoneDrop + STONE_INFO_MAX_NUM , stone_num ) - aStoneDrop ;
if ( idx > = STONE_INFO_MAX_NUM | | aStoneDrop [ idx ] . dwMobVnum ! = stone_num )
{
m_dwDropMetinStone = 0 ;
}
else
{
const SStoneDropInfo & info = aStoneDrop [ idx ] ;
m_bDropMetinStonePct = info . iDropPct ;
{
2022-11-27 14:36:04 +02:00
m_dwDropMetinStone = c_adwMetin [ Random : : get ( 0 , METIN_STONE_NUM - 1 ) ] ;
int iGradePct = Random : : get ( 1 , 100 ) ;
2022-03-05 12:44:06 +02:00
for ( int iStoneLevel = 0 ; iStoneLevel < STONE_LEVEL_MAX_NUM ; iStoneLevel + + )
{
int iLevelGradePortion = info . iLevelPct [ iStoneLevel ] ;
if ( iGradePct < = iLevelGradePortion )
{
break ;
}
else
{
iGradePct - = iLevelGradePortion ;
m_dwDropMetinStone + = 100 ; // <20> <> +a -> +(a+1)<29> <> <20> ɶ<EFBFBD> <C9B6> <EFBFBD> <EFBFBD> <EFBFBD> 100<30> <30> <20> <> <EFBFBD> <EFBFBD>
}
}
}
}
}
void CHARACTER : : SendEquipment ( LPCHARACTER ch )
{
TPacketViewEquip p ;
p . header = HEADER_GC_VIEW_EQUIP ;
p . vid = GetVID ( ) ;
for ( int i = 0 ; i < WEAR_MAX_NUM ; i + + )
{
LPITEM item = GetWear ( i ) ;
if ( item )
{
p . equips [ i ] . vnum = item - > GetVnum ( ) ;
p . equips [ i ] . count = item - > GetCount ( ) ;
2022-03-06 17:36:43 +02:00
memcpy ( p . equips [ i ] . alSockets , item - > GetSockets ( ) , sizeof ( p . equips [ i ] . alSockets ) ) ;
memcpy ( p . equips [ i ] . aAttr , item - > GetAttributes ( ) , sizeof ( p . equips [ i ] . aAttr ) ) ;
2022-03-05 12:44:06 +02:00
}
else
{
p . equips [ i ] . vnum = 0 ;
}
}
ch - > GetDesc ( ) - > Packet ( & p , sizeof ( p ) ) ;
}
bool CHARACTER : : CanSummon ( int iLeaderShip )
{
return ( iLeaderShip > = 20 | | iLeaderShip > = 12 & & m_dwLastDeadTime + 180 > get_dword_time ( ) ) ;
}
void CHARACTER : : MountVnum ( DWORD vnum )
{
if ( m_dwMountVnum = = vnum )
return ;
m_dwMountVnum = vnum ;
m_dwMountTime = get_dword_time ( ) ;
if ( m_bIsObserver )
return ;
//NOTE : Mount<6E> Ѵ ٰ<D1B4> <20> ؼ<EFBFBD> Client Side<64> <65> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ʴ´ <CAB4> .
//<2F> <EFBFBD> <D7B8> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> Side<64> <65> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ġ <20> ̵<EFBFBD> <CCB5> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ʴ´ <CAB4> . <20> ֳ<EFBFBD> <D6B3> ϸ<EFBFBD> Client Side<64> <65> <EFBFBD> <EFBFBD> Coliision Adjust<73> <74> <20> Ҽ<EFBFBD> <20> ִµ<D6B4>
//<2F> <> ü<EFBFBD> <C3BC> <20> Ҹ<EFBFBD> <D2B8> <EFBFBD> <EFBFBD> ״ٰ<D7B4> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ġ<EFBFBD> <C4A1> <20> ̵<EFBFBD> <CCB5> <EFBFBD> Ű<EFBFBD> <C5B0> <20> ̶<EFBFBD> collision check<63> <6B> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ƿ<EFBFBD> <20> <> <EFBFBD> 濡 <20> <> <EFBFBD> ų<EFBFBD> <20> հ <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> Ѵ <EFBFBD> .
m_posDest . x = m_posStart . x = GetX ( ) ;
m_posDest . y = m_posStart . y = GetY ( ) ;
//EncodeRemovePacket(this);
EncodeInsertPacket ( this ) ;
ENTITY_MAP : : iterator it = m_map_view . begin ( ) ;
while ( it ! = m_map_view . end ( ) )
{
LPENTITY entity = ( it + + ) - > first ;
//Mount<6E> Ѵ ٰ<D1B4> <20> ؼ<EFBFBD> Client Side<64> <65> <20> <> ü<EFBFBD> <C3BC> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ʴ´ <CAB4> .
//EncodeRemovePacket(entity);
//if (!m_bIsObserver)
EncodeInsertPacket ( entity ) ;
//if (!entity->IsObserverMode())
// entity->EncodeInsertPacket(this);
}
SetValidComboInterval ( 0 ) ;
SetComboSequence ( 0 ) ;
ComputePoints ( ) ;
}
namespace {
class FuncCheckWarp
{
public :
FuncCheckWarp ( LPCHARACTER pkWarp )
{
m_lTargetY = 0 ;
m_lTargetX = 0 ;
m_lX = pkWarp - > GetX ( ) ;
m_lY = pkWarp - > GetY ( ) ;
m_bInvalid = false ;
m_bEmpire = pkWarp - > GetEmpire ( ) ;
char szTmp [ 64 ] ;
2022-03-12 11:39:41 +02:00
if ( 3 ! = sscanf ( pkWarp - > GetName ( ) , " %s %d %d " , szTmp , & m_lTargetX , & m_lTargetY ) )
2022-03-05 12:44:06 +02:00
{
2022-11-27 14:36:04 +02:00
if ( Random : : get ( 1 , 100 ) < 5 )
2022-03-05 12:44:06 +02:00
sys_err ( " Warp NPC name wrong : vnum(%d) name(%s) " , pkWarp - > GetRaceNum ( ) , pkWarp - > GetName ( ) ) ;
m_bInvalid = true ;
return ;
}
m_lTargetX * = 100 ;
m_lTargetY * = 100 ;
m_bUseWarp = true ;
if ( pkWarp - > IsGoto ( ) )
{
LPSECTREE_MAP pkSectreeMap = SECTREE_MANAGER : : instance ( ) . GetMap ( pkWarp - > GetMapIndex ( ) ) ;
m_lTargetX + = pkSectreeMap - > m_setting . iBaseX ;
m_lTargetY + = pkSectreeMap - > m_setting . iBaseY ;
m_bUseWarp = false ;
}
}
bool Valid ( )
{
return ! m_bInvalid ;
}
void operator ( ) ( LPENTITY ent )
{
if ( ! Valid ( ) )
return ;
if ( ! ent - > IsType ( ENTITY_CHARACTER ) )
return ;
LPCHARACTER pkChr = ( LPCHARACTER ) ent ;
if ( ! pkChr - > IsPC ( ) )
return ;
int iDist = DISTANCE_APPROX ( pkChr - > GetX ( ) - m_lX , pkChr - > GetY ( ) - m_lY ) ;
if ( iDist > 300 )
return ;
if ( m_bEmpire & & pkChr - > GetEmpire ( ) & & m_bEmpire ! = pkChr - > GetEmpire ( ) )
return ;
if ( pkChr - > IsHack ( ) )
return ;
if ( ! pkChr - > CanHandleItem ( false , true ) )
return ;
if ( m_bUseWarp )
pkChr - > WarpSet ( m_lTargetX , m_lTargetY ) ;
else
{
pkChr - > Show ( pkChr - > GetMapIndex ( ) , m_lTargetX , m_lTargetY ) ;
pkChr - > Stop ( ) ;
}
}
bool m_bInvalid ;
bool m_bUseWarp ;
2022-03-12 11:39:41 +02:00
int m_lX ;
int m_lY ;
int m_lTargetX ;
int m_lTargetY ;
2022-03-05 12:44:06 +02:00
BYTE m_bEmpire ;
} ;
}
EVENTFUNC ( warp_npc_event )
{
char_event_info * info = dynamic_cast < char_event_info * > ( event - > info ) ;
if ( info = = NULL )
{
sys_err ( " warp_npc_event> <Factor> Null pointer " ) ;
return 0 ;
}
LPCHARACTER ch = info - > ch ;
if ( ch = = NULL ) { // <Factor>
return 0 ;
}
if ( ! ch - > GetSectree ( ) )
{
ch - > m_pkWarpNPCEvent = NULL ;
return 0 ;
}
FuncCheckWarp f ( ch ) ;
if ( f . Valid ( ) )
ch - > GetSectree ( ) - > ForEachAround ( f ) ;
return passes_per_sec / 2 ;
}
void CHARACTER : : StartWarpNPCEvent ( )
{
if ( m_pkWarpNPCEvent )
return ;
if ( ! IsWarp ( ) & & ! IsGoto ( ) )
return ;
char_event_info * info = AllocEventInfo < char_event_info > ( ) ;
info - > ch = this ;
m_pkWarpNPCEvent = event_create ( warp_npc_event , info , passes_per_sec / 2 ) ;
}
void CHARACTER : : SyncPacket ( )
{
TEMP_BUFFER buf ;
TPacketCGSyncPositionElement elem ;
elem . dwVID = GetVID ( ) ;
elem . lX = GetX ( ) ;
elem . lY = GetY ( ) ;
TPacketGCSyncPosition pack ;
pack . bHeader = HEADER_GC_SYNC_POSITION ;
pack . wSize = sizeof ( TPacketGCSyncPosition ) + sizeof ( elem ) ;
buf . write ( & pack , sizeof ( pack ) ) ;
buf . write ( & elem , sizeof ( elem ) ) ;
PacketAround ( buf . read_peek ( ) , buf . size ( ) ) ;
}
LPCHARACTER CHARACTER : : GetMarryPartner ( ) const
{
return m_pkChrMarried ;
}
void CHARACTER : : SetMarryPartner ( LPCHARACTER ch )
{
m_pkChrMarried = ch ;
}
int CHARACTER : : GetMarriageBonus ( DWORD dwItemVnum , bool bSum )
{
if ( IsNPC ( ) )
return 0 ;
marriage : : TMarriage * pMarriage = marriage : : CManager : : instance ( ) . Get ( GetPlayerID ( ) ) ;
if ( ! pMarriage )
return 0 ;
return pMarriage - > GetBonus ( dwItemVnum , bSum , this ) ;
}
void CHARACTER : : ConfirmWithMsg ( const char * szMsg , int iTimeout , DWORD dwRequestPID )
{
if ( ! IsPC ( ) )
return ;
TPacketGCQuestConfirm p ;
p . header = HEADER_GC_QUEST_CONFIRM ;
p . requestPID = dwRequestPID ;
p . timeout = iTimeout ;
2022-03-05 19:59:39 +02:00
strncpy ( p . msg , szMsg , sizeof ( p . msg ) ) ;
2022-03-05 12:44:06 +02:00
GetDesc ( ) - > Packet ( & p , sizeof ( p ) ) ;
}
int CHARACTER : : GetPremiumRemainSeconds ( BYTE bType ) const
{
if ( bType > = PREMIUM_MAX_NUM )
return 0 ;
return m_aiPremiumTimes [ bType ] - get_global_time ( ) ;
}
bool CHARACTER : : WarpToPID ( DWORD dwPID )
{
LPCHARACTER victim ;
if ( ( victim = ( CHARACTER_MANAGER : : instance ( ) . FindByPID ( dwPID ) ) ) )
{
int mapIdx = victim - > GetMapIndex ( ) ;
if ( IS_SUMMONABLE_ZONE ( mapIdx ) )
{
if ( CAN_ENTER_ZONE ( this , mapIdx ) )
{
WarpSet ( victim - > GetX ( ) , victim - > GetY ( ) ) ;
}
else
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ." ) ) ;
return false ;
}
}
else
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ." ) ) ;
return false ;
}
}
else
{
// <20> ٸ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> α <EFBFBD> <CEB1> ε<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> -> <20> <EFBFBD> <DEBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> ǥ<EFBFBD> <C7A5> <20> ƿ<DEBE> <C6BF> <EFBFBD>
// 1. A.pid, B.pid <20> <> <20> Ѹ<EFBFBD>
// 2. B.pid<69> <64> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> Ѹ<EFBFBD> <D1B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> A.pid, <20> <> ǥ <20> <> <20> <> <EFBFBD> <EFBFBD>
// 3. <20> <> <EFBFBD> <EFBFBD>
CCI * pcci = P2P_MANAGER : : instance ( ) . FindByPID ( dwPID ) ;
if ( ! pcci )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ¶<EFBFBD> <C2B6> <EFBFBD> <20> <> <EFBFBD> °<EFBFBD> <20> ƴմϴ<D5B4> ." ) ) ;
return false ;
}
if ( pcci - > bChannel ! = g_bChannel )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> %d ä<> ο <EFBFBD> <20> ֽ<EFBFBD> <D6BD> ϴ<EFBFBD> . (<28> <> <EFBFBD> <EFBFBD> ä<> <C3A4> %d)" ) , pcci - > bChannel , g_bChannel ) ;
return false ;
}
else if ( false = = IS_SUMMONABLE_ZONE ( pcci - > lMapIndex ) )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ." ) ) ;
return false ;
}
else
{
if ( ! CAN_ENTER_ZONE ( this , pcci - > lMapIndex ) )
{
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ִ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ." ) ) ;
return false ;
}
TPacketGGFindPosition p ;
p . header = HEADER_GG_FIND_POSITION ;
p . dwFromPID = GetPlayerID ( ) ;
p . dwTargetPID = dwPID ;
pcci - > pkDesc - > Packet ( & p , sizeof ( TPacketGGFindPosition ) ) ;
if ( test_server )
ChatPacket ( CHAT_TYPE_PARTY , " sent find position packet for teleport " ) ;
}
}
return true ;
}
// ADD_REFINE_BUILDING
CGuild * CHARACTER : : GetRefineGuild ( ) const
{
LPCHARACTER chRefineNPC = CHARACTER_MANAGER : : instance ( ) . Find ( m_dwRefineNPCVID ) ;
return ( chRefineNPC ? chRefineNPC - > GetGuild ( ) : NULL ) ;
}
bool CHARACTER : : IsRefineThroughGuild ( ) const
{
return GetRefineGuild ( ) ! = NULL ;
}
int CHARACTER : : ComputeRefineFee ( int iCost , int iMultiply ) const
{
CGuild * pGuild = GetRefineGuild ( ) ;
if ( pGuild )
{
if ( pGuild = = GetGuild ( ) )
return iCost * iMultiply * 9 / 10 ;
// <20> ٸ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> õ<EFBFBD> <C3B5> ϴ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <20> ߰<EFBFBD> <DFB0> <EFBFBD> 3<> <33> <20> <>
LPCHARACTER chRefineNPC = CHARACTER_MANAGER : : instance ( ) . Find ( m_dwRefineNPCVID ) ;
if ( chRefineNPC & & chRefineNPC - > GetEmpire ( ) ! = GetEmpire ( ) )
return iCost * iMultiply * 3 ;
return iCost * iMultiply ;
}
else
return iCost ;
}
void CHARACTER : : PayRefineFee ( int iTotalMoney )
{
int iFee = iTotalMoney / 10 ;
CGuild * pGuild = GetRefineGuild ( ) ;
int iRemain = iTotalMoney ;
if ( pGuild )
{
// <20> ڱ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ̸<EFBFBD> iTotalMoney<65> <79> <20> ̹<EFBFBD> 10%<25> <> <20> <> <EFBFBD> ܵǾ<DCB5> <C7BE> ִ<EFBFBD>
if ( pGuild ! = GetGuild ( ) )
{
pGuild - > RequestDepositMoney ( this , iFee ) ;
iRemain - = iFee ;
}
}
PointChange ( POINT_GOLD , - iRemain ) ;
}
// END_OF_ADD_REFINE_BUILDING
//Hack <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> üũ.
bool CHARACTER : : IsHack ( bool bSendMsg , bool bCheckShopOwner , int limittime )
{
const int iPulse = thecore_pulse ( ) ;
if ( test_server )
bSendMsg = true ;
//â<> <C3A2> <20> <> <EFBFBD> <EFBFBD> üũ
if ( iPulse - GetSafeboxLoadTime ( ) < PASSES_PER_SEC ( limittime ) )
{
if ( bSendMsg )
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " â<EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> %d<> <64> <20> ̳<EFBFBD> <CCB3> <EFBFBD> <EFBFBD> <EFBFBD> <20> ٸ<EFBFBD> <D9B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̵<EFBFBD> <CCB5> Ҽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> . " ) , limittime ) ;
if ( test_server )
ChatPacket ( CHAT_TYPE_INFO , " [TestOnly]Pulse %d LoadTime %d PASS %d " , iPulse , GetSafeboxLoadTime ( ) , PASSES_PER_SEC ( limittime ) ) ;
return true ;
}
//<2F> ŷ<EFBFBD> <C5B7> <EFBFBD> <EFBFBD> <EFBFBD> â üũ
if ( bCheckShopOwner )
{
if ( GetExchange ( ) | | GetMyShop ( ) | | GetShopOwner ( ) | | IsOpenSafebox ( ) | | IsCubeOpen ( ) )
{
if ( bSendMsg )
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> ŷ<EFBFBD> â,â<> <C3A2> <20> <> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> ¿<EFBFBD> <C2BF> <EFBFBD> <EFBFBD> <EFBFBD> <20> ٸ<EFBFBD> <D9B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̵<EFBFBD> ,<2C> <> <EFBFBD> <EFBFBD> <20> Ҽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> " ) ) ;
return true ;
}
}
else
{
if ( GetExchange ( ) | | GetMyShop ( ) | | IsOpenSafebox ( ) | | IsCubeOpen ( ) )
{
if ( bSendMsg )
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> ŷ<EFBFBD> â,â<> <C3A2> <20> <> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> ¿<EFBFBD> <C2BF> <EFBFBD> <EFBFBD> <EFBFBD> <20> ٸ<EFBFBD> <D9B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̵<EFBFBD> ,<2C> <> <EFBFBD> <EFBFBD> <20> Ҽ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> " ) ) ;
return true ;
}
}
//PREVENT_PORTAL_AFTER_EXCHANGE
//<2F> <> ȯ <20> <> <20> ð<EFBFBD> üũ
if ( iPulse - GetExchangeTime ( ) < PASSES_PER_SEC ( limittime ) )
{
if ( bSendMsg )
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> ŷ<EFBFBD> <20> <> %d<> <64> <20> ̳<EFBFBD> <CCB3> <EFBFBD> <EFBFBD> <EFBFBD> <20> ٸ<EFBFBD> <D9B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̵<EFBFBD> <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ." ) , limittime ) ;
return true ;
}
//END_PREVENT_PORTAL_AFTER_EXCHANGE
//PREVENT_ITEM_COPY
if ( iPulse - GetMyShopTime ( ) < PASSES_PER_SEC ( limittime ) )
{
if ( bSendMsg )
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> ŷ<EFBFBD> <20> <> %d<> <64> <20> ̳<EFBFBD> <CCB3> <EFBFBD> <EFBFBD> <EFBFBD> <20> ٸ<EFBFBD> <D9B8> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> ̵<EFBFBD> <20> <> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ." ) , limittime ) ;
return true ;
}
if ( iPulse - GetRefineTime ( ) < PASSES_PER_SEC ( limittime ) )
{
if ( bSendMsg )
ChatPacket ( CHAT_TYPE_INFO , LC_TEXT ( " <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> %d<> <64> <20> ̳<EFBFBD> <CCB3> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ȯ<EFBFBD> <C8AF> ,<2C> <> ȯ<EFBFBD> <C8AF> <EFBFBD> <EFBFBD> <EFBFBD> θ<EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> ϴ<EFBFBD> ." ) , limittime ) ;
return true ;
}
//END_PREVENT_ITEM_COPY
return false ;
}
BOOL CHARACTER : : IsMonarch ( ) const
{
//MONARCH_LIMIT
if ( CMonarch : : instance ( ) . IsMonarch ( GetPlayerID ( ) , GetEmpire ( ) ) )
return true ;
return false ;
//END_MONARCH_LIMIT
}
void CHARACTER : : Say ( const std : : string & s )
{
struct : : packet_script packet_script ;
packet_script . header = HEADER_GC_SCRIPT ;
packet_script . skin = 1 ;
packet_script . src_size = s . size ( ) ;
packet_script . size = packet_script . src_size + sizeof ( struct packet_script ) ;
TEMP_BUFFER buf ;
buf . write ( & packet_script , sizeof ( struct packet_script ) ) ;
buf . write ( & s [ 0 ] , s . size ( ) ) ;
if ( IsPC ( ) )
{
GetDesc ( ) - > Packet ( buf . read_peek ( ) , buf . size ( ) ) ;
}
}
//
// Monarch
//
void CHARACTER : : InitMC ( )
{
for ( int n = 0 ; n < MI_MAX ; + + n )
{
m_dwMonarchCooltime [ n ] = thecore_pulse ( ) ;
}
m_dwMonarchCooltimelimit [ MI_HEAL ] = PASSES_PER_SEC ( MC_HEAL ) ;
m_dwMonarchCooltimelimit [ MI_WARP ] = PASSES_PER_SEC ( MC_WARP ) ;
m_dwMonarchCooltimelimit [ MI_TRANSFER ] = PASSES_PER_SEC ( MC_TRANSFER ) ;
m_dwMonarchCooltimelimit [ MI_TAX ] = PASSES_PER_SEC ( MC_TAX ) ;
m_dwMonarchCooltimelimit [ MI_SUMMON ] = PASSES_PER_SEC ( MC_SUMMON ) ;
m_dwMonarchCooltime [ MI_HEAL ] - = PASSES_PER_SEC ( GetMCL ( MI_HEAL ) ) ;
m_dwMonarchCooltime [ MI_WARP ] - = PASSES_PER_SEC ( GetMCL ( MI_WARP ) ) ;
m_dwMonarchCooltime [ MI_TRANSFER ] - = PASSES_PER_SEC ( GetMCL ( MI_TRANSFER ) ) ;
m_dwMonarchCooltime [ MI_TAX ] - = PASSES_PER_SEC ( GetMCL ( MI_TAX ) ) ;
m_dwMonarchCooltime [ MI_SUMMON ] - = PASSES_PER_SEC ( GetMCL ( MI_SUMMON ) ) ;
}
DWORD CHARACTER : : GetMC ( enum MONARCH_INDEX e ) const
{
return m_dwMonarchCooltime [ e ] ;
}
void CHARACTER : : SetMC ( enum MONARCH_INDEX e )
{
m_dwMonarchCooltime [ e ] = thecore_pulse ( ) ;
}
bool CHARACTER : : IsMCOK ( enum MONARCH_INDEX e ) const
{
int iPulse = thecore_pulse ( ) ;
if ( ( iPulse - GetMC ( e ) ) < GetMCL ( e ) )
{
if ( test_server )
sys_log ( 0 , " Pulse %d cooltime %d, limit %d " , iPulse , GetMC ( e ) , GetMCL ( e ) ) ;
return false ;
}
if ( test_server )
sys_log ( 0 , " Pulse %d cooltime %d, limit %d " , iPulse , GetMC ( e ) , GetMCL ( e ) ) ;
return true ;
}
DWORD CHARACTER : : GetMCL ( enum MONARCH_INDEX e ) const
{
return m_dwMonarchCooltimelimit [ e ] ;
}
DWORD CHARACTER : : GetMCLTime ( enum MONARCH_INDEX e ) const
{
int iPulse = thecore_pulse ( ) ;
if ( test_server )
sys_log ( 0 , " Pulse %d cooltime %d, limit %d " , iPulse , GetMC ( e ) , GetMCL ( e ) ) ;
return ( GetMCL ( e ) ) / passes_per_sec - ( iPulse - GetMC ( e ) ) / passes_per_sec ;
}
bool CHARACTER : : IsSiegeNPC ( ) const
{
return IsNPC ( ) & & ( GetRaceNum ( ) = = 11000 | | GetRaceNum ( ) = = 11002 | | GetRaceNum ( ) = = 11004 ) ;
}
//------------------------------------------------
void CHARACTER : : UpdateDepositPulse ( )
{
m_deposit_pulse = thecore_pulse ( ) + PASSES_PER_SEC ( 60 * 5 ) ; // 5<> <35>
}
bool CHARACTER : : CanDeposit ( ) const
{
return ( m_deposit_pulse = = 0 | | ( m_deposit_pulse < thecore_pulse ( ) ) ) ;
}
//------------------------------------------------
ESex GET_SEX ( LPCHARACTER ch )
{
switch ( ch - > GetRaceNum ( ) )
{
case MAIN_RACE_WARRIOR_M :
case MAIN_RACE_SURA_M :
case MAIN_RACE_ASSASSIN_M :
case MAIN_RACE_SHAMAN_M :
return SEX_MALE ;
case MAIN_RACE_ASSASSIN_W :
case MAIN_RACE_SHAMAN_W :
case MAIN_RACE_WARRIOR_W :
case MAIN_RACE_SURA_W :
return SEX_FEMALE ;
}
/* default sex = male */
return SEX_MALE ;
}
int CHARACTER : : GetHPPct ( ) const
{
return ( GetHP ( ) * 100 ) / GetMaxHP ( ) ;
}
bool CHARACTER : : IsBerserk ( ) const
{
if ( m_pkMobInst ! = NULL )
return m_pkMobInst - > m_IsBerserk ;
else
return false ;
}
void CHARACTER : : SetBerserk ( bool mode )
{
if ( m_pkMobInst ! = NULL )
m_pkMobInst - > m_IsBerserk = mode ;
}
bool CHARACTER : : IsGodSpeed ( ) const
{
if ( m_pkMobInst ! = NULL )
{
return m_pkMobInst - > m_IsGodSpeed ;
}
else
{
return false ;
}
}
void CHARACTER : : SetGodSpeed ( bool mode )
{
if ( m_pkMobInst ! = NULL )
{
m_pkMobInst - > m_IsGodSpeed = mode ;
if ( mode = = true )
{
SetPoint ( POINT_ATT_SPEED , 250 ) ;
}
else
{
SetPoint ( POINT_ATT_SPEED , m_pkMobData - > m_table . sAttackSpeed ) ;
}
}
}
bool CHARACTER : : IsDeathBlow ( ) const
{
2022-11-27 14:36:04 +02:00
if ( Random : : get ( 1 , 100 ) < = m_pkMobData - > m_table . bDeathBlowPoint )
2022-03-05 12:44:06 +02:00
{
return true ;
}
else
{
return false ;
}
}
struct FFindReviver
{
FFindReviver ( )
{
pChar = NULL ;
HasReviver = false ;
}
void operator ( ) ( LPCHARACTER ch )
{
if ( ch - > IsMonster ( ) ! = true )
{
return ;
}
if ( ch - > IsReviver ( ) = = true & & pChar ! = ch & & ch - > IsDead ( ) ! = true )
{
2022-11-27 14:36:04 +02:00
if ( Random : : get ( 1 , 100 ) < = ch - > GetMobTable ( ) . bRevivePoint )
2022-03-05 12:44:06 +02:00
{
HasReviver = true ;
pChar = ch ;
}
}
}
LPCHARACTER pChar ;
bool HasReviver ;
} ;
bool CHARACTER : : HasReviverInParty ( ) const
{
LPPARTY party = GetParty ( ) ;
if ( party ! = NULL )
{
if ( party - > GetMemberCount ( ) = = 1 ) return false ;
FFindReviver f ;
party - > ForEachMemberPtr ( f ) ;
return f . HasReviver ;
}
return false ;
}
bool CHARACTER : : IsRevive ( ) const
{
if ( m_pkMobInst ! = NULL )
{
return m_pkMobInst - > m_IsRevive ;
}
return false ;
}
void CHARACTER : : SetRevive ( bool mode )
{
if ( m_pkMobInst ! = NULL )
{
m_pkMobInst - > m_IsRevive = mode ;
}
}
# define IS_SPEED_HACK_PLAYER(ch) (ch->m_speed_hack_count > SPEEDHACK_LIMIT_COUNT)
EVENTFUNC ( check_speedhack_event )
{
char_event_info * info = dynamic_cast < char_event_info * > ( event - > info ) ;
if ( info = = NULL )
{
sys_err ( " check_speedhack_event> <Factor> Null pointer " ) ;
return 0 ;
}
LPCHARACTER ch = info - > ch ;
if ( NULL = = ch | | ch - > IsNPC ( ) )
return 0 ;
if ( IS_SPEED_HACK_PLAYER ( ch ) )
{
// write hack log
LogManager : : instance ( ) . SpeedHackLog ( ch - > GetPlayerID ( ) , ch - > GetX ( ) , ch - > GetY ( ) , ch - > m_speed_hack_count ) ;
if ( false = = LC_IsEurope ( ) )
{
// close connection
LPDESC desc = ch - > GetDesc ( ) ;
if ( desc )
{
DESC_MANAGER : : instance ( ) . DestroyDesc ( desc ) ;
return 0 ;
}
}
}
ch - > m_speed_hack_count = 0 ;
ch - > ResetComboHackCount ( ) ;
return PASSES_PER_SEC ( 60 ) ;
}
void CHARACTER : : StartCheckSpeedHackEvent ( )
{
if ( m_pkCheckSpeedHackEvent )
return ;
char_event_info * info = AllocEventInfo < char_event_info > ( ) ;
info - > ch = this ;
m_pkCheckSpeedHackEvent = event_create ( check_speedhack_event , info , PASSES_PER_SEC ( 60 ) ) ; // 1<> <31>
}
void CHARACTER : : GoHome ( )
{
WarpSet ( EMPIRE_START_X ( GetEmpire ( ) ) , EMPIRE_START_Y ( GetEmpire ( ) ) ) ;
}
void CHARACTER : : SendGuildName ( CGuild * pGuild )
{
if ( NULL = = pGuild ) return ;
DESC * desc = GetDesc ( ) ;
if ( NULL = = desc ) return ;
if ( m_known_guild . find ( pGuild - > GetID ( ) ) ! = m_known_guild . end ( ) ) return ;
m_known_guild . insert ( pGuild - > GetID ( ) ) ;
TPacketGCGuildName pack ;
memset ( & pack , 0x00 , sizeof ( pack ) ) ;
pack . header = HEADER_GC_GUILD ;
pack . subheader = GUILD_SUBHEADER_GC_GUILD_NAME ;
pack . size = sizeof ( TPacketGCGuildName ) ;
pack . guildID = pGuild - > GetID ( ) ;
memcpy ( pack . guildName , pGuild - > GetName ( ) , GUILD_NAME_MAX_LEN ) ;
desc - > Packet ( & pack , sizeof ( pack ) ) ;
}
void CHARACTER : : SendGuildName ( DWORD dwGuildID )
{
SendGuildName ( CGuildManager : : instance ( ) . FindGuild ( dwGuildID ) ) ;
}
EVENTFUNC ( destroy_when_idle_event )
{
char_event_info * info = dynamic_cast < char_event_info * > ( event - > info ) ;
if ( info = = NULL )
{
sys_err ( " destroy_when_idle_event> <Factor> Null pointer " ) ;
return 0 ;
}
LPCHARACTER ch = info - > ch ;
if ( ch = = NULL ) { // <Factor>
return 0 ;
}
if ( ch - > GetVictim ( ) )
{
return PASSES_PER_SEC ( 300 ) ;
}
sys_log ( 1 , " DESTROY_WHEN_IDLE: %s " , ch - > GetName ( ) ) ;
ch - > m_pkDestroyWhenIdleEvent = NULL ;
M2_DESTROY_CHARACTER ( ch ) ;
return 0 ;
}
void CHARACTER : : StartDestroyWhenIdleEvent ( )
{
if ( m_pkDestroyWhenIdleEvent )
return ;
char_event_info * info = AllocEventInfo < char_event_info > ( ) ;
info - > ch = this ;
m_pkDestroyWhenIdleEvent = event_create ( destroy_when_idle_event , info , PASSES_PER_SEC ( 300 ) ) ;
}
void CHARACTER : : SetComboSequence ( BYTE seq )
{
m_bComboSequence = seq ;
}
BYTE CHARACTER : : GetComboSequence ( ) const
{
return m_bComboSequence ;
}
void CHARACTER : : SetLastComboTime ( DWORD time )
{
m_dwLastComboTime = time ;
}
DWORD CHARACTER : : GetLastComboTime ( ) const
{
return m_dwLastComboTime ;
}
void CHARACTER : : SetValidComboInterval ( int interval )
{
m_iValidComboInterval = interval ;
}
int CHARACTER : : GetValidComboInterval ( ) const
{
return m_iValidComboInterval ;
}
BYTE CHARACTER : : GetComboIndex ( ) const
{
return m_bComboIndex ;
}
void CHARACTER : : IncreaseComboHackCount ( int k )
{
m_iComboHackCount + = k ;
if ( m_iComboHackCount > = 10 )
{
if ( GetDesc ( ) )
2022-11-27 14:36:04 +02:00
if ( GetDesc ( ) - > DelayedDisconnect ( Random : : get ( 2 , 7 ) ) )
2022-03-05 12:44:06 +02:00
{
sys_log ( 0 , " COMBO_HACK_DISCONNECT: %s count: %d " , GetName ( ) , m_iComboHackCount ) ;
LogManager : : instance ( ) . HackLog ( " Combo " , this ) ;
}
}
}
void CHARACTER : : ResetComboHackCount ( )
{
m_iComboHackCount = 0 ;
}
void CHARACTER : : SkipComboAttackByTime ( int interval )
{
m_dwSkipComboAttackByTime = get_dword_time ( ) + interval ;
}
DWORD CHARACTER : : GetSkipComboAttackByTime ( ) const
{
return m_dwSkipComboAttackByTime ;
}
void CHARACTER : : ResetChatCounter ( )
{
m_bChatCounter = 0 ;
}
BYTE CHARACTER : : IncreaseChatCounter ( )
{
return + + m_bChatCounter ;
}
BYTE CHARACTER : : GetChatCounter ( ) const
{
return m_bChatCounter ;
}
// <20> <> <EFBFBD> ̳<EFBFBD> <20> ٸ<EFBFBD> <D9B8> <EFBFBD> <EFBFBD> <EFBFBD> Ÿ<> <C5B8> <20> ֳ<EFBFBD> ?
bool CHARACTER : : IsRiding ( ) const
{
return IsHorseRiding ( ) | | GetMountVnum ( ) ;
}
bool CHARACTER : : CanWarp ( ) const
{
const int iPulse = thecore_pulse ( ) ;
const int limit_time = PASSES_PER_SEC ( g_nPortalLimitTime ) ;
if ( ( iPulse - GetSafeboxLoadTime ( ) ) < limit_time )
return false ;
if ( ( iPulse - GetExchangeTime ( ) ) < limit_time )
return false ;
if ( ( iPulse - GetMyShopTime ( ) ) < limit_time )
return false ;
if ( ( iPulse - GetRefineTime ( ) ) < limit_time )
return false ;
if ( GetExchange ( ) | | GetMyShop ( ) | | GetShopOwner ( ) | | IsOpenSafebox ( ) | | IsCubeOpen ( ) )
return false ;
return true ;
}
DWORD CHARACTER : : GetNextExp ( ) const
{
if ( PLAYER_EXP_TABLE_MAX < GetLevel ( ) )
return 2500000000 ;
else
return exp_table [ GetLevel ( ) ] ;
}
int CHARACTER : : GetSkillPowerByLevel ( int level , bool bMob ) const
{
2022-11-27 22:18:08 +02:00
return CTableBySkill : : instance ( ) . GetSkillPowerByLevelFromType ( GetJob ( ) , GetSkillGroup ( ) , std : : clamp < int > ( level , 0 , SKILL_MAX_LEVEL ) , bMob ) ;
2022-03-05 12:44:06 +02:00
}