looks very nice.
Beiträge von Schizophren.
-
-
Wenn es irgendwann um bezahlte Hilfe geht musst du echt aufpassen. Gibt viele die sich bereichern wollen aber nichts leisten können. Immer erst machen lassen, dannach zahlen.
-
Bitte melden Sie sich an, um diesen Anhang zu sehen.
Official server start is scheduled for the 13.10.2023 at approx. 19:00 CEST.
We would like to inform you that a Discord Invite Event is currently taking place, which will make it much easier for you to start on the server when you win the event.
Bitte melden Sie sich an, um diesen Link zu sehen.Bitte melden Sie sich an, um diesen Link zu sehen. Bitte melden Sie sich an, um diesen Link zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
Bitte melden Sie sich an, um dieses Bild zu sehen.
-
Haste die Sockets auch in der DB hinzugefügt ?
sprich im player.item table
Ja die sind auch dort hinzugefügt. Jedoch wird dann dort als beispiel 14570605 als vnum für den 5ten socket gesetzt nach dem craften.
Syserr vom server kommt dann das:Wenn ich diesen Part auskommentiere werden die slots nicht mit übernommen, also auch wenn steine drinnen sind werden diese nicht mit übernommen. Evtl. muss hier dran was geändert werden, jedoch weis ich nicht genau was.
-
Hallo,
Ich habe gerade ein Problem bemerkt. Meine ITEM_SOCKET_SLOT_MAX_NUM = 6, ist auf 6 eingestellt, bei den Items in der Item_Proto jedoch auf 4.
Sobald ich jetzt eine Rüsstung Crafte kommt socket 5 und 6 Dazu und dort ist eine Galle drinnen. Wie kommt das zu stande ?
Bitte melden Sie sich an, um diesen Anhang zu sehen.
Danke im voraus. -
habe ein Worldboss System welches 4verschiedene Bosse spawnt zu bestimmten Uhrzeiten aber ich denke daran liegt es nicht.
LynxDas CWhisperAdmin ist ein Whispersystem womit man als Implementor ne Message an jeden Ch/Core Spieler sendet.
Nunja, im endeffekt habe ich bisher keine Lösung gefunden. Woran könnte es denn jetzt evtl. genauer liegen?
Bin mir eigentlich sehr sicher, dass das Admin Whisper Gedöns zum Absturz führt. Kommentier das mal aus.
Auch wenn es in diesen Momenten nicht genutzt wird? weil außer mir kann es niemand nutzen und ich bin in diesen Zeiten nicht online. Aber wenn du sagst es könnte daran liegen versuche ich es mal.
Wenn ich kein bt full mache kommt nur der fehler mit der enity_view.cpp aber daran sollte es ja nicht liegen oder ? -
Irgendein System wie Battlezone oder etwas anderes das von selber startet und endet vorhanden?
habe ein Worldboss System welches 4verschiedene Bosse spawnt zu bestimmten Uhrzeiten aber ich denke daran liegt es nicht.
LynxDas CWhisperAdmin ist ein Whispersystem womit man als Implementor ne Message an jeden Ch/Core Spieler sendet.
Nunja, im endeffekt habe ich bisher keine Lösung gefunden. Woran könnte es denn jetzt evtl. genauer liegen?
-
überprüf mal deine Destroy Funktion in der char.cpp
hmm legit keine ahnung...
Code- #include "stdafx.h"
- #include <boost/format.hpp>
- #include <unordered_set>
- #include "../../common/vnum_helper.h"
- #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 "banword.h"
- #include "target.h"
- #include "wedding.h"
- #include "mob_manager.h"
- #include "mining.h"
- #include "arena.h"
- #include "horsename_manager.h"
- #include "gm.h"
- #include "map_location.h"
- #include "blue_dragon_binder.h"
- #include "skill_power.h"
- #include "buff_on_attributes.h"
- #include "pet_system.h"
- #include "dragon_soul.h"
- #include "battle_arena.h"
- #ifdef ENABLE_SEND_TARGET_INFO
- #include <algorithm>
- #include <iterator>
- using namespace std;
- #endif
- #include "new_inventory.h"
- #ifdef ENABLE_NEW_PET_SYSTEM
- #include "new_pet_system.h"
- #endif
- #ifdef __MELEY_LAIR_DUNGEON__
- #include "new_meley_lair.h"
- #endif
- #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
- #include "new_mount_system.h"
- #endif
- #ifdef __ENABLE_NEW_OFFLINESHOP__
- #include "new_offlineshop.h"
- #include "new_offlineshop_manager.h"
- #endif
- #ifdef ENABLE_BATTLE_PASS
- #include "new_battle_pass.h"
- #endif
- #ifdef ENABLE_SWITCHBOT
- #include "new_switchbot.h"
- #endif
- #ifdef ENABLE_ZODIAC_TEMPLE
- #include "new_zodiac_temple.h"
- #endif
- #ifdef ENABLE_DAILY_BOSS
- #include "new_daily_boss.h"
- #endif
- #ifdef ENABLE_BOSS_TRACKING
- #include "new_boss_tracking.h"
- #endif
- #ifdef __ADMIN_MANAGER__
- #include "new_admin_manager.h"
- #endif
- #ifdef ENABLE_EXTENDED_BATTLE_PASS
- #include "battlepass_manager.h"
- #endif
- bool IS_BLOCKED_PET_SUMMON_MAP(int map_index, bool isHorse)
- {
- if (map_index == 113)
- {
- return true;
- }
- return false;
- }
- bool IS_MOUNTABLE_ZONE(int map_index, bool isHorse)
- {
- if (map_index >= 10000)
- {
- map_index /= 10000;
- }
- if (CWarMapManager::instance().IsWarMap(map_index))
- {
- return false;
- }
- if (CArenaManager::instance().IsArenaMap(map_index))
- {
- return false;
- }
- switch (map_index)
- {
- case 81: // m2_wedding
- case 110: // m2_t3
- case 112: // m2_duelmap
- case 113: // m2_ox
- case 254: // m2_kingdomwar
- {
- return false;
- }
- }
- return true;
- }
- bool CAN_ENTER_ZONE(const LPCHARACTER &ch, int map_index)
- {
- switch (map_index)
- {
- case 218: // m2_capedragonhead
- case 302: // m2_dawnmistwood
- case 303: // m2_bayblacksand
- case 304: // m2_mt_thunder
- if (ch->GetLevel() < 90)
- {
- return false;
- }
- case 72: // m2_v3
- case 73: // m2_v4
- case 217: // m2_sd3
- if (ch->GetLevel() < 75)
- {
- return false;
- }
- case 68: // m2_red_forest
- case 71: // m2_sd1_and_sd2
- if (ch->GetLevel() < 35)
- {
- return false;
- }
- }
- return true;
- }
- #ifdef ENABLE_NEW_ICEDAMAGE_SYSTEM
- const DWORD CHARACTER::GetNoDamageRaceFlag()
- {
- return m_dwNDRFlag;
- }
- void CHARACTER::SetNoDamageRaceFlag(DWORD dwRaceFlag)
- {
- if (dwRaceFlag >= MAIN_RACE_MAX_NUM)
- {
- return;
- }
- if (IS_SET(m_dwNDRFlag, 1 << dwRaceFlag))
- {
- return;
- }
- SET_BIT(m_dwNDRFlag, 1 << dwRaceFlag);
- }
- void CHARACTER::UnsetNoDamageRaceFlag(DWORD dwRaceFlag)
- {
- if (dwRaceFlag >= MAIN_RACE_MAX_NUM)
- {
- return;
- }
- if (!IS_SET(m_dwNDRFlag, 1 << dwRaceFlag))
- {
- return;
- }
- REMOVE_BIT(m_dwNDRFlag, 1 << dwRaceFlag);
- }
- void CHARACTER::ResetNoDamageRaceFlag()
- {
- m_dwNDRFlag = 0;
- }
- const std::set<DWORD> & CHARACTER::GetNoDamageAffectFlag()
- {
- return m_setNDAFlag;
- }
- void CHARACTER::SetNoDamageAffectFlag(DWORD dwAffectFlag)
- {
- m_setNDAFlag.insert(dwAffectFlag);
- }
- void CHARACTER::UnsetNoDamageAffectFlag(DWORD dwAffectFlag)
- {
- m_setNDAFlag.erase(dwAffectFlag);
- }
- void CHARACTER::ResetNoDamageAffectFlag()
- {
- m_setNDAFlag.clear();
- }
- #endif
- 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;
- }
- DWORD GetHairPartByJob(DWORD hair, BYTE job)
- {
- switch (job)
- {
- case JOB_WARRIOR:
- hair -= 72000;
- break;
- case JOB_ASSASSIN:
- hair -= 71250;
- break;
- case JOB_SURA:
- hair -= 70500;
- break;
- case JOB_SHAMAN:
- hair -= 69750;
- break;
- #ifdef ENABLE_WOLFMAN
- case JOB_WOLFMAN:
- break;
- #endif
- default:
- break;
- }
- return hair;
- }
- 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;
- #ifdef ENABLE_SEND_TARGET_INFO
- dwLastTargetInfoPulse = 0;
- #endif
- #ifdef ENABLE_KICK_HACK_SECURITY
- m_iLastPMPulse = 0;
- m_iPMCounter = 0;
- #endif
- 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;
- #ifdef ENABLE_MULTI_FARM_BLOCK
- m_bmultiFarmStatus = false;
- #endif
- m_pkMobData = NULL;
- m_pkMobInst = NULL;
- _canRegenHP = true;
- 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;
- m_pkMiningEvent = NULL;
- m_pkPoisonEvent = NULL;
- #ifdef ENABLE_WOLFMAN
- m_pkBleedEvent = NULL;
- #endif
- m_pkChangeChannelEvent = NULL;
- m_pkFireEvent = NULL;
- m_pkDecayEvent = NULL;
- 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 = std::min(0UL, (unsigned long)get_dword_time() - 120000UL);
- m_bAddChrState = 0;
- m_pkChrStone = NULL;
- m_pkSafebox = NULL;
- m_iSafeboxSize = -1;
- m_iSafeboxLoadTime = 0;
- m_pkMall = NULL;
- m_iMallLoadTime = 0;
- #ifdef __ENABLE_ITEMSHOP_IN_GAME__
- m_iItemShopRefreshTime = 0;
- #endif
- 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;
- #ifdef ENABLE_WOLFMAN
- m_bHasBleeded = false;
- #endif
- 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_dwUnderGuildWarInfoMessageTime = get_dword_time() - 60000;
- m_bUnderRefine = false;
- m_dwRefineNPCVID = 0;
- 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;
- #ifdef __ENABLE_NEW_OFFLINESHOP__
- m_pkOfflineShop = NULL;
- m_pkShopSafebox = NULL;
- m_pkAuction = NULL;
- m_pkAuctionGuest= NULL;
- m_pkOfflineShopGuest = NULL;
- m_bIsLookingOfflineshopOfferList = false;
- #endif
- ResetStopTime();
- #ifdef ENABLE_GAYA_SYSTEM
- LOAD_GAYA();
- #endif
- 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;
- m_dwLastSkillTime = get_dword_time();
- memset(m_adwMobSkillCooltime, 0, sizeof(m_adwMobSkillCooltime));
- m_pArena = NULL;
- m_nPotionLimit = quest::CQuestManager::instance().GetEventFlag("arena_potion_limit_count");
- m_isOpenSafebox = 0;
- m_iRefineTime = 0;
- m_iSeedTime = 0;
- m_iExchangeTime = 0;
- m_iMyShopTime = 0;
- m_deposit_pulse = 0;
- m_strNewName.clear();
- m_known_guild.clear();
- m_dwLogOffInterval = 0;
- m_dwLastPlay = 0;
- m_bComboIndex = 0;
- m_dwSkipComboAttackByTime = 0;
- m_dwMountTime = 0;
- m_dwLastGoldDropTime = 0;
- m_bIsLoadedAffect = false;
- cannot_dead = false;
- m_petSystem = 0;
- m_bIsPet = false;
- #ifdef ENABLE_NEW_ICEDAMAGE_SYSTEM
- m_dwNDRFlag = 0;
- m_setNDAFlag.clear();
- #endif
- m_fAttMul = 1.0f;
- m_fDamMul = 1.0f;
- m_pointsInstant.iDragonSoulActiveDeck = -1;
- memset(&m_tvLastSyncTime, 0, sizeof(m_tvLastSyncTime));
- #ifdef ENABLE_EXTENDED_BATTLE_PASS
- m_listExtBattlePass.clear();
- m_bIsLoadedExtBattlePass = false;
- m_dwLastReciveExtBattlePassInfoTime = 0;
- #endif
- #ifdef ENABLE_SHOULDER_SASH_SYSTEM
- m_bSashCombination = false;
- m_bSashAbsorption = false;
- #endif
- m_powersStripped = false;
- m_RegenDelay = 0;
- m_RegenPctReduction = 0;
- itemAward_vnum = 0;
- memset(itemAward_cmd, 0, 20);
- m_inventory = NULL;
- SetLastPickupTime(0);
- m_activityHandler = NULL;
- #if defined(ENABLE_FAKE_PC) || defined(ENABLE_FAKE_BUFF)
- m_dwLastSkillVnum = 0;
- #endif
- #ifdef ENABLE_FAKE_PC
- m_pkFakePCAfkEvent = NULL;
- m_pkFakePCOwner = NULL;
- m_pkFakePCSpawnItem = NULL;
- m_fFakePCDamageFactor = 1.0f;
- m_bIsNoAttackFakePC = false;
- m_bCanChangeVictim = true;
- m_bDisabledHealPotion = false;
- #endif
- #ifdef ENABLE_FAKE_BUFF
- m_pkFakeBuffOwner = NULL;
- m_pkFakeBuffSpawn = NULL;
- m_pkFakeBuffItem = NULL;
- m_pkFollowOwner = NULL;
- #endif
- #ifdef ENABLE_BATTLE_PASS
- m_listBattlePass.clear();
- m_bIsLoadedBattlePass = false;
- #endif
- #ifdef ENABLE_SORT_INVENTORY
- m_sortInventoryPulse = 0;
- m_sortSpecialStoragePulse = 0;
- #endif
- #ifdef ENABLE_ZODIAC_TEMPLE
- m_pkZodiac = NULL;
- m_dwZodiacCzLastTime = 0;
- m_dwLastZodiacAttackTime = 0;
- m_dwDeadCount = 0;
- #endif
- #ifdef ENABLE_SKILL_COLOR_SYSTEM
- memset(&m_dwSkillColor, 0, sizeof(m_dwSkillColor));
- #endif
- #ifdef ENABLE_TELEPORT_TO_A_FRIEND
- m_iLastWarpRequestTime = {};
- #endif
- #ifdef ENABLE_AFK_MODE_SYSTEM
- m_pkUpdateCharacter = NULL;
- m_isAway = false;
- #endif
- #ifdef ENABLE_BOSS_TRACKING
- m_pkUpdateBossTracking = NULL;
- #endif
- #ifdef __ADMIN_MANAGER__
- m_dwChatBanCount = 0;
- #endif
- #ifdef ENABLE_RUNE_SYSTEM
- m_dwRuneBonuses.clear();
- m_iStrike.clear();
- m_dwRuneString = "";
- #endif
- /*** From Lysium ***/
- bImmortality = false;
- m_damageHPLimit = 0;
- /*** End ***/
- #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
- m_MountSystem = 0;
- m_bIsMountSystem = false;
- #endif
- #ifdef ENABLE_ANTI_PACKET_FLOOD
- analyze_protect = 0;
- analyze_protect_count = 0;
- #endif
- #ifdef ENABLE_COSTUME_AURA_SYSTEM
- m_bAuraRefineWindowType = AURA_WINDOW_TYPE_MAX;
- m_bAuraRefineWindowOpen = false;
- for (BYTE i = AURA_SLOT_MAIN; i < AURA_SLOT_MAX; i++)
- m_pAuraRefineWindowItemSlot[i] = NPOS;
- memset(&m_bAuraRefineInfo, 0, AURA_REFINE_INFO_SLOT_MAX * sizeof(TAuraRefineInfo));
- #endif
- #ifdef ENABLE_CHECK_PICKUP_HACK
- m_dwLastPickupTime = 0;
- #endif
- #ifdef ENABLE_CHECK_GHOSTMODE
- m_dwCountGhostmodePoint = 0;
- #endif
- #ifdef ENABLE_NEW_PET_SYSTEM
- m_stImmortalSt = 0;
- memset(m_newpetskillcd, 0, sizeof(m_newpetskillcd));
- m_newpetSystem = 0;
- m_eggvid = 0;
- m_bIsNewPet = false;
- #endif
- #ifdef ENABLE_BIOLOG_SYSTEM
- m_pkBiologManager = NULL;
- #endif
- }
- void CHARACTER::Create(std::string stName, DWORD vid, bool isPC)
- {
- static int s_crc = 172814;
- char crc_string[128 + 1] {};
- snprintf(crc_string, sizeof(crc_string), "%s%p%d", stName.c_str(), this, ++s_crc);
- m_vid = VID(vid, GetCRC32(crc_string, strlen(crc_string)));
- if (isPC)
- {
- m_stName = stName;
- m_activityHandler = spActivityHandler(new ActivityHandler(this));
- m_inventory = std::shared_ptr<CInventory>(new CInventory(this));
- }
- }
- void CHARACTER::Destroy()
- {
- #ifdef __ADMIN_MANAGER__
- if (IsNPC())
- CAdminManager::instance().OnMonsterDestroy(this);
- #endif
- #ifdef ENABLE_FAKE_PC
- if (FakePC_Check() && !FakePC_IsSupporter())
- {
- if (!IsDead() && GetDungeon())
- {
- Dead(NULL, false);
- }
- }
- #endif
- CloseMyShop();
- #ifdef ENABLE_FAKE_PC
- FakePC_Destroy();
- #endif
- #ifdef ENABLE_FAKE_BUFF
- if (FakeBuff_Check())
- {
- FakeBuff_Destroy();
- }
- if (GetFollowing())
- {
- GetFollowing()->RemoveFollower(this);
- }
- while (!m_set_Follower.empty())
- {
- M2_DESTROY_CHARACTER(*m_set_Follower.begin());
- }
- #endif
- if (m_pkRegen)
- {
- if (m_pkDungeon)
- {
- if (m_pkDungeon->IsValidRegen(m_pkRegen, regen_id_))
- {
- --m_pkRegen->count;
- }
- }
- #ifdef ENABLE_ZODIAC_TEMPLE
- else if (m_pkZodiac)
- {
- if (m_pkZodiac->IsValidRegen(m_pkRegen, regen_id_))
- {
- --m_pkRegen->count;
- }
- }
- #endif
- else
- {
- --m_pkRegen->count;
- }
- m_pkRegen = NULL;
- }
- if (m_pkDungeon)
- {
- SetDungeon(NULL);
- }
- #ifdef ENABLE_ZODIAC_TEMPLE
- if (m_pkZodiac)
- {
- SetZodiac(NULL);
- }
- #endif
- if (m_petSystem)
- {
- m_petSystem->Destroy();
- delete m_petSystem;
- m_petSystem = 0;
- }
- #ifdef ENABLE_NEW_PET_SYSTEM
- if (m_newpetSystem)
- {
- m_newpetSystem->Destroy();
- delete m_newpetSystem;
- m_newpetSystem = 0;
- }
- #endif
- #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
- if (m_MountSystem)
- {
- m_MountSystem->Destroy();
- delete m_MountSystem;
- m_MountSystem = 0;
- }
- #endif
- HorseSummon(false);
- if (GetRider())
- {
- GetRider()->ClearHorseInfo();
- }
- if (GetDesc())
- {
- GetDesc()->BindCharacter(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();
- }
- 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);
- }
- 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;
- }
- for (auto it = m_map_buff_on_attrs.begin(); it != m_map_buff_on_attrs.end(); it++)
- {
- M2_DELETE(it->second);
- }
- m_map_buff_on_attrs.clear();
- 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);
- #ifdef ENABLE_WOLFMAN
- event_cancel(&m_pkBleedEvent);
- #endif
- event_cancel(&m_pkChangeChannelEvent);
- event_cancel(&m_pkFireEvent);
- event_cancel(&m_pkDecayEvent);
- event_cancel(&m_pkPartyRequestEvent);
- event_cancel(&m_pkWarpEvent);
- event_cancel(&m_pkMiningEvent);
- #ifdef ENABLE_BOSS_TRACKING
- event_cancel(&m_pkUpdateBossTracking);
- #endif
- for (auto &it : m_mapMobSkillEvent)
- {
- LPEVENT pkEvent = it.second;
- event_cancel(&pkEvent);
- }
- m_mapMobSkillEvent.clear();
- ClearAffect();
- 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();
- }
- std::string CHARACTER::GetStringName() const
- {
- return m_stName.empty() ? (m_pkMobData ? std::string(m_pkMobData->m_table.szLocaleName) : "") : m_stName;
- }
- const char* CHARACTER::GetProtoName() const
- {
- return m_pkMobData ? m_pkMobData->m_table.szName : "";
- }
- #ifdef ENABLE_EXTENDED_COUNT_ITEMS
- void CHARACTER::OpenMyShop(const char* c_pszSign, TShopItemTable* pTable, uint16_t bItemCount)
- #else
- void CHARACTER::OpenMyShop(const char* c_pszSign, TShopItemTable* pTable, BYTE bItemCount)
- #endif
- {
- if (GetMyShop())
- {
- CloseMyShop();
- return;
- }
- quest::PC* pPC = quest::CQuestManager::instance().GetPCForce(GetPlayerID());
- if (pPC->IsRunning())
- {
- return;
- }
- if (bItemCount == 0)
- {
- return;
- }
- unsigned long long nTotalMoney = 0;
- for (int n = 0; n < bItemCount; ++n)
- {
- nTotalMoney += static_cast<unsigned long long>((pTable+n)->price);
- }
- nTotalMoney += static_cast<unsigned long long>(GetGold());
- if (GetAllowedGold() <= nTotalMoney)
- {
- ChatInfoTrans(("YOU_CAN_NOT_DO_THIS_BECAUSE_YOU_HAVE_TOO_MUCH_MONEY"));
- return;
- }
- std::string shopSign = c_pszSign;
- shopSign.erase(std::remove_if(shopSign.begin(), shopSign.end(), [](char c)
- {
- return !isalnum(c) && c != ' ' && c != '+';
- }), shopSign.end());
- if (shopSign.length() < 3)
- {
- ChatInfoTrans(("SHOP_SIGN_INVALID_OR_TOO_SMALL"));
- return;
- }
- if (CBanwordManager::instance().CheckString(shopSign.c_str(), shopSign.length() + 1))
- {
- ChatInfoTrans(("SHOP_NAME_NOT_ALLOWED"));
- return;
- }
- std::map<DWORD, unsigned long long> itemkind;
- std::set<TItemPos> cont;
- #ifdef ENABLE_EXTENDED_COUNT_ITEMS
- for (uint16_t i = 0; i < bItemCount; ++i)
- #else
- for (BYTE i = 0; i < bItemCount; ++i)
- #endif
- {
- if (cont.find((pTable + i)->pos) != cont.end())
- {
- sys_err("MYSHOP: duplicate shop item detected! (name: %s)", GetName());
- return;
- }
- 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)))
- {
- ChatInfoTrans(("YOU_CANNOT_SELL_THIS_ITEM_IN_A_PRIVATE_SHOP"));
- return;
- }
- if (pkItem->IsEquipped())
- {
- ChatInfoTrans(("YOU_CANNOT_SELL_EQUIPPED_ITEMS_IN_A_PRIVATE_SHOP"));
- return;
- }
- #ifdef ENABLE_BINDING_SYSTEM
- if (pkItem->IsSealed())
- {
- ChatInfoTrans(("ITEM_IS_SEALED_CANNOT_DO"));
- return;
- }
- #endif
- if (pkItem->isLocked())
- {
- ChatInfoTrans(("ITEMS_BEING_IN_USE_CAN_NOT_BE_SOLD_IN_SHOP"));
- return;
- }
- if (pkItem->GetWindow() != INVENTORY && pkItem->GetWindow() != DRAGON_SOUL_INVENTORY)
- {
- sys_err("Wrong window (%d) when setting item %lu on shop", pkItem->GetWindow(), pkItem->GetID());
- return;
- }
- itemkind[pkItem->GetVnum()] = (pTable + i)->price / (uint16_t)pkItem->GetCount();
- }
- cont.insert((pTable + i)->pos);
- }
- if (CountSpecifyItem(71049))
- {
- TPacketMyshopPricelistHeader header;
- TItemPriceInfo info;
- header.dwOwnerID = GetPlayerID();
- header.byCount = itemkind.size();
- TEMP_BUFFER buf;
- buf.write(&header, sizeof(header));
- for (auto &it : itemkind)
- {
- 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());
- }
- else if (CountSpecifyItem(50200))
- {
- RemoveSpecifyItem(50200, 1);
- }
- else
- {
- return;
- }
- if (m_pkExchange)
- {
- m_pkExchange->Cancel();
- }
- TPacketGCShopSign p;
- p.bHeader = HEADER_GC_SHOP_SIGN;
- p.dwVID = GetVID();
- strlcpy(p.szSign, c_pszSign, sizeof(p.szSign));
- PacketAround(&p, sizeof(TPacketGCShopSign));
- m_pkMyShop = CShopManager::instance().CreatePCShop(this, pTable, bItemCount);
- if (IsPolymorphed())
- {
- RemoveAffect(AFFECT_POLYMORPH);
- }
- if (GetHorse())
- {
- HorseSummon(false, true);
- }
- else if (GetMountVnum())
- {
- RemoveAffect(AFFECT_MOUNT);
- RemoveAffect(AFFECT_MOUNT_BONUS);
- }
- 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));
- SetPolymorph(GetJob(), true);
- }
- }
- void EncodeMovePacket(TPacketGCMove &pack, DWORD dwVID, BYTE bFunc, UINT uArg, DWORD x, DWORD y, DWORD dwDuration, DWORD dwTime, BYTE bRot)
- {
- pack.bHeader = HEADER_GC_CHARACTER_MOVE;
- pack.bFunc = bFunc;
- pack.uArg = uArg;
- 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);
- //
- auto 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);
- }
- }
- }
- }
- void CHARACTER::EncodeInsertPacket(LPENTITY entity)
- {
- LPDESC d;
- if (!(d = entity->GetDesc()))
- {
- return;
- }
- LPCHARACTER ch = (LPCHARACTER) entity;
- ch->SendGuildName(GetGuild());
- std::function<bool(LPCHARACTER)> f = GetRequirementFunction();
- if (f && !f(ch))
- {
- return;
- }
- uint16_t raceNum = GetRaceNum();
- TPacketGCCharacterAdd pack;
- pack.header = HEADER_GC_CHARACTER_ADD;
- pack.guildID = 0;
- pack.dwVID = m_vid;
- #ifdef ENABLE_FAKE_BUFF
- pack.bType = GetFollowing() ? CHAR_TYPE_NPC : GetCharType();
- #else
- pack.bType = GetCharType();
- #endif
- pack.angle = GetRotation();
- pack.x = GetX();
- pack.y = GetY();
- pack.z = GetZ();
- pack.wRaceNum = raceNum;
- if (IsPet()
- #ifdef ENABLE_NEW_PET_SYSTEM
- || IsNewPet()
- #endif
- #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
- || IsMountSystem()
- #endif
- )
- {
- 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;
- #ifdef ENABLE_FAKE_PC
- if (FakePC_Check())
- {
- pack.bType = CHAR_TYPE_PC;
- pack.wRaceNum = FakePC_GetOwner()->GetRaceNum();
- }
- #endif
- #ifdef ENABLE_FAKE_BUFF
- if (FakeBuff_Check())
- {
- pack.bType = CHAR_TYPE_PC;
- pack.wRaceNum = MAIN_RACE_SHAMAN_W;
- }
- #endif
- 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() || m_bCharType == CHAR_TYPE_NPC
- #ifdef ENABLE_FAKE_PC
- || FakePC_Check()
- #endif
- #ifdef ENABLE_FAKE_BUFF
- || FakeBuff_Check()
- #endif
- )
- {
- TPacketGCCharacterAdditionalInfo addPacket;
- memset(&addPacket, 0, sizeof(TPacketGCCharacterAdditionalInfo));
- addPacket.header = HEADER_GC_CHAR_ADDITIONAL_INFO;
- addPacket.dwVID = m_vid;
- #ifdef ENABLE_SPECULAR_SYSTEM
- for (int i = 0; i < 4; ++i)
- {
- if (GetWear(WEAR_COSTUME_BODY))
- {
- addPacket.bSpecularColor[i] = GetWear(WEAR_COSTUME_BODY) ? GetWear(WEAR_COSTUME_BODY)->GetSpecularColorSingle(i) : 0;
- }
- else
- {
- addPacket.bSpecularColor[i] = GetWear(WEAR_BODY) ? GetWear(WEAR_BODY)->GetSpecularColorSingle(i) : 0;
- }
- #ifdef ENABLE_COSTUME_WEAPON_SYSTEM
- if (GetWear(WEAR_COSTUME_WEAPON))
- {
- addPacket.bSpecularColor[i+4] = GetWear(WEAR_COSTUME_WEAPON) ? GetWear(WEAR_COSTUME_WEAPON)->GetSpecularColorSingle(i) : 0;
- }
- else
- {
- addPacket.bSpecularColor[i+4] = GetWear(WEAR_WEAPON) ? GetWear(WEAR_WEAPON)->GetSpecularColorSingle(i) : 0;
- }
- #else
- addPacket.bSpecularColor[i+4] = GetWear(WEAR_WEAPON) ? GetWear(WEAR_WEAPON)->GetSpecularColorSingle(i) : 0;
- #endif
- addPacket.bSpecularColor[i+8] = GetWear(WEAR_COSTUME_HAIR) ? GetWear(WEAR_COSTUME_HAIR)->GetSpecularColorSingle(i) : 0;
- #ifdef ENABLE_SHOULDER_SASH_SYSTEM
- addPacket.bSpecularColor[i+12] = GetWear(WEAR_COSTUME_SASH) ? GetWear(WEAR_COSTUME_SASH)->GetSpecularColorSingle(i) : 0;
- #endif
- }
- #endif
- addPacket.adwPart[CHR_EQUIPPART_ARMOR] = GetPart(PART_MAIN);
- addPacket.adwPart[CHR_EQUIPPART_WEAPON] = GetPart(PART_WEAPON);
- addPacket.adwPart[CHR_EQUIPPART_HEAD] = GetPart(PART_HEAD);
- addPacket.adwPart[CHR_EQUIPPART_HAIR] = GetPart(PART_HAIR);
- #ifdef ENABLE_SHOULDER_SASH_SYSTEM
- addPacket.adwPart[CHR_EQUIPPART_SASH] = GetPart(PART_SASH);
- #endif
- #ifdef ENABLE_COSTUME_AURA_SYSTEM
- addPacket.adwPart[CHR_EQUIPPART_AURA] = GetPart(PART_AURA);
- #endif
- #ifdef ENABLE_EFFECT_SYSTEM
- addPacket.adwPart[CHR_BODY_EFFECT] = GetPart(BODY_EFFECT);
- addPacket.adwPart[CHR_WEAPON_RIGHT_EFFECT] = GetPart(WEAPON_RIGHT_EFFECT);
- addPacket.adwPart[CHR_WEAPON_LEFT_EFFECT] = GetPart(WEAPON_LEFT_EFFECT);
- #endif
- #ifdef ENABLE_QUIVER_SYSTEM
- LPITEM arrow = GetWear(WEAR_ARROW);
- if (arrow)
- {
- addPacket.dwArrow = arrow->GetVnum();
- }
- else
- {
- addPacket.dwArrow = 0;
- }
- #endif
- #ifdef ENABLE_SKILL_COLOR_SYSTEM
- memcpy(addPacket.dwSkillColor, GetSkillColor(), sizeof(addPacket.dwSkillColor));
- #endif
- addPacket.bPKMode = m_bPKMode;
- addPacket.dwMountVnum = GetMountVnum();
- addPacket.bEmpire = m_bEmpire;
- #ifdef ENABLE_GLOBAL_LANGUAGE
- strcpy(addPacket.szCountry, GetLang().c_str());
- #endif
- #ifdef ENABLE_NEW_PET_SYSTEM
- if (IsPC() || IsNewPet())
- #else
- if (IsPC())
- #endif
- {
- 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:
- strlcpy(addPacket.name, GetName(), sizeof(addPacket.name));
- 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();
- strlcpy(p.szSign, m_stShopSign.c_str(), sizeof(p.szSign));
- 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());
- }
- }
- #ifdef ENABLE_SPECULAR_SYSTEM
- void CHARACTER::UpdatePacket(bool bUnequip)
- #else
- void CHARACTER::UpdatePacket()
- #endif
- {
- if (GetSectree() == NULL)
- {
- return;
- }
- TPacketGCCharacterUpdate pack;
- TPacketGCCharacterUpdate pack2;
- pack.header = HEADER_GC_CHARACTER_UPDATE;
- pack.dwVID = m_vid;
- #ifdef ENABLE_SPECULAR_SYSTEM
- for (int i = 0; i < 4; ++i)
- {
- if (GetWear(WEAR_COSTUME_BODY) && !bUnequip)
- {
- pack.bSpecularColor[i] = GetWear(WEAR_COSTUME_BODY) ? GetWear(WEAR_COSTUME_BODY)->GetSpecularColorSingle(i) : 0;
- }
- else
- {
- pack.bSpecularColor[i] = GetWear(WEAR_BODY) ? GetWear(WEAR_BODY)->GetSpecularColorSingle(i) : 0;
- }
- #ifdef ENABLE_COSTUME_WEAPON_SYSTEM
- if (GetWear(WEAR_COSTUME_WEAPON) && !bUnequip)
- {
- pack.bSpecularColor[i+4] = GetWear(WEAR_COSTUME_WEAPON) ? GetWear(WEAR_COSTUME_WEAPON)->GetSpecularColorSingle(i) : 0;
- }
- else
- {
- pack.bSpecularColor[i+4] = GetWear(WEAR_WEAPON) ? GetWear(WEAR_WEAPON)->GetSpecularColorSingle(i) : 0;
- }
- #else
- pack.bSpecularColor[i+4] = GetWear(WEAR_WEAPON) ? GetWear(WEAR_WEAPON)->GetSpecularColorSingle(i) : 0;
- #endif
- pack.bSpecularColor[i+8] = GetWear(WEAR_COSTUME_HAIR) ? GetWear(WEAR_COSTUME_HAIR)->GetSpecularColorSingle(i) : 0;
- #ifdef ENABLE_SHOULDER_SASH_SYSTEM
- pack.bSpecularColor[i+12] = GetWear(WEAR_COSTUME_SASH) ? GetWear(WEAR_COSTUME_SASH)->GetSpecularColorSingle(i) : 0;
- #endif
- }
- #endif
- pack.adwPart[CHR_EQUIPPART_ARMOR] = GetPart(PART_MAIN);
- pack.adwPart[CHR_EQUIPPART_WEAPON] = GetPart(PART_WEAPON);
- pack.adwPart[CHR_EQUIPPART_HEAD] = GetPart(PART_HEAD);
- pack.adwPart[CHR_EQUIPPART_HAIR] = GetPart(PART_HAIR);
- #ifdef ENABLE_SHOULDER_SASH_SYSTEM
- pack.adwPart[CHR_EQUIPPART_SASH] = GetPart(PART_SASH);
- #endif
- #ifdef ENABLE_COSTUME_AURA_SYSTEM
- pack.adwPart[CHR_EQUIPPART_AURA] = GetPart(PART_AURA);
- #endif
- #ifdef ENABLE_EFFECT_SYSTEM
- pack.adwPart[CHR_BODY_EFFECT] = GetPart(BODY_EFFECT);
- pack.adwPart[CHR_WEAPON_RIGHT_EFFECT] = GetPart(WEAPON_RIGHT_EFFECT);
- pack.adwPart[CHR_WEAPON_LEFT_EFFECT] = GetPart(WEAPON_LEFT_EFFECT);
- #endif
- #ifdef ENABLE_QUIVER_SYSTEM
- LPITEM arrow = GetWear(WEAR_ARROW);
- if (arrow)
- {
- pack.dwArrow = arrow->GetVnum();
- }
- else
- {
- pack.dwArrow = 0;
- }
- #endif
- #ifdef ENABLE_SKILL_COLOR_SYSTEM
- memcpy(pack.dwSkillColor, GetSkillColor(), sizeof(pack.dwSkillColor));
- #endif
- 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.dwLevel = GetLevel();
- pack.bPKMode = m_bPKMode;
- if (GetGuild())
- {
- pack.dwGuildID = GetGuild()->GetID();
- }
- pack.dwMountVnum = GetMountVnum();
- #ifdef ENABLE_GLOBAL_LANGUAGE
- strcpy(pack.szCountry, GetLang().c_str());
- #endif
- pack2 = pack;
- pack2.dwGuildID = 0;
- pack2.sAlignment = 0;
- pack2.dwLevel = 0;
- if (false)
- {
- if (m_bIsObserver != true)
- {
- for (auto &iter : m_map_view)
- {
- LPENTITY pEntity = iter.first;
- if (pEntity != NULL)
- {
- if (pEntity->IsType(ENTITY_CHARACTER))
- {
- 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)
- {
- auto 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() && !IsDoor())
- {
- switch (pos)
- {
- case POS_FIGHTING:
- if (!IsState(m_stateBattle))
- {
- MonsterLog("[BATTLE] Fighting status");
- }
- GotoState(m_stateBattle);
- break;
- default:
- if (!IsState(m_stateIdle))
- {
- MonsterLog("[IDLE] Off state");
- }
- GotoState(m_stateIdle);
- break;
- }
- }
- m_pointsInstant.position = pos;
- }
- void CHARACTER::Save()
- {
- #ifdef ENABLE_FAKE_PC
- if (!GetDesc())
- {
- return;
- }
- #endif
- if (!m_bSkipSave)
- {
- CHARACTER_MANAGER::instance().DelayedSave(this);
- }
- }
- void CHARACTER::CreatePlayerProto(TPlayerTable &tab)
- {
- memset(&tab, 0, sizeof(TPlayerTable));
- if (GetNewName().empty())
- {
- strlcpy(tab.name, GetName(), sizeof(tab.name));
- }
- else
- {
- strlcpy(tab.name, GetNewName().c_str(), sizeof(tab.name));
- }
- strlcpy(tab.ip, GetDesc()->GetHostName(), sizeof(tab.ip));
- 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();
- #ifdef ENABLE_CHAT_COLOR_SYSTEM
- tab.color = GetChatColor();
- #endif
- tab.job = m_points.job;
- tab.part_base = m_pointsInstant.bBasePart;
- tab.skill_group = m_points.skill_group;
- #ifdef ENABLE_GAYA_SYSTEM
- tab.gaya = GetGaya();
- #endif
- #ifdef ENABLE_ZODIAC_TEMPLE_SHOP
- tab.zodiac_point = GetZodiacPoint();
- tab.last_zodiac_point_reward = GetLastZodiacPointReward();
- #endif
- 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];
- }
- thecore_memcpy(tab.parts, m_pointsInstant.parts, sizeof(tab.parts));
- thecore_memcpy(tab.skills, m_pSkillLevels, sizeof(TPlayerSkill) * SKILL_MAX_NUM);
- tab.horse = GetHorseData();
- #ifdef ENABLE_EXTENDED_BATTLE_PASS
- tab.battle_pass_premium_id = GetExtBattlePassPremiumID();
- #endif
- #ifdef __ADMIN_MANAGER__
- tab.chat_ban_count = m_dwChatBanCount;
- #endif
- #ifdef ENABLE_RUNE_SYSTEM
- strlcpy(tab.cAvailableRunes, GetRunes().c_str(), sizeof(tab.cAvailableRunes));
- #endif
- #ifdef ENABLE_BIOLOG_SYSTEM
- tab.m_BiologActualMission = GetBiologMissions();
- tab.m_BiologCollectedItems = GetBiologCollectedItems();
- tab.m_BiologCooldownReminder = GetBiologCooldownReminder();
- tab.m_BiologCooldown = GetBiologCooldown();
- #endif
- }
- 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();
- }
- TMarriage* pMarriage = CMarriageManager::instance().Get(GetPlayerID());
- if (pMarriage)
- {
- pMarriage->Save();
- }
- spActivityHandler activityHandler = GetActivityHandler();
- if (activityHandler)
- {
- activityHandler->Save();
- }
- }
- void CHARACTER::FlushDelayedSaveItem()
- {
- 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");
- #ifdef ENABLE_FAKE_PC
- FakePC_Owner_DespawnAll();
- #endif
- #ifdef ENABLE_DUNGEON_REJOIN
- if(GetMapIndex() >= 10000)
- {
- LPDUNGEON pkDungeon = CDungeonManager::instance().FindByMapIndex(GetMapIndex());
- if(pkDungeon)
- {
- TDungeonRejoinData dng;
- dng.command = DUNGEON_INSERT_PLAYER;
- dng.dungeon.dungeon = pkDungeon->GetId();
- dng.dungeon.index = GetMapIndex();
- dng.dungeon.channel = g_bChannel;
- dng.player.pid = GetPlayerID();
- dng.player.x = GetX();
- dng.player.y = GetY();
- db_clientdesc->DBPacketHeader(HEADER_GD_DUNGEON_REJOIN, 0, sizeof(TDungeonRejoinData));
- db_clientdesc->Packet(&dng, sizeof(TDungeonRejoinData));
- }
- }
- #endif
- if (GetShop())
- {
- GetShop()->RemoveGuest(this);
- SetShop(NULL);
- }
- if (GetArena() != NULL)
- {
- GetArena()->OnDisconnect(GetPlayerID());
- }
- if (GetParty() != NULL)
- {
- GetParty()->UpdateOfflineState(GetPlayerID());
- }
- CMarriageManager::instance().Logout(this);
- #ifdef ENABLE_MULTI_FARM_BLOCK
- //CHARACTER_MANAGER::Instance().CheckMultiFarmAccount(GetDesc() ? GetDesc()->GetHostName() : "", GetPlayerID(),GetName(), false);
- CHARACTER_MANAGER::Instance().RemoveMultiFarm(GetDesc() ? GetDesc()->GetHostName() : "", GetPlayerID(), false);
- #endif
- TPacketGGLogout p;
- p.bHeader = HEADER_GG_LOGOUT;
- strlcpy(p.szName, GetName(), sizeof(p.szName));
- P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGLogout));
- char buf[51];
- snprintf(buf, sizeof(buf), "%s %llu %d %ld %d", inet_ntoa(GetDesc()->GetAddr().sin_addr), GetGold(), g_bChannel, GetMapIndex(), GetAlignment());
- LogManager::instance().CharLog(this, 0, "LOGOUT", "");
- #ifdef __MELEY_LAIR_DUNGEON__
- if (MeleyLair::CMgr::instance().IsMeleyMap(GetMapIndex()))
- {
- MeleyLair::CMgr::instance().Leave(GetGuild(), this, false);
- }
- #endif
- if (m_pWarMap)
- {
- SetWarMap(NULL);
- }
- if (m_pWeddingMap)
- {
- SetWeddingMap(NULL);
- }
- if (GetGuild())
- {
- GetGuild()->LogoutMember(this);
- }
- quest::CQuestManager::instance().LogoutPC(this);
- #ifdef ENABLE_EXTENDED_BATTLE_PASS
- ListExtBattlePassMap::iterator itext = m_listExtBattlePass.begin();
- while (itext != m_listExtBattlePass.end())
- {
- TPlayerExtBattlePassMission* pkMission = *itext++;
- if (!pkMission->bIsUpdated)
- continue;
- db_clientdesc->DBPacket(HEADER_GD_SAVE_EXT_BATTLE_PASS, 0, pkMission, sizeof(TPlayerExtBattlePassMission));
- }
- m_bIsLoadedExtBattlePass = false;
- #endif
- if (GetParty())
- {
- GetParty()->Unlink(this);
- }
- if (IsStun() || IsDead())
- {
- DeathPenalty(0);
- PointChange(POINT_HP, 50 - GetHP());
- }
- if (!CHARACTER_MANAGER::instance().FlushDelayedSave(this))
- {
- SaveReal();
- }
- #ifdef __ENABLE_NEW_OFFLINESHOP__
- offlineshop::GetManager().RemoveSafeboxFromCache(GetPlayerID());
- offlineshop::GetManager().RemoveGuestFromShops(this);
- if(m_pkAuctionGuest)
- {
- m_pkAuctionGuest->RemoveGuest(this);
- }
- if (GetOfflineShop())
- {
- SetOfflineShop(NULL);
- }
- SetShopSafebox(NULL);
- m_pkAuction = NULL;
- m_pkAuctionGuest= NULL;
- m_bIsLookingOfflineshopOfferList = false;
- #endif
- #ifdef ENABLE_BIOLOG_SYSTEM
- if (m_pkBiologManager)
- {
- delete m_pkBiologManager;
- m_pkBiologManager = NULL;
- }
- #endif
- #ifdef ENABLE_BATTLE_PASS
- auto it = m_listBattlePass.begin();
- while (it != m_listBattlePass.end())
- {
- TPlayerBattlePassMission * pkMission = *it++;
- if (!pkMission->bIsUpdated)
- continue;
- db_clientdesc->DBPacket(HEADER_GD_SAVE_BATTLE_PASS, 0, pkMission, sizeof(TPlayerBattlePassMission));
- }
- m_bIsLoadedBattlePass = false;
- #endif
- FlushDelayedSaveItem();
- SaveAffect();
- m_bIsLoadedAffect = false;
- m_bSkipSave = true;
- quest::CQuestManager::instance().DisconnectPC(this);
- CloseSafebox();
- CloseMall();
- #ifdef ENABLE_COSTUME_AURA_SYSTEM
- if (IsAuraRefineWindowOpen())
- {
- AuraRefineWindowClose();
- }
- #endif
- CPVPManager::instance().Disconnect(this);
- CTargetManager::instance().Logout(GetPlayerID());
- MessengerManager::instance().Logout(GetName());
- #ifdef ENABLE_ONLY_ONE_IP_OX
- if (GetMapIndex() == OXEVENT_MAP_INDEX)
- {
- COXEventManager::Instance().RemoveFromAttenderList(GetPlayerID());
- }
- #endif
- #ifdef __ADMIN_MANAGER__
- CAdminManager::instance().OnLogoutPlayer(this);
- #endif
- if (GetDesc())
- {
- GetDesc()->BindCharacter(NULL);
- }
- M2_DESTROY_CHARACTER(this);
- }
- bool CHARACTER::Show(long lMapIndex, long x, long y, long z, bool bShowSpawnMotion)
- {
- 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;
- }
- #ifdef __ADMIN_MANAGER__
- bool bAdminManagerIsOldMap = false;
- bool bAdminManagerNewMap = false;
- if (GetMapIndex() != lMapIndex)
- {
- bAdminManagerNewMap = true;
- if (GetMapIndex() && GetSectree() != NULL)
- {
- bAdminManagerIsOldMap = true;
- }
- }
- #endif
- 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);
- #ifdef __ADMIN_MANAGER__
- if (bAdminManagerNewMap && IsNPC())
- {
- if (bAdminManagerIsOldMap)
- CAdminManager::instance().OnMonsterDestroy(this);
- CAdminManager::instance().OnMonsterCreate(this);
- }
- else if (!bAdminManagerNewMap && IsPC())
- {
- CAdminManager::instance().OnPlayerMove(this);
- }
- #endif
- return true;
- }
- 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)
- {
- auto 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;
- }
- void CHARACTER::MainCharacterPacket()
- {
- const unsigned mapIndex = GetMapIndex();
- const BGMInfo &bgmInfo = CHARACTER_GetBGMInfo(mapIndex);
- 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();
- strlcpy(mainChrPacket.szChrName, GetName(), sizeof(mainChrPacket.szChrName));
- mainChrPacket.fBGMVol = bgmInfo.vol;
- strlcpy(mainChrPacket.szBGMName, bgmInfo.name.c_str(), sizeof(mainChrPacket.szBGMName));
- 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();
- strlcpy(mainChrPacket.szChrName, GetName(), sizeof(mainChrPacket.szChrName));
- strlcpy(mainChrPacket.szBGMName, bgmInfo.name.c_str(), sizeof(mainChrPacket.szBGMName));
- GetDesc()->Packet(&mainChrPacket, sizeof(TPacketGCMainCharacter3_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();
- strlcpy(pack.szName, GetName(), sizeof(pack.szName));
- GetDesc()->Packet(&pack, sizeof(TPacketGCMainCharacter));
- }
- }
- 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_STAMINA] = GetStamina();
- pack.points[POINT_MAX_STAMINA] = GetMaxStamina();
- for (int i = POINT_ST; i < POINT_MAX_NUM; ++i)
- {
- pack.points[i] = GetPoint(i);
- }
- #ifdef ENABLE_RUNE_SYSTEM
- for (int w = 0; w <= 17; ++w)
- {
- BYTE bType = POINT_RUNE_PAGE1_KEYSTONE1 + w;
- pack.points[bType] = GetPoint(bType);
- }
- #endif
- #ifdef ENABLE_GAYA_SYSTEM
- pack.points[POINT_GAYA] = GetGaya();
- #endif
- #ifdef ENABLE_ZODIAC_TEMPLE_SHOP
- pack.points[POINT_ZODIAC] = GetNewUnit();
- pack.points[POINT_ZODIAC] = GetZodiacPoint();
- #endif
- #ifdef ENABLE_EXTENDED_BATTLE_PASS
- pack.points[POINT_BATTLE_PASS_PREMIUM_ID] = GetExtBattlePassPremiumID();
- #endif
- GetDesc()->Packet(&pack, sizeof(TPacketGCPoints));
- TPacketGCGold packGold;
- packGold.header = HEADER_GC_CHARACTER_GOLD;
- packGold.gold = GetGold();
- GetDesc()->Packet(&packGold, sizeof(TPacketGCGold));
- }
- 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;
- #ifdef ENABLE_WOLFMAN
- case MAIN_RACE_WOLFMAN_M:
- m_points.job = MAIN_RACE_WOLFMAN_M;
- break;
- #endif
- 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;
- }
- uint16_t CHARACTER::GetRaceNum() const
- {
- if (m_dwPolymorphRace)
- {
- return (uint16_t)m_dwPolymorphRace;
- }
- if (m_pkMobData)
- {
- return (uint16_t)m_pkMobData->m_table.dwVnum;
- }
- return (uint16_t)m_points.job;
- }
- #ifdef __ADMIN_MANAGER__
- uint16_t CHARACTER::GetRealRaceNum() const
- {
- if (m_pkMobData)
- {
- return (uint16_t)m_pkMobData->m_table.dwVnum;
- }
- return (uint16_t)m_points.job;
- }
- #endif
- 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
- {
- #ifdef ENABLE_FAKE_PC
- if (FakePC_Check())
- {
- return FakePC_GetOwner()->GetJob();
- }
- #endif
- #ifdef ENABLE_FAKE_BUFF
- if (FakeBuff_Check())
- {
- return JOB_SHAMAN;
- }
- #endif
- 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;
- }
- #ifdef ENABLE_FAKE_PC
- bool CHARACTER::IsEnemy() const
- {
- if (IsStone())
- {
- return true;
- }
- if (IsMonster())
- {
- if (FakePC_IsSupporter())
- {
- return false;
- }
- #ifdef ENABLE_FAKE_BUFF
- if (FakeBuff_Check())
- {
- return false;
- }
- #endif
- return true;
- }
- return false;
- }
- bool CHARACTER::IsPurgeable() const
- {
- if (!IsNPC())
- {
- return false;
- }
- if (FakePC_IsSupporter())
- {
- return false;
- }
- if (IsPet())
- {
- return false;
- }
- #ifdef ENABLE_FAKE_BUFF
- if (FakeBuff_Check())
- {
- return false;
- }
- #endif
- #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
- if (IsMountSystem())
- {
- return false;
- }
- #endif
- #ifdef ENABLE_NEW_PET_SYSTEM
- if (IsNewPet())
- {
- return false;
- }
- #endif
- #ifdef ENABLE_HYDRA_DUNGEON
- if (IsNPC())
- {
- if (GetRaceNum() == 20434 || GetRaceNum() == 20436 || GetRaceNum() == 3960 || GetRaceNum() == 3961 || GetRaceNum() == 3962 || GetRaceNum() == 3962 || GetRaceNum() == 3964)
- {
- return false;
- }
- }
- #endif
- return true;
- }
- #endif
- 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;
- }
- #ifdef ENABLE_ZODIAC_TEMPLE_SHOP
- void CHARACTER::SetPZ(long NewUnit)
- {
- m_NewUnit = NewUnit;
- SetPoint(POINT_ZODIAC, NewUnit);
- }
- long CHARACTER::GetPZ() const
- {
- std::unique_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT new_unit FROM account.account WHERE id = '%d';", GetDesc()->GetAccountTable().id));
- if (pMsg->Get()->uiNumRows == 0)
- {
- return 0;
- }
- MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
- DWORD pz = 0;
- str_to_number(pz, row[0]);
- return pz;
- }
- void CHARACTER::SetNewUnit(long NewUnit)
- {
- DBManager::instance().DirectQuery("UPDATE account.account SET new_unit = '%d' WHERE id = '%d';", NewUnit, GetDesc()->GetAccountTable().id);
- m_NewUnit = NewUnit;
- }
- #endif
- void CHARACTER::SetPlayerProto(const TPlayerTable* t)
- {
- if (!GetDesc() || !*GetDesc()->GetHostName())
- {
- sys_err("cannot get desc or hostname");
- }
- else
- {
- SetGMLevel();
- }
- m_bCharType = CHAR_TYPE_PC;
- SetPlayerID(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]);
- #ifdef ENABLE_SHOULDER_SASH_SYSTEM
- SetPart(PART_SASH, t->parts[PART_SASH]);
- #endif
- #ifdef ENABLE_COSTUME_AURA_SYSTEM
- SetPart(PART_AURA, t->parts[PART_AURA]);
- #endif
- #ifdef ENABLE_EFFECT_SYSTEM
- SetPart(BODY_EFFECT, GetOriginalPart(BODY_EFFECT));
- SetPart(WEAPON_RIGHT_EFFECT, GetOriginalPart(WEAPON_RIGHT_EFFECT));
- SetPart(WEAPON_LEFT_EFFECT, GetOriginalPart(WEAPON_LEFT_EFFECT));
- #endif
- m_points.iRandomHP = t->sRandomHP;
- m_points.iRandomSP = t->sRandomSP;
- M2_DELETE_ARRAY(m_pSkillLevels);
- m_pSkillLevels = M2_NEW TPlayerSkill[SKILL_MAX_NUM];
- thecore_memcpy(m_pSkillLevels, t->skills, sizeof(TPlayerSkill) * SKILL_MAX_NUM);
- if (t->lMapIndex >= 10000)
- {
- #ifdef ENABLE_ZODIAC_TEMPLE
- bool zodiak_index = (t->lMapIndex >= 3580000 && t->lMapIndex < 3590000) ? false : true;
- if (zodiak_index)
- {
- m_posWarp.x = t->lExitX;
- m_posWarp.y = t->lExitY;
- m_lWarpMapIndex = t->lExitMapIndex;
- }
- #else
- m_posWarp.x = t->lExitX;
- m_posWarp.y = t->lExitY;
- m_lWarpMapIndex = t->lExitMapIndex;
- #endif
- }
- 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((BYTE)t->job);
- SetLevel(t->level);
- SetExp(t->exp);
- SetGold(t->gold);
- #ifdef ENABLE_CHAT_COLOR_SYSTEM
- SetChatColor(t->color);
- #endif
- #ifdef ENABLE_GAYA_SYSTEM
- SetGaya(t->gaya);
- #endif
- #ifdef ENABLE_ZODIAC_TEMPLE_SHOP
- SetZodiacPoint(t->zodiac_point);
- SetLastZodiacPointReward(t->last_zodiac_point_reward);
- #endif
- #ifdef ENABLE_EXTENDED_BATTLE_PASS
- SetExtBattlePassPremiumID(t->battle_pass_premium_id);
- #endif
- SetMapIndex(t->lMapIndex);
- SetXYZ(t->x, t->y, t->z);
- #ifdef ENABLE_RUNE_SYSTEM
- m_dwRuneString = t->cAvailableRunes;
- size_t pos = 0;
- size_t w = 0;
- std::string s = m_dwRuneString;
- while ((pos = s.find(',')) != std::string::npos)
- {
- SetPoint(POINT_RUNE_PAGE1_KEYSTONE1 + w, stoi(s.substr(0, pos)));
- w++;
- s.erase(0, pos + 1);
- }
- #endif
- ComputePoints();
- SetHP(t->hp);
- SetSP(t->sp);
- SetStamina(t->stamina);
- if (GetHP() <= 0)
- {
- SetHP(1);
- }
- if (!test_server && GetGMLevel() > GM_LOW_WIZARD)
- {
- m_afAffectFlag.Set(AFF_YMIR);
- }
- if (GetLevel() < PK_PROTECT_LEVEL)
- {
- m_bPKMode = PK_MODE_PROTECT;
- }
- SetHorseData(t->horse);
- if (GetHorseLevel() > 0)
- {
- UpdateHorseDataByLogoff(t->logoff_interval);
- }
- thecore_memcpy(m_aiPremiumTimes, t->aiPremiumTimes, sizeof(t->aiPremiumTimes));
- m_dwLogOffInterval = t->logoff_interval;
- m_dwLastAttackTime = t->last_play;
- 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());
- }
- if (m_petSystem)
- {
- m_petSystem->Destroy();
- delete m_petSystem;
- }
- m_petSystem = M2_NEW CPetSystem(this);
- #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
- if (m_MountSystem)
- {
- m_MountSystem->Destroy();
- delete m_MountSystem;
- }
- m_MountSystem = M2_NEW CMountSystem(this);
- #endif
- #ifdef ENABLE_NEW_PET_SYSTEM
- if (m_newpetSystem)
- {
- m_newpetSystem->Destroy();
- delete m_newpetSystem;
- }
- m_newpetSystem = M2_NEW CNewPetSystem(this);
- #endif
- #ifdef __ADMIN_MANAGER__
- m_dwChatBanCount = t->chat_ban_count;
- #endif
- #ifdef ENABLE_BIOLOG_SYSTEM
- if (m_pkBiologManager)
- {
- sys_err("Biolog manager already exist for owner %u %s", GetPlayerID(), GetName());
- delete m_pkBiologManager;
- }
- m_pkBiologManager = M2_NEW CBiologSystem(this);
- SetBiologMissions(t->m_BiologActualMission);
- SetBiologCollectedItems(t->m_BiologCollectedItems);
- SetBiologCooldownReminder(t->m_BiologCooldownReminder);
- SetBiologCooldown(t->m_BiologCooldown);
- #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)
- {
- return 0;
- }
- ch->m_pkMiningEvent = NULL;
- M2_DESTROY_CHARACTER(ch);
- return 0;
- }
- void CHARACTER::SetProto(const CMob* pkMob)
- {
- 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()
- #ifdef ENABLE_HYDRA_DUNGEON
- || GetRaceNum() == 3949
- #endif
- )
- {
- StartWarpNPCEvent();
- }
- CHARACTER_MANAGER::instance().RegisterRaceNumMap(this);
- // CHAOS DUNGEON
- if (GetRaceNum() == 20425)
- {
- m_dwPlayStartTime = get_dword_time() + 120 * 1000;
- }
- 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
- #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
- || IsMountSystem()
- #endif
- )
- {
- 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);
- }
- if (mining::IsVeinOfOre(GetRaceNum()))
- {
- char_event_info* info = AllocEventInfo<char_event_info>();
- info->ch = this;
- m_pkMiningEvent = event_create(kill_ore_load_event, info, PASSES_PER_SEC(number(7 * 60, 15 * 60)));
- }
- if (IsGoto() || IsWarp())
- {
- SetName(GetProtoName());
- }
- }
- 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
- {
- #ifdef ENABLE_HYDRA_DUNGEON
- if (IsDefanceWaweMastAttackMob(GetRaceNum()))
- {
- return m_pkMobData->m_table.dwDamageRange[0] + 10000;
- }
- else
- {
- return m_pkMobData->m_table.dwDamageRange[0];
- }
- #else
- return m_pkMobData->m_table.dwDamageRange[0];
- #endif
- }
- DWORD CHARACTER::GetMobDamageMax() const
- {
- #ifdef ENABLE_HYDRA_DUNGEON
- if (IsDefanceWaweMastAttackMob(GetRaceNum()))
- {
- return m_pkMobData->m_table.dwDamageRange[1] + 10000;
- }
- else
- {
- return m_pkMobData->m_table.dwDamageRange[1];
- }
- #else
- return m_pkMobData->m_table.dwDamageRange[1];
- #endif
- }
- float CHARACTER::GetMobDamageMultiply() const
- {
- float fDamMultiply = GetMobTable().fDamMultiply;
- if (IsBerserk())
- {
- fDamMultiply = fDamMultiply * 2.0f;
- }
- return fDamMultiply;
- }
- DWORD CHARACTER::GetMobDropItemVnum() const
- {
- if (m_pkMobData == NULL)
- {
- return 0;
- }
- 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;
- }
- return m_pkMobData->m_table.bRank;
- }
- uint16_t CHARACTER::GetMobSize() const
- {
- if (!m_pkMobData)
- {
- return 100;
- }
- return m_pkMobData->m_table.wScale;
- }
- DWORD CHARACTER::GetMobSkillRange() const
- {
- if (!m_pkMobData)
- {
- return 70;
- }
- if (m_pkMobData->m_table.dwSkillRange == 0)
- {
- return 70;
- }
- return m_pkMobData->m_table.dwSkillRange;
- }
- uint16_t CHARACTER::GetMobAttackRange() const
- {
- #ifdef ENABLE_FAKE_PC
- if (FakePC_Check())
- {
- LPITEM pkWeapon = GetWear(WEAR_WEAPON);
- if (pkWeapon && pkWeapon->GetType() == WEAPON_BOW)
- {
- return 600;
- }
- else
- {
- return 300;
- }
- }
- #endif
- switch (GetMobBattleType())
- {
- case BATTLE_TYPE_RANGE:
- case BATTLE_TYPE_MAGIC:
- #ifdef ENABLE_HYDRA_DUNGEON
- if (GetRaceNum() == 3960 || GetRaceNum() == 3961 || GetRaceNum() == 3962)
- {
- return m_pkMobData->m_table.wAttackRange + GetPoint(POINT_BOW_DISTANCE) + 4000;
- }
- else
- {
- return m_pkMobData->m_table.wAttackRange + GetPoint(POINT_BOW_DISTANCE);
- }
- #else
- return m_pkMobData->m_table.wAttackRange + GetPoint(POINT_BOW_DISTANCE);
- #endif
- default:
- #ifdef ENABLE_HYDRA_DUNGEON
- if ((GetRaceNum() <= 3955 && GetRaceNum() >= 3950 && GetRaceNum() != 3953))
- {
- return m_pkMobData->m_table.wAttackRange + 300;
- }
- else
- {
- return m_pkMobData->m_table.wAttackRange;
- }
- #else
- return m_pkMobData->m_table.wAttackRange;
- #endif
- }
- }
- BYTE CHARACTER::GetMobBattleType() const
- {
- if (!m_pkMobData)
- {
- return BATTLE_TYPE_MELEE;
- }
- return (m_pkMobData->m_table.bBattleType);
- }
- void CHARACTER::ComputeBattlePoints()
- {
- /*** Here was the function "IsPolymorphed" , now is eliminated and transformation bug is fixed ***/
- if (IsPC()
- #ifdef ENABLE_FAKE_PC
- || FakePC_Check()
- #endif
- )
- {
- SetPoint(POINT_ATT_GRADE, 0);
- SetPoint(POINT_DEF_GRADE, 0);
- SetPoint(POINT_CLIENT_DEF_GRADE, 0);
- #ifdef ENABLE_FAKE_PC
- SetPoint(POINT_MAGIC_ATT_GRADE, 0);
- SetPoint(POINT_MAGIC_DEF_GRADE, 0);
- #else
- SetPoint(POINT_MAGIC_ATT_GRADE, GetPoint(POINT_ATT_GRADE));
- SetPoint(POINT_MAGIC_DEF_GRADE, GetPoint(POINT_DEF_GRADE));
- #endif
- 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;
- #ifdef ENABLE_WOLFMAN
- case JOB_WOLFMAN:
- iStatAtk = (4 * GetPoint(POINT_DX) + 2 * GetPoint(POINT_HT)) / 3;
- break;
- #endif
- default:
- sys_err("invalid job %d", GetJob());
- iStatAtk = (2 * GetPoint(POINT_ST));
- break;
- }
- if (GetMountVnum() && iStatAtk < 2 * GetPoint(POINT_ST))
- {
- iStatAtk = (2 * GetPoint(POINT_ST));
- }
- iAtk += iStatAtk;
- if (GetMountVnum())
- {
- if (GetJob() == JOB_SURA && GetSkillGroup() == 1)
- {
- iAtk += (iAtk * GetHorseLevel()) / 60;
- }
- else
- {
- iAtk += (iAtk * GetHorseLevel()) / 30;
- }
- }
- iAtk += GetPoint(POINT_ATT_GRADE_BONUS);
- PointChange(POINT_ATT_GRADE, iAtk);
- int iShowDef = GetLevel() + GetPoint(POINT_HT);
- int iDef = GetLevel() + (int)(GetPoint(POINT_HT) / 1.25);
- 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));
- }
- }
- #ifdef ENABLE_COSTUME_AURA_SYSTEM
- else if (pkItem && pkItem->GetType() == ITEM_COSTUME && pkItem->GetSubType() == COSTUME_AURA)
- {
- const long c_lLevelSocket = pkItem->GetSocket(ITEM_SOCKET_AURA_CURRENT_LEVEL);
- const long c_lDrainSocket = pkItem->GetSocket(ITEM_SOCKET_AURA_DRAIN_ITEM_VNUM);
- const long c_lBoostSocket = pkItem->GetSocket(ITEM_SOCKET_AURA_BOOST);
- BYTE bCurLevel = (c_lLevelSocket / 100000) - 1000;
- BYTE bBoostIndex = c_lBoostSocket / 100000000;
- TItemTable* pBoosterProto = ITEM_MANAGER::instance().GetTable(ITEM_AURA_BOOST_ITEM_VNUM_BASE + bBoostIndex);
- float fAuraDrainPer = (1.0f * bCurLevel / 10.0f) / 100.0f;
- if (pBoosterProto)
- fAuraDrainPer += 1.0f * pBoosterProto->alValues[ITEM_AURA_BOOST_PERCENT_VALUE] / 100.0f;
- TItemTable* pDrainedItem = NULL;
- if (c_lDrainSocket != 0)
- pDrainedItem = ITEM_MANAGER::instance().GetTable(c_lDrainSocket);
- if (pDrainedItem != NULL && pDrainedItem->bType == ITEM_ARMOR && pDrainedItem->bSubType == ARMOR_SHIELD)
- {
- float fValue = (pDrainedItem->alValues[1] + (2 * pDrainedItem->alValues[5])) * fAuraDrainPer;
- iArmor += static_cast<int>((fValue < 1.0f) ? ceilf(fValue) : truncf(fValue));;
- }
- }
- #endif
- }
- 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);
- PointChange(POINT_DEF_GRADE, iDef + iArmor);
- PointChange(POINT_CLIENT_DEF_GRADE, (iShowDef + iArmor) - GetPoint(POINT_DEF_GRADE));
- 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));
- }
- #ifdef ENABLE_FAKE_PC
- else if (m_pkMobData)
- #else
- else
- #endif
- {
- int iAtt = GetLevel() * 2 + GetPoint(POINT_ST) * 2;
- 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()
- {
- long lStat = GetPoint(POINT_STAT);
- long lStatResetCount = GetPoint(POINT_STAT_RESET_COUNT);
- long lSkillActive = GetPoint(POINT_SKILL);
- long lSkillSub = GetPoint(POINT_SUB_SKILL);
- long lSkillHorse = GetPoint(POINT_HORSE_SKILL);
- long lLevelStep = GetPoint(POINT_LEVEL_STEP);
- long lAttackerBonus = GetPoint(POINT_PARTY_ATTACKER_BONUS);
- long lTankerBonus = GetPoint(POINT_PARTY_TANKER_BONUS);
- long lBufferBonus = GetPoint(POINT_PARTY_BUFFER_BONUS);
- long lSkillMasterBonus = GetPoint(POINT_PARTY_SKILL_MASTER_BONUS);
- long lHasteBonus = GetPoint(POINT_PARTY_HASTE_BONUS);
- long lDefenderBonus = GetPoint(POINT_PARTY_DEFENDER_BONUS);
- long lHPRecovery = GetPoint(POINT_HP_RECOVERY);
- long lSPRecovery = GetPoint(POINT_SP_RECOVERY);
- #ifdef ENABLE_RUNE_SYSTEM
- std::vector<int> vRunes;
- #ifdef ENABLE_FAKE_PC
- if (IsPC() || FakePC_Check())
- #else
- if (IsPC())
- #endif
- {
- for (int w = 0; w <= 17; ++w)
- {
- BYTE bType = POINT_RUNE_PAGE1_KEYSTONE1 + w;
- vRunes.push_back(GetPoint(bType));
- }
- vRunes.push_back(0);
- }
- #endif
- #ifdef ENABLE_ZODIAC_TEMPLE_SHOP
- long lNewUnit = GetNewUnit();
- #endif
- 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));
- #ifdef ENABLE_SHOULDER_SASH_SYSTEM
- SetPart(PART_SASH, GetOriginalPart(PART_SASH));
- #endif
- #ifdef ENABLE_COSTUME_AURA_SYSTEM
- SetPart(PART_AURA, GetOriginalPart(PART_AURA));
- #endif
- 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);
- #ifdef ENABLE_ZODIAC_TEMPLE_SHOP
- SetPoint(POINT_ZODIAC, lNewUnit);
- #endif
- SetPoint(POINT_PC_BANG_EXP_BONUS, 0);
- SetPoint(POINT_PC_BANG_DROP_BONUS, 0);
- #ifdef ENABLE_RUNE_SYSTEM
- #ifdef ENABLE_FAKE_PC
- if (IsPC() || FakePC_Check())
- #else
- if (IsPC())
- #endif
- {
- for (int w = 0; w <= 17; ++w)
- {
- BYTE bType = POINT_RUNE_PAGE1_KEYSTONE1 + w;
- SetPoint(bType, vRunes[w]);
- }
- vRunes.clear();
- }
- #endif
- long iMaxHP, iMaxSP; /*** Fix for long HP/SP (50k +) ***/
- int iMaxStamina;
- #ifdef ENABLE_FAKE_PC
- if (IsPC() || FakePC_Check())
- #else
- if (IsPC())
- #endif
- {
- 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());
- }
- }
- DWORD speed = 250;
- if (GetGMLevel() > GM_PLAYER)
- {
- speed = 400;
- }
- SetPoint(POINT_MOV_SPEED, speed);
- SetPoint(POINT_ATT_SPEED, 150);
- 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 + 250);
- SetPoint(POINT_CASTING_SPEED, m_pkMobData->m_table.sAttackSpeed);
- }
- #ifdef ENABLE_EVENT_MANAGER
- CHARACTER_MANAGER::Instance().CheckBonusEvent(this);
- #endif
- 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);
- }
- }
- }
- }
- #ifndef ENABLE_FAKE_PC
- if (IsPC())
- {
- 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();
- #endif
- if (iMaxHP != GetMaxHP())
- {
- SetRealPoint(POINT_MAX_HP, iMaxHP);
- }
- PointChange(POINT_MAX_HP, 0);
- if (iMaxSP != GetMaxSP())
- {
- SetRealPoint(POINT_MAX_SP, iMaxSP);
- }
- 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)
- {
- #ifdef ENABLE_FAKE_PC
- pItem->ModifyPoints(true, this);
- SET_BIT(m_pointsInstant.dwImmuneFlag, pItem->GetImmuneFlag());
- #else
- pItem->ModifyPoints(true);
- SET_BIT(m_pointsInstant.dwImmuneFlag, GetWear(i)->GetImmuneFlag());
- #endif
- }
- }
- ComputeSkillPoints();
- RefreshAffect();
- #ifndef ENABLE_FAKE_PC
- int iCurHP = this->GetHP();
- int iCurSP = this->GetSP();
- if (IsPC())
- {
- if (this->GetHP() != iCurHP)
- {
- this->PointChange(POINT_HP, iCurHP - this->GetHP());
- }
- if (this->GetSP() != iCurSP)
- {
- this->PointChange(POINT_SP, iCurSP - this->GetSP());
- }
- }
- #endif
- #ifndef ENABLE_COSTUME_PET_SYSTEM
- CPetSystem* pPetSystem = GetPetSystem();
- if (NULL != pPetSystem)
- {
- pPetSystem->RefreshBuff();
- }
- #endif
- #ifdef ENABLE_FAKE_PC
- TMapBuffOnAttrs* pBuffOnAttrMap = &m_map_buff_on_attrs;
- if (FakePC_Check())
- {
- pBuffOnAttrMap = &FakePC_GetOwner()->m_map_buff_on_attrs;
- }
- #endif
- /*** Function For Enable Bonus to Pet System Default From Navicat (item_proto.sql) ***/
- #ifdef ENABLE_FAKE_PC
- for (TMapBuffOnAttrs::iterator it = pBuffOnAttrMap->begin(); it != pBuffOnAttrMap->end(); it++)
- {
- it->second->GiveAllAttributes(this);
- }
- #else
- for (TMapBuffOnAttrs::iterator it = m_map_buff_on_attrs.begin(); it != m_map_buff_on_attrs.end(); it++)
- {
- it->second->GiveAllAttributes();
- }
- #endif
- /*** End function***/
- if (GetHP() > GetMaxHP())
- {
- PointChange(POINT_HP, GetMaxHP() - GetHP());
- }
- if (GetSP() > GetMaxSP())
- {
- PointChange(POINT_SP, GetMaxSP() - GetSP());
- }
- #ifdef ENABLE_FAKE_PC
- ComputeBattlePoints();
- #endif
- UpdatePacket();
- #ifdef ENABLE_FAKE_PC
- if (IsPC())
- {
- FakePC_Owner_ExecFunc(&CHARACTER::ComputePoints);
- }
- #endif
- }
- 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)
- {
- return 0;
- }
- if (!ch->IsPC())
- {
- if (!ch->CanRegenHP())
- {
- return 0;
- }
- if (ch->IsAffectFlag(AFF_POISON)
- #ifdef ENABLE_WOLFMAN
- || ch->IsAffectFlag(AFF_BLEEDING)
- #endif
- )
- {
- return PASSES_PER_SEC(MAX(1, ch->GetMobTable().bRegenCycle));
- }
- DWORD vnum = ch->GetMobTable().dwVnum;
- if (vnum == 2493)
- {
- 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;
- }
- }
- ch->PointChange(POINT_HP, MAX(1, (ch->GetMaxHP() * regenPct) / 100));
- }
- else if (!ch->IsDoor())
- {
- BYTE finalRegenPct = MINMAX(0, ch->GetMobTable().bRegenPercent - ch->GetPenaltyRegenPct(), 100);
- ch->MonsterLog("HP_REGEN +%d", MAX(1, (ch->GetMaxHP() * finalRegenPct) / 100));
- ch->PointChange(POINT_HP, MAX(1, (ch->GetMaxHP() * finalRegenPct) / 100));
- }
- 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);
- return PASSES_PER_SEC(MAX(1, (ch->GetMobTable().bRegenCycle - (val * cnt))));
- }
- }
- }
- return PASSES_PER_SEC(MAX(1, ch->GetMobTable().bRegenCycle + ch->GetPenaltyRegenTime()));
- }
- else
- {
- ch->CheckTarget();
- ch->UpdateKillerMode();
- if (ch->IsAffectFlag(AFF_POISON))
- {
- return 3;
- }
- #ifdef ENABLE_WOLFMAN
- if (ch->IsAffectFlag(AFF_BLEEDING))
- return 3;
- #endif
- int iSec = (get_dword_time() - ch->GetLastMoveTime()) / 3000;
- ch->DistributeSP(ch);
- if (ch->GetMaxHP() <= ch->GetHP())
- {
- return PASSES_PER_SEC(3);
- }
- int iPercent = 0;
- int iAmount = 0;
- {
- iPercent = aiRecoveryPercents[MIN(9, iSec)];
- 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())
- {
- return;
- }
- #ifdef __MELEY_LAIR_DUNGEON__
- if ((MeleyLair::CMgr::instance().IsMeleyMap(GetMapIndex())) && ((GetRaceNum() == (uint16_t) (MeleyLair::STATUE_VNUM)) || ((GetRaceNum() == (uint16_t) (MeleyLair::BOSS_VNUM)))))
- {
- return;
- }
- #endif
- char_event_info* info = AllocEventInfo<char_event_info>();
- info->ch = this;
- int iSec = IsPC() ? 3 : (MAX(1, GetMobTable().bRegenCycle + GetPenaltyRegenTime()));
- 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;
- }
- void CHARACTER::SetRotationToXY(long x, long y)
- {
- SetRotation(GetDegreeFromPositionXY(GetX(), GetY(), x, y));
- }
- bool CHARACTER::CannotMoveByAffect() const
- {
- return (IsAffectFlag(AFF_STUN));
- }
- bool CHARACTER::CanMove() const
- {
- if (CannotMoveByAffect())
- {
- return false;
- }
- if (GetMyShop())
- {
- return false;
- }
- if (IsDead())
- {
- return false;
- }
- return true;
- }
- bool CHARACTER::Sync(long x, long y)
- {
- if (!GetSectree())
- {
- return false;
- }
- /*** Kick fix "back to login" when you ride a mount with slow internet connection or old PC. ***/
- LPSECTREE new_tree = SECTREE_MANAGER::instance().Get(GetMapIndex(), x, y);
- if (!new_tree)
- {
- if (!GetDesc())
- {
- sys_err("No tree %s %ld %ld %ld", GetName(), x, y, GetMapIndex());
- SetNoRewardFlag();
- Dead();
- return false;
- }
- x = GetX();
- y = GetY();
- new_tree = GetSectree();
- return false;
- }
- /*** End ***/
- #ifdef ENABLE_CHECK_MOVESPEED_HACK
- if (IsPC())
- {
- if (GetCShield()->CheckMoveSpeedhack(x, y, get_dword_time(), IsRiding(), GetMoveSpeed()))
- {
- #ifdef ENABLE_SILENT_MODE
- LogManager::instance().HackLog("Movespeed Hack", this);
- #else
- LPDESC d = GetDesc();
- if (d)
- {
- if (d->DelayedDisconnect(3))
- {
- LogManager::instance().HackLog("Movespeed Hack", this);
- }
- }
- #endif
- }
- }
- #endif
- SetRotationToXY(x, y);
- SetXYZ(x, y, 0);
- if (GetDungeon())
- {
- 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();
- const float fDist = DISTANCE_SQRT(id.coord.x - old_id.coord.x, id.coord.y - old_id.coord.y);
- sys_log(0, "SECTREE DIFFER: %s %dx%d was %dx%d dist %.1fm", GetName(), id.coord.x, id.coord.y, old_id.coord.x, old_id.coord.y, fDist);
- }
- new_tree->InsertEntity(this);
- }
- return true;
- }
- void CHARACTER::Stop()
- {
- if (!IsState(m_stateIdle))
- {
- MonsterLog("[IDLE] Starting");
- }
- GotoState(m_stateIdle);
- m_posDest.x = m_posStart.x = GetX();
- m_posDest.y = m_posStart.y = GetY();
- }
- bool CHARACTER::Goto(long x, long y)
- {
- 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() ? "To victim" : "Free");
- if (GetVictim())
- {
- }
- }
- 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)))
- {
- dwMode = GetMotionModeBySubType(pkItem->GetProto()->bSubType);
- }
- return dwMode;
- }
- DWORD CHARACTER::GetMotionModeBySubType(BYTE bSubType) const
- {
- DWORD dwMode = MOTION_MODE_GENERAL;
- switch (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;
- #ifdef ENABLE_WOLFMAN
- case WEAPON_CLAW:
- dwMode = MOTION_MODE_CLAW;
- break;
- #endif
- }
- 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(m_posStart, m_posDest);
- 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();
- }
- bool CHARACTER::Move(long x, long y)
- {
- if (IsPC() && IsDead())
- {
- return false;
- }
- 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, UINT uArg, 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, uArg, x, y, dwDuration, dwTime, iRot == -1 ? (int) GetRotation() / 5 : iRot);
- #ifdef ENABLE_FAKE_PC
- if (FakePC_Check())
- {
- if (pack.bFunc == FUNC_ATTACK)
- {
- DWORD dwTime = get_dword_time();
- pack.bFunc = FUNC_COMBO;
- BYTE bComboIndex = FakePC_ComputeComboIndex();
- if (GetWear(WEAR_WEAPON) && bComboIndex < 3)
- {
- SetComboSequence(bComboIndex + 1);
- }
- else
- {
- SetComboSequence(0);
- }
- SetValidComboInterval(2000);
- SetLastComboTime(dwTime);
- pack.uArg = MOTION_COMBO_ATTACK_1 + bComboIndex;
- }
- }
- #endif
- PacketView(&pack, sizeof(TPacketGCMove), this);
- }
- int CHARACTER::GetRealPoint(BYTE type) const
- {
- #ifdef ENABLE_FAKE_PC
- if (FakePC_Check())
- {
- return FakePC_GetOwner()->GetRealPoint(type);
- }
- #endif
- 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;
- }
- #ifdef ENABLE_FAKE_PC
- if (FakePC_Check())
- {
- const static BYTE abTypesFromOwner[] = {
- POINT_PARTY_ATTACKER_BONUS, POINT_PARTY_TANKER_BONUS, POINT_PARTY_BUFFER_BONUS, POINT_PARTY_SKILL_MASTER_BONUS, POINT_PARTY_HASTE_BONUS, POINT_PARTY_DEFENDER_BONUS,
- };
- const BYTE* pbFirstVal = &(abTypesFromOwner[0]);
- const BYTE* pbLastVal = pbFirstVal + (sizeof(abTypesFromOwner) / sizeof(abTypesFromOwner[0]));
- const BYTE* pbFind = std::find(pbFirstVal, pbLastVal, type);
- if (pbFind != pbLastVal)
- {
- return FakePC_GetOwner()->GetPoint(type);
- }
- }
- #endif
- 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);
- }
- #ifdef __ADMIN_MANAGER__
- int CHARACTER::GetConvPoint(BYTE type) const
- {
- switch (type)
- {
- case POINT_LEVEL:
- return GetLevel();
- break;
- case POINT_EXP:
- return GetExp();
- break;
- case POINT_NEXT_EXP:
- return GetNextExp();
- break;
- case POINT_HP:
- return GetHP();
- break;
- case POINT_MAX_HP:
- return GetMaxHP();
- break;
- case POINT_SP:
- return GetSP();
- break;
- case POINT_MAX_SP:
- return GetMaxSP();
- break;
- case POINT_GOLD:
- return GetGold();
- break;
- case POINT_STAMINA:
- return GetStamina();
- break;
- case POINT_MAX_STAMINA:
- return GetMaxStamina();
- break;
- }
- return GetPoint(type);
- }
- #endif
- 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())
- {
- if (GetGMLevel() > GM_PLAYER)
- {
- limit = 400;
- }
- else
- {
- limit = 250;
- }
- }
- 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;
- if (type == POINT_MOV_SPEED && get_dword_time() < m_dwMoveStartTime + m_dwMoveDuration)
- {
- CalculateMoveDuration();
- }
- }
- unsigned long long CHARACTER::GetAllowedGold() const
- {
- return yang_max;
- }
- void CHARACTER::CheckMaximumPoints()
- {
- if (GetMaxHP() < GetHP())
- {
- PointChange(POINT_HP, GetMaxHP() - GetHP());
- }
- if (GetMaxSP() < GetSP())
- {
- PointChange(POINT_SP, GetMaxSP() - GetSP());
- }
- }
- void CHARACTER::ChangeGold(long long amount)
- {
- const long long nTotalMoney = static_cast<long long>(GetGold()) + static_cast<long long>(amount);
- if (GetAllowedGold() <= nTotalMoney)
- {
- sys_err("[OVERFLOW_GOLD] OriGold %llu AddedGold %llu id %u Name %s ", GetGold(), amount, GetPlayerID(), GetName());
- LogManager::instance().CharLog(this, GetGold() + amount, "OVERFLOW_GOLD", "");
- return;
- }
- SetGold(GetGold() + amount);
- if (GetDesc())
- {
- TPacketGCGoldChange pack;
- pack.header = HEADER_GC_CHARACTER_GOLD_CHANGE;
- pack.dwVID = m_vid;
- if (amount <= 0)
- {
- pack.amount = 0;
- }
- else
- {
- pack.amount = amount;
- }
- pack.value = GetGold();
- GetDesc()->Packet(&pack, sizeof(TPacketGCGoldChange));
- }
- }
- void CHARACTER::PointChange(BYTE type, long long amount, bool bAmount, bool bBroadcast)
- {
- long long val = 0;
- switch (type)
- {
- case POINT_NONE:
- #ifdef ENABLE_BATTLE_PASS
- case POINT_BATTLE_PASS_ID:
- #endif
- 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());
- #ifdef ENABLE_WOLFMAN
- if (GetJob() == JOB_WOLFMAN)
- {
- if (val >= 5)
- {
- if (GetSkillGroup() != 1)
- {
- PointChange(POINT_SKILL, 5);
- SetSkillGroup(1);
- }
- }
- else
- {
- SetSkillGroup(0);
- }
- }
- #endif
- PointChange(POINT_NEXT_EXP, GetNextExp(), false);
- #ifdef ENABLE_FAKE_PC
- if (IsPC() && amount)
- #else
- if (amount)
- #endif
- {
- 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());
- }
- }
- PointsPacket();
- }
- break;
- case POINT_NEXT_EXP:
- val = GetNextExp();
- bAmount = false;
- break;
- case POINT_EXP:
- {
- if (FindAffect(AFFECT_EXP_CURSE) && amount > 0)
- {
- return;
- }
- DWORD exp = GetExp();
- DWORD next_exp = GetNextExp();
- if (amount < 0 && exp <= -amount)
- {
- sys_log(0, "%s - Reduce EXP by %d, CUR EXP: %d (setting to zero)", GetName(), -amount, exp);
- amount = -(long)exp;
- SetExp(0);
- val = GetExp();
- }
- else
- {
- if (gPlayerMaxLevel <= GetLevel())
- {
- return;
- }
- DWORD iExpBalance = 0;
- 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);
- 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() <= g_iStatusPointGetLevelLimit) && (GetLevel() <= gPlayerMaxLevelStats))
- PointChange(POINT_STAT, 1);
- break;
- case 4:
- {
- int iHP = number(JobInitialPoints[GetJob()].hp_per_lv_begin, JobInitialPoints[GetJob()].hp_per_lv_end);
- int iSP = number(JobInitialPoints[GetJob()].sp_per_lv_begin, JobInitialPoints[GetJob()].sp_per_lv_end);
- 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;
- }
- 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();
- amount = MIN(GetMaxHP() - GetHP(), amount);
- SetHP(GetHP() + amount);
- val = GetHP();
- BroadcastTargetPacket();
- if (GetParty() && IsPC() && val != prev_hp)
- {
- GetParty()->SendPartyInfoOneToAll(this);
- }
- }
- break;
- case POINT_SP:
- {
- if (IsDead() || IsStun())
- {
- return;
- }
- amount = MIN(GetMaxSP() - GetSP(), amount);
- SetSP(GetSP() + amount);
- val = GetSP();
- }
- break;
- case POINT_STAMINA:
- {
- if (IsDead() || IsStun())
- {
- return;
- }
- int prev_val = GetStamina();
- amount = MIN(GetMaxStamina() - GetStamina(), amount);
- SetStamina(GetStamina() + amount);
- val = GetStamina();
- if (val == 0)
- {
- SetNowWalking(true);
- }
- else if (prev_val == 0)
- {
- ResetWalking();
- }
- if (amount < 0 && val != 0)
- {
- return;
- }
- }
- break;
- case POINT_MAX_HP:
- {
- SetPoint(type, GetPoint(type) + amount);
- int curMaxHP = GetMaxHP();
- int hp = GetRealPoint(POINT_MAX_HP);
- int add_hp = MIN(3500, hp * GetPoint(POINT_MAX_HP_PCT) / 100);
- add_hp += GetPoint(POINT_MAX_HP);
- add_hp += GetPoint(POINT_PARTY_TANKER_BONUS);
- #ifdef ENABLE_FAKE_PC
- if (FakePC_Check())
- {
- hp += hp;
- add_hp += add_hp;
- }
- #endif
- SetMaxHP(hp + add_hp);
- float fRatio = (float)GetMaxHP() / (float)curMaxHP;
- PointChange(POINT_HP, GetHP() * fRatio - GetHP());
- val = GetMaxHP();
- }
- break;
- case POINT_MAX_SP:
- {
- SetPoint(type, GetPoint(type) + amount);
- int curMaxSP = GetMaxSP();
- int sp = GetRealPoint(POINT_MAX_SP);
- int add_sp = MIN(800, sp * GetPoint(POINT_MAX_SP_PCT) / 100);
- add_sp += GetPoint(POINT_MAX_SP);
- add_sp += GetPoint(POINT_PARTY_SKILL_MASTER_BONUS);
- SetMaxSP(sp + add_sp);
- float fRatio = (float)GetMaxSP() / (float)curMaxSP;
- PointChange(POINT_SP, GetSP() * fRatio - GetSP());
- 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;
- #ifdef ENABLE_GAYA_SYSTEM
- case POINT_GAYA:
- {
- const int64_t nTotalGaya = static_cast<int64_t>(GetGaya()) + static_cast<int64_t>(amount);
- if (GAYA_MAX <= nTotalGaya)
- {
- return;
- }
- SetGaya(GetGaya() + amount);
- val = GetGaya();
- }
- break;
- #endif
- #ifdef ENABLE_ZODIAC_TEMPLE_SHOP
- case POINT_ZODIAC:
- {
- const int64_t AnimeSfers = static_cast<int64_t>(GetNewUnit()) + static_cast<int64_t>(amount);
- if (AnimeSfers > 1151)
- {
- return;
- }
- if (NEW_UNIT_MAX <= AnimeSfers)
- {
- return;
- }
- SetNewUnit(GetNewUnit() + amount);
- val = GetNewUnit();
- }
- break;
- #endif
- 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_MOV_SPEED:
- {
- 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_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:
- case POINT_ATTBONUS_ANIMAL:
- case POINT_ATTBONUS_ORC:
- case POINT_ATTBONUS_MILGYO:
- case POINT_ATTBONUS_UNDEAD:
- case POINT_ATTBONUS_DEVIL:
- case POINT_ATTBONUS_MONSTER:
- case POINT_ATTBONUS_SURA:
- case POINT_ATTBONUS_ASSASSIN:
- case POINT_ATTBONUS_WARRIOR:
- case POINT_ATTBONUS_SHAMAN:
- #ifdef ENABLE_WOLFMAN
- case POINT_ATTBONUS_WOLFMAN:
- #endif
- 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:
- #ifdef ENABLE_WOLFMAN
- case POINT_BLEEDING_PCT:
- case POINT_BLEEDING_REDUCE:
- #endif
- case POINT_CURSE_PCT:
- case POINT_STEAL_HP:
- case POINT_STEAL_SP:
- case POINT_MANA_BURN_PCT:
- case POINT_DAMAGE_SP_RECOVER:
- 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:
- #ifdef ENABLE_WOLFMAN
- case POINT_RESIST_CLAW:
- #endif
- 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:
- case POINT_REFLECT_CURSE:
- case POINT_POISON_REDUCE:
- case POINT_KILL_SP_RECOVER:
- case POINT_KILL_HP_RECOVERY:
- 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:
- #ifdef ENABLE_MAGIC_REDUCTION_SYSTEM
- case POINT_RESIST_MAGIC_REDUCTION:
- #endif
- #ifdef ENABLE_BOSS_AND_STONE_BONUS
- case POINT_ATTBONUS_SEFI:
- case POINT_ATTBONUS_METINE:
- #endif
- case POINT_SKILL_DEFEND_BONUS:
- case POINT_NORMAL_HIT_DEFEND_BONUS:
- #ifdef ENABLE_ELEMENT_ADD
- case POINT_ATTBONUS_ELEC:
- case POINT_ATTBONUS_FIRE:
- case POINT_ATTBONUS_ICE:
- case POINT_ATTBONUS_WIND:
- case POINT_ATTBONUS_EARTH:
- case POINT_ATTBONUS_DARK:
- case POINT_ATTBONUS_INSECT:
- case POINT_ATTBONUS_DESERT:
- case POINT_ATTBONUS_CZ:
- #endif
- #ifdef ENABLE_PENDANT
- case POINT_ATTBONUS_SWORD:
- case POINT_ATTBONUS_TWOHAND:
- case POINT_ATTBONUS_DAGGER:
- case POINT_ATTBONUS_BELL:
- case POINT_ATTBONUS_FAN:
- case POINT_ATTBONUS_BOW:
- #ifdef ENABLE_WOLFMAN
- case POINT_ATTBONUS_CLAW:
- #endif
- case POINT_RESIST_HUMAN:
- case POINT_RESIST_MOUNT_FALL:
- #endif
- #ifdef ENABLE_HYDRA_DUNGEON
- case POINT_ATTBONUS_HYDRA:
- #endif
- SetPoint(type, GetPoint(type) + amount);
- val = GetPoint(type);
- break;
- 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:
- #ifdef ENABLE_WOLFMAN
- case POINT_RESIST_WOLFMAN:
- #endif
- 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:
- case POINT_MAGIC_ATT_BONUS_PER:
- if (GetPoint(type) + amount > 100)
- {
- amount = 100 - GetPoint(type);
- }
- SetPoint(type, GetPoint(type) + amount);
- val = GetPoint(type);
- break;
- 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;
- case POINT_EXP_DOUBLE_BONUS:
- case POINT_GOLD_DOUBLE_BONUS:
- case POINT_ITEM_DROP_BONUS:
- case POINT_POTION_BONUS:
- if (GetPoint(type) + amount > 100)
- {
- amount = 100 - GetPoint(type);
- }
- SetPoint(type, GetPoint(type) + amount);
- val = GetPoint(type);
- break;
- case POINT_IMMUNE_STUN:
- SetPoint(type, GetPoint(type) + amount);
- val = GetPoint(type);
- #ifdef ENABLE_FAKE_PC
- if (GetPoint(POINT_IMMUNE_STUN))
- #else
- if (val)
- #endif
- {
- SET_BIT(m_pointsInstant.dwImmuneFlag, IMMUNE_STUN);
- }
- else
- {
- REMOVE_BIT(m_pointsInstant.dwImmuneFlag, IMMUNE_STUN);
- }
- break;
- case POINT_IMMUNE_SLOW:
- 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:
- 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:
- 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;
- #ifdef ENABLE_RUNE_SYSTEM
- case POINT_RUNE_PAGE1_KEYSTONE1:
- case POINT_RUNE_PAGE1_KEYSTONE2:
- case POINT_RUNE_PAGE1_KEYSTONE3:
- case POINT_RUNE_PAGE2_KEYSTONE1:
- case POINT_RUNE_PAGE2_KEYSTONE2:
- case POINT_RUNE_PAGE2_KEYSTONE3:
- case POINT_RUNE_PAGE3_KEYSTONE1:
- case POINT_RUNE_PAGE3_KEYSTONE2:
- case POINT_RUNE_PAGE3_KEYSTONE3:
- case POINT_RUNE_PAGE1_ROW1:
- case POINT_RUNE_PAGE1_ROW2:
- case POINT_RUNE_PAGE1_ROW3:
- case POINT_RUNE_PAGE2_ROW1:
- case POINT_RUNE_PAGE2_ROW2:
- case POINT_RUNE_PAGE2_ROW3:
- case POINT_RUNE_PAGE3_ROW1:
- case POINT_RUNE_PAGE3_ROW2:
- case POINT_RUNE_PAGE3_ROW3:
- {
- SetPoint(type, amount);
- val = GetPoint(type);
- }
- break;
- #endif
- #ifdef ENABLE_EXTENDED_BATTLE_PASS
- case POINT_BATTLE_PASS_PREMIUM_ID:
- {
- SetExtBattlePassPremiumID(amount);
- val = GetExtBattlePassPremiumID();
- }
- break;
- #endif
- 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())
- {
- struct SPacketGCPointChange pack;
- 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)
- {
- GetDesc()->Packet(&pack, sizeof(struct SPacketGCPointChange));
- }
- else
- {
- PacketAround(&pack, sizeof(pack));
- }
- #ifdef __ADMIN_MANAGER__
- CAdminManager::instance().OnPlayerPointChange(this, type, val);
- #endif
- }
- }
- void CHARACTER::ApplyPoint(BYTE bApplyType, int iVal)
- {
- switch (bApplyType)
- {
- case APPLY_NONE:
- 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:
- {
- 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;
- }
- auto iter = m_SkillDamageBonus.find(bSkillVnum);
- if (iter == m_SkillDamageBonus.end())
- {
- m_SkillDamageBonus.insert(std::make_pair(bSkillVnum, iChange));
- }
- else
- {
- iter->second += iChange;
- }
- }
- break;
- case APPLY_MAX_HP:
- case APPLY_MAX_HP_PCT:
- {
- if (GetMaxHP() == 0) break;
- PointChange(aApplyInfo[bApplyType].bPointType, iVal);
- }
- break;
- case APPLY_MAX_SP:
- case APPLY_MAX_SP_PCT:
- {
- if (GetMaxSP() == 0) break;
- PointChange(aApplyInfo[bApplyType].bPointType, iVal);
- }
- break;
- case APPLY_STR:
- case APPLY_DEX:
- 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:
- case APPLY_ATTBONUS_ASSASSIN:
- case APPLY_ATTBONUS_SURA:
- case APPLY_ATTBONUS_SHAMAN:
- case APPLY_ATTBONUS_MONSTER:
- 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:
- case APPLY_SKILL_DEFEND_BONUS:
- case APPLY_NORMAL_HIT_DEFEND_BONUS:
- 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:
- case APPLY_DEF_GRADE:
- case APPLY_COSTUME_ATTR_BONUS:
- case APPLY_MAGIC_ATTBONUS_PER:
- case APPLY_MELEE_MAGIC_ATTBONUS_PER:
- #ifdef ENABLE_WOLFMAN
- case APPLY_BLEEDING_PCT:
- case APPLY_BLEEDING_REDUCE:
- case APPLY_ATTBONUS_WOLFMAN:
- case APPLY_RESIST_WOLFMAN:
- #endif
- #ifdef ENABLE_MAGIC_REDUCTION_SYSTEM
- case APPLY_RESIST_MAGIC_REDUCTION:
- #endif
- #ifdef ENABLE_BOSS_AND_STONE_BONUS
- case APPLY_ATTBONUS_SEFI:
- case APPLY_ATTBONUS_METINE:
- #endif
- #ifdef ENABLE_ELEMENT_ADD
- case APPLY_ENCHANT_ELECT:
- case APPLY_ENCHANT_FIRE:
- case APPLY_ENCHANT_ICE:
- case APPLY_ENCHANT_WIND:
- case APPLY_ENCHANT_EARTH:
- case APPLY_ENCHANT_DARK:
- case APPLY_ATTBONUS_INSECT:
- case APPLY_ATTBONUS_DESERT:
- case APPLY_ATTBONUS_CZ:
- #endif
- #ifdef ENABLE_PENDANT
- case APPLY_ATTBONUS_SWORD:
- case APPLY_ATTBONUS_TWOHAND:
- case APPLY_ATTBONUS_DAGGER:
- case APPLY_ATTBONUS_BELL:
- case APPLY_ATTBONUS_FAN:
- case APPLY_ATTBONUS_BOW:
- #ifdef ENABLE_WOLFMAN
- case APPLY_ATTBONUS_CLAW:
- #endif
- case APPLY_RESIST_HUMAN:
- case APPLY_RESIST_MOUNT_FALL:
- #endif
- #ifdef ENABLE_HYDRA_DUNGEON
- case APPLY_ATTBONUS_HYDRA:
- #endif
- 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)
- {
- 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;
- }
- ++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());
- }
- #ifdef ENABLE_GLOBAL_LANGUAGE
- void CHARACTER::ChatInfo(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);
- TPacketGCChat pack_chat;
- pack_chat.header = HEADER_GC_CHAT;
- pack_chat.size = sizeof(TPacketGCChat) + len;
- pack_chat.type = CHAT_TYPE_INFO;
- pack_chat.id = 0;
- pack_chat.bEmpire = d->GetEmpire();
- TEMP_BUFFER buf;
- buf.write(&pack_chat, sizeof(TPacketGCChat));
- buf.write(chatbuf, len);
- d->Packet(buf.read_peek(), buf.size());
- }
- void CHARACTER::ChatInfoCond(bool cond, const char * format, ...)
- {
- if (cond)
- {
- 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);
- TPacketGCChat pack_chat;
- pack_chat.header = HEADER_GC_CHAT;
- pack_chat.size = sizeof(TPacketGCChat) + len;
- pack_chat.type = CHAT_TYPE_INFO;
- pack_chat.id = 0;
- pack_chat.bEmpire = d->GetEmpire();
- TEMP_BUFFER buf;
- buf.write(&pack_chat, sizeof(TPacketGCChat));
- buf.write(chatbuf, len);
- d->Packet(buf.read_peek(), buf.size());
- }
- }
- void CHARACTER::ChatInfoTrans(const char * format, ...)
- {
- LPDESC d = GetDesc();
- if (!d || !format)
- return;
- std::string transText = LC_TEXT_TRANS(format, GetLang());
- char chatbuf[CHAT_MAX_LEN + 1];
- va_list args;
- va_start(args, format);
- int32_t len = vsnprintf(chatbuf, sizeof(chatbuf), transText.c_str(), args);
- va_end(args);
- TPacketGCChat pack_chat;
- pack_chat.header = HEADER_GC_CHAT;
- pack_chat.size = sizeof(TPacketGCChat) + len;
- pack_chat.type = CHAT_TYPE_INFO;
- pack_chat.id = 0;
- pack_chat.bEmpire = d->GetEmpire();
- TEMP_BUFFER buf;
- buf.write(&pack_chat, sizeof(TPacketGCChat));
- buf.write(chatbuf, len);
- d->Packet(buf.read_peek(), buf.size());
- }
- void CHARACTER::ChatShoutTrans(const char * lang, const char * format, ...)
- {
- LPDESC d = GetDesc();
- if (!d || !format)
- {
- return;
- }
- char chatbuf_c[CHAT_MAX_LEN + 1];
- int len_c = snprintf(chatbuf_c, sizeof(chatbuf_c), "%s", format);
- TPacketGCChat pack_chat;
- pack_chat.header = HEADER_GC_CHAT;
- pack_chat.size = sizeof(TPacketGCChat) + len_c;
- pack_chat.type = CHAT_TYPE_SHOUT;
- pack_chat.id = 0;
- pack_chat.bEmpire = d->GetEmpire();
- strlcpy(pack_chat.lang, lang, sizeof(pack_chat.lang));
- TEMP_BUFFER buf;
- buf.write(&pack_chat, sizeof(TPacketGCChat));
- buf.write(chatbuf_c, len_c);
- d->Packet(buf.read_peek(), buf.size());
- }
- #endif
- 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 SPacketGCChat pack_chat;
- pack_chat.header = HEADER_GC_CHAT;
- pack_chat.size = sizeof(struct SPacketGCChat) + len;
- pack_chat.type = type;
- pack_chat.id = 0;
- pack_chat.bEmpire = d->GetEmpire();
- TEMP_BUFFER buf;
- buf.write(&pack_chat, sizeof(struct SPacketGCChat));
- buf.write(chatbuf, len);
- d->Packet(buf.read_peek(), buf.size());
- }
- void CHARACTER::mining_take()
- {
- m_pkMiningEvent = NULL;
- }
- void CHARACTER::mining_cancel()
- {
- if (m_pkMiningEvent)
- {
- event_cancel(&m_pkMiningEvent);
- ChatInfoTrans(("MINING_CANCELED"));
- }
- }
- void CHARACTER::mining(LPCHARACTER chLoad)
- {
- if (m_pkMiningEvent)
- {
- mining_cancel();
- return;
- }
- if (!chLoad)
- {
- return;
- }
- if (GetMapIndex() != chLoad->GetMapIndex() || DISTANCE_APPROX(GetX() - chLoad->GetX(), GetY() - chLoad->GetY()) > 1000)
- {
- return;
- }
- if (mining::GetRawOreFromLoad(chLoad->GetRaceNum()) == 0)
- {
- return;
- }
- LPITEM pick = GetWear(WEAR_WEAPON);
- if (!pick || pick->GetType() != ITEM_PICK)
- {
- ChatInfoTrans(("YOU_NEED_A_PICKAXE_FOR_MINING"));
- return;
- }
- if (pick->GetSubType() != 0)
- {
- ChatInfoTrans(("YOU_CANT_USE_THIS_PICKAXE_ON_THIS_VEIN"));
- return;
- }
- if (DISTANCE_APPROX(GetX() - chLoad->GetX(), GetY() - chLoad->GetY()) > 2500)
- {
- return;
- }
- int count = number(5, 15);
- 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);
- }
- void CHARACTER::fishing()
- {
- if (m_pkFishingEvent)
- {
- fishing_take();
- return;
- }
- 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))
- {
- ChatInfoTrans(("YOU_CANNOT_DO_FISHING_HERE"));
- return;
- }
- LPITEM rod = GetWear(WEAR_WEAPON);
- if (!rod || rod->GetType() != ITEM_ROD)
- {
- ChatInfoTrans(("PLEASE_CHOOSE_A_FISHING_ROD"));
- return;
- }
- if (0 == rod->GetSocket(2))
- {
- ChatInfoTrans(("ATTACH_BAIT_FIRST"));
- 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
- {
- ChatInfoTrans(("YOU_CANNOT_GO_FISHING_WITHOUT_A_ROD"));
- }
- 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()
- {
- #ifdef ENABLE_FAKE_PC
- if (FakePC_Check())
- {
- return;
- }
- #endif
- 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("Let's go to the next state");
- }
- }
- 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, DWORD wVal)
- {
- assert(bPartPos < PART_MAX_NUM);
- m_pointsInstant.parts[bPartPos] = wVal;
- }
- DWORD CHARACTER::GetPart(BYTE bPartPos) const
- {
- assert(bPartPos < PART_MAX_NUM);
- #ifdef ENABLE_FAKE_PC
- if(FakePC_Check())
- {
- if(FakePC_GetOwner())
- {
- return FakePC_GetOwner()->GetPart(bPartPos);
- }
- }
- #endif
- #ifdef ENABLE_HIDE_COSTUME_PART
- if (bPartPos == PART_HAIR && GetWear(WEAR_COSTUME_HAIR) && GetQuestFlag("HIDE.COSTUME_HAIR") == 1)
- {
- return 0;
- }
- else if (bPartPos == PART_MAIN && GetWear(WEAR_COSTUME_BODY) && GetQuestFlag("HIDE.COSTUME_BODY") == 1)
- {
- if (const LPITEM pArmor = GetWear(WEAR_BODY))
- {
- return pArmor->GetVnum();
- }
- else
- {
- return 0;
- }
- }
- #ifdef ENABLE_COSTUME_WEAPON_SYSTEM
- else if (bPartPos == PART_WEAPON && GetWear(WEAR_COSTUME_WEAPON) && GetQuestFlag("HIDE.COSTUME_WEAPON") == 1)
- {
- if (const LPITEM pWeapon = GetWear(WEAR_WEAPON))
- {
- return pWeapon->GetVnum();
- }
- else
- {
- return 0;
- }
- }
- #endif
- #ifdef ENABLE_SHOULDER_SASH_SYSTEM
- else if (bPartPos == PART_SASH && GetWear(WEAR_COSTUME_SASH) && GetQuestFlag("HIDE.COSTUME_SASH") == 1)
- {
- return 0;
- }
- #endif
- #endif
- return m_pointsInstant.parts[bPartPos];
- }
- DWORD CHARACTER::GetOriginalPart(BYTE bPartPos) const
- {
- #ifdef ENABLE_FAKE_PC
- if (FakePC_Check())
- {
- return FakePC_GetOwner()->GetOriginalPart(bPartPos);
- }
- #endif
- switch (bPartPos)
- {
- case PART_MAIN:
- #ifdef ENABLE_HIDE_COSTUME_PART
- if (GetWear(WEAR_COSTUME_BODY) && GetQuestFlag("HIDE.COSTUME_BODY") == 1)
- {
- if (const LPITEM pArmor = GetWear(WEAR_BODY))
- {
- return pArmor->GetVnum();
- }
- }
- #endif
- if (!IsPC())
- {
- return GetPart(PART_MAIN);
- }
- else
- {
- return m_pointsInstant.bBasePart;
- }
- case PART_HAIR:
- #ifdef ENABLE_HIDE_COSTUME_PART
- if (GetWear(WEAR_COSTUME_HAIR) && GetQuestFlag("HIDE.COSTUME_HAIR") == 1)
- {
- return 0;
- }
- #endif
- return GetPart(PART_HAIR);
- #ifdef ENABLE_SHOULDER_SASH_SYSTEM
- case PART_SASH:
- #ifdef ENABLE_HIDE_COSTUME_PART
- if (GetWear(WEAR_COSTUME_SASH) && GetQuestFlag("HIDE.COSTUME_SASH") == 1)
- {
- return 0;
- }
- #endif
- return GetPart(PART_SASH);
- #endif
- #ifdef ENABLE_COSTUME_WEAPON_SYSTEM
- case PART_WEAPON:
- #ifdef ENABLE_HIDE_COSTUME_PART
- if (GetWear(WEAR_COSTUME_WEAPON) && GetQuestFlag("HIDE.COSTUME_WEAPON") == 1)
- {
- if (const LPITEM pWeapon = GetWear(WEAR_WEAPON))
- {
- return pWeapon->GetVnum();
- }
- }
- #endif
- return GetWear(WEAR_COSTUME_WEAPON) ? GetPart(PART_WEAPON) : 0;
- #endif
- #ifdef ENABLE_EFFECT_SYSTEM
- case BODY_EFFECT:
- return GetPart(BODY_EFFECT);
- case WEAPON_RIGHT_EFFECT:
- return GetPart(WEAPON_RIGHT_EFFECT);
- case WEAPON_LEFT_EFFECT:
- return GetPart(WEAPON_LEFT_EFFECT);
- #endif
- default:
- return 0;
- }
- }
- BYTE CHARACTER::GetCharType() const
- {
- return m_bCharType;
- }
- bool CHARACTER::SetSyncOwner(LPCHARACTER ch, bool bRemoveFromList)
- {
- if (IS_SET(m_pointsInstant.dwAIFlag, AIFLAG_NOMOVE))
- {
- return false;
- }
- if (ch!=NULL)
- {
- if (!battle_is_attackable(ch, this))
- {
- SendDamagePacket(ch, 0, DAMAGE_BLOCK);
- return false;
- }
- }
- 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());
- }
- m_pkChrSyncOwner = NULL;
- }
- else
- {
- if (!IsSyncOwner(ch))
- {
- return false;
- }
- if (DISTANCE_APPROX(GetX() - ch->GetX(), GetY() - ch->GetY()) > 250)
- {
- sys_log(1, "SetSyncOwner distance over than 250 %s %s", GetName(), ch->GetName());
- 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);
- 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();
- }
- 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);
- }
- };
- void CHARACTER::ClearSync()
- {
- SetSyncOwner(NULL);
- 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;
- }
- 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() && !pkParty)
- {
- SetDungeon(NULL);
- }
- #ifdef ENABLE_ZODIAC_TEMPLE
- if (m_pkZodiac && IsPC() && !pkParty)
- {
- SetZodiac(NULL);
- }
- #endif
- 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();
- }
- }
- EVENTINFO(TPartyJoinEventInfo)
- {
- DWORD dwGuestPID;
- DWORD dwLeaderPID;
- 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)
- {
- ChatInfoTrans(("__GROUP__THIS_REQUEST_CAN_NOT_BE_CONSIDERED"));
- 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:
- ChatInfoTrans(("THIS_COMMAND_CAN_NOT_BE_USED"));
- return false;
- case PERR_DIFFEMPIRE:
- ChatInfoTrans(("__GROUP__YOU_CAN_NOT_CREATE_OR_INVITE_SOMEONE_FROM_DIFFERENT_KINGDOM"));
- return false;
- case PERR_DUNGEON:
- ChatInfoTrans(("__GROUP__YOU_CAN_NOT_CREATE_OR_INVITE_SOMEONE_IN_A_GROUP_TO_BE_IN_DUNGEON"));
- return false;
- case PERR_OBSERVER:
- ChatInfoTrans(("__GROUP__YOU_CAN_NOT_SEND_A_GROUP_INVITATION_AS_SPECTATOR"));
- return false;
- case PERR_LVBOUNDARY:
- ChatInfoTrans(("__GROUP__YOU_CAN_NOT_ENTER_IN_THIS_GROUP_THE_LEVEL_DIFFERENCE_IS_TOO_HIGH"));
- return false;
- case PERR_LOWLEVEL:
- ChatInfoTrans(("__GROUP__YOU_CAN_DO_THIS_BECAUSE_YOU_ARE_30_HIGHER_LEVELS"));
- return false;
- case PERR_HILEVEL:
- ChatInfoTrans(("__GROUP__YOU_CAN_DO_THIS_BECAUSE_YOU_ARE_30_HIGHER_LEVELS"));
- return false;
- case PERR_ALREADYJOIN:
- return false;
- case PERR_PARTYISFULL:
- ChatInfoTrans(("__GROUP__YOU_CAN_NOT_INVITE_OTHER_PLAYER_IN_GROUP"));
- 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());
- ChatInfoTrans(("__GROUP__%s_SENT_A_JOIN_GRUP_REQUEST"), 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->ChatInfoTrans(("__GROUP__IT_BELONGS_TO_SOMEONE_ELSE"));
- }
- else
- {
- if (GetPlayerID() != GetParty()->GetLeaderPID())
- {
- return;
- }
- PartyJoinErrCode errcode = IsPartyJoinableCondition(this, member);
- switch (errcode)
- {
- case PERR_NONE: member->PartyJoin(this); return;
- case PERR_SERVER: member->ChatInfoTrans(("THIS_COMMAND_CAN_NOT_BE_USED")); break;
- case PERR_DUNGEON: member->ChatInfoTrans(("__GROUP__YOU_CAN_NOT_CREATE_OR_INVITE_SOMEONE_IN_A_GROUP_TO_BE_IN_DUNGEON")); break;
- case PERR_OBSERVER: member->ChatInfoTrans(("__GROUP__YOU_CAN_NOT_SEND_A_GROUP_INVITATION_AS_SPECTATOR")); break;
- case PERR_LVBOUNDARY: member->ChatInfoTrans(("__GROUP__YOU_CAN_NOT_ENTER_IN_THIS_GROUP_THE_LEVEL_DIFFERENCE_IS_TOO_HIGH")); break;
- case PERR_LOWLEVEL: member->ChatInfoTrans(("__GROUP__YOU_CAN_DO_THIS_BECAUSE_YOU_ARE_30_HIGHER_LEVELS")); break;
- case PERR_HILEVEL: member->ChatInfoTrans(("__GROUP__YOU_CAN_DO_THIS_BECAUSE_YOU_ARE_30_HIGHER_LEVELS")); break;
- case PERR_ALREADYJOIN: break;
- case PERR_PARTYISFULL:
- {
- ChatInfoTrans(("__GROUP__YOU_CAN_NOT_INVITE_OTHER_PLAYER_IN_GROUP"));
- member->ChatInfoTrans(("__GROUP__THE_USER_LIMIT_HAS_BEEN_REACHED"));
- break;
- }
- default: sys_err("Do not process party join error(%d)", errcode);
- }
- }
- member->ChatPacket(CHAT_TYPE_COMMAND, "PartyRequestDenied");
- }
- 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())
- {
- ChatInfoTrans(("__GROUP__YOU_DO_NOT_HAVE_PERMISION_TO_INVITE_ANOTHER_MEMBERS"));
- return;
- }
- else if (pchInvitee->IsBlockMode(BLOCK_PARTY_INVITE))
- {
- ChatInfoTrans(("__GROUP__THE_GROUP_%s_HAS_BEEN_INVITTION_BLOCKED"), pchInvitee->GetName());
- return;
- }
- else if (CArenaManager::instance().IsArenaMap (pchInvitee->GetMapIndex()))
- {
- ChatInfoTrans(("__GROUP__YOU_DO_NOT_HAVE_PERMISION_TO_MAKE_A_GROUP_OR_REQUEST_A_INVITATION_HERE"));
- return;
- }
- PartyJoinErrCode errcode = IsPartyJoinableCondition(this, pchInvitee);
- switch (errcode)
- {
- case PERR_NONE:
- break;
- case PERR_SERVER:
- ChatInfoTrans(("THIS_COMMAND_CAN_NOT_BE_USED"));
- return;
- case PERR_DIFFEMPIRE:
- ChatInfoTrans(("__GROUP__YOU_CAN_NOT_CREATE_OR_INVITE_SOMEONE_FROM_DIFFERENT_KINGDOM"));
- return;
- case PERR_DUNGEON:
- ChatInfoTrans(("__GROUP__YOU_CAN_NOT_CREATE_OR_INVITE_SOMEONE_IN_A_GROUP_TO_BE_IN_DUNGEON"));
- return;
- case PERR_OBSERVER:
- ChatInfoTrans(("__GROUP__YOU_CAN_NOT_SEND_A_GROUP_INVITATION_AS_SPECTATOR"));
- return;
- case PERR_LVBOUNDARY:
- ChatInfoTrans(("__GROUP__YOU_CAN_NOT_ENTER_IN_THIS_GROUP_THE_LEVEL_DIFFERENCE_IS_TOO_HIGH"));
- return;
- case PERR_LOWLEVEL:
- ChatInfoTrans(("__GROUP__YOU_CAN_DO_THIS_BECAUSE_YOU_ARE_30_HIGHER_LEVELS"));
- return;
- case PERR_HILEVEL:
- ChatInfoTrans(("__GROUP__YOU_CAN_DO_THIS_BECAUSE_YOU_ARE_30_HIGHER_LEVELS"));
- return;
- case PERR_ALREADYJOIN:
- ChatInfoTrans(("__GROUP__%s_IS_ALREADY_JOIN_IN_ANOTHER_GROUP"), pchInvitee->GetName());
- return;
- case PERR_PARTYISFULL:
- ChatInfoTrans(("__GROUP__YOU_CAN_NOT_INVITE_OTHER_PLAYER_IN_GROUP"));
- return;
- default:
- sys_err("Do not process party join error(%d)", errcode);
- return;
- }
- if (m_PartyInviteEventMap.end() != m_PartyInviteEventMap.find(pchInvitee->GetPlayerID()))
- {
- return;
- }
- 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))));
- TPacketGCPartyInvite p;
- p.header = HEADER_GC_PARTY_INVITE;
- p.leader_vid = GetVID();
- pchInvitee->GetDesc()->Packet(&p, sizeof(p));
- }
- void CHARACTER::PartyInviteAccept(LPCHARACTER pchInvitee)
- {
- auto 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())
- {
- ChatInfoTrans(("__GROUP__YOU_DO_NOT_HAVE_PERMISION_TO_INVITE_ANOTHER_MEMBERS"));
- return;
- }
- PartyJoinErrCode errcode = IsPartyJoinableMutableCondition(this, pchInvitee);
- switch (errcode)
- {
- case PERR_NONE:
- break;
- case PERR_SERVER:
- pchInvitee->ChatInfoTrans(("THIS_COMMAND_CAN_NOT_BE_USED"));
- return;
- case PERR_DUNGEON:
- pchInvitee->ChatInfoTrans(("THE_GROUP_CAN_NOT_RESPOND_TO_A_REQUEST_WHILE_IN_A_DUNGEON"));
- return;
- case PERR_OBSERVER:
- pchInvitee->ChatInfoTrans(("__GROUP__YOU_CAN_NOT_SEND_A_GROUP_INVITATION_AS_SPECTATOR"));
- return;
- case PERR_LVBOUNDARY:
- pchInvitee->ChatInfoTrans(("__GROUP__YOU_CAN_NOT_ENTER_IN_THIS_GROUP_THE_LEVEL_DIFFERENCE_IS_TOO_HIGH"));
- return;
- case PERR_LOWLEVEL:
- pchInvitee->ChatInfoTrans(("__GROUP__YOU_CAN_DO_THIS_BECAUSE_YOU_ARE_30_HIGHER_LEVELS"));
- return;
- case PERR_HILEVEL:
- pchInvitee->ChatInfoTrans(("__GROUP__YOU_CAN_DO_THIS_BECAUSE_YOU_ARE_30_HIGHER_LEVELS"));
- return;
- case PERR_ALREADYJOIN:
- pchInvitee->ChatInfoTrans(("__GROUP__IS_ALREADY_JOIN_IN_ANOTHER_GROUP"));
- return;
- case PERR_PARTYISFULL:
- ChatInfoTrans(("__GROUP__YOU_CAN_NOT_INVITE_OTHER_PLAYER_IN_GROUP"));
- pchInvitee->ChatInfoTrans(("__GROUP__THE_USER_LIMIT_HAS_BEEN_REACHED"));
- return;
- default:
- sys_err("ignore party join error(%d)", errcode);
- return;
- }
- 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)
- {
- auto 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)
- {
- ChatInfoTrans(("__GROUP__THE_INVITATION_WAS_REJECTED"), pchInvitee->GetName());
- }
- }
- void CHARACTER::PartyJoin(LPCHARACTER pLeader)
- {
- pLeader->ChatInfoTrans(("%s_JOINED_THE_GROUP"), GetName());
- ChatInfoTrans(("YOU_JOINED_THE_%s_GROUP"), 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;
- 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 (!__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;
- }
- 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);
- }
- }
- #ifdef ENABLE_FAKE_PC
- else if (IsEnemy())
- #else
- else if (IsMonster() || IsStone())
- #endif
- {
- 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);
- }
- }
- #ifdef ENABLE_FAKE_PC
- else if (IsEnemy())
- #else
- else if (IsMonster() || IsStone())
- #endif
- {
- m_pkDungeon->IncMonster();
- }
- }
- }
- #ifdef ENABLE_ZODIAC_TEMPLE
- void CHARACTER::SetZodiac(LPZODIAC pkZodiac)
- {
- if (pkZodiac && m_pkZodiac)
- {
- sys_err("%s is trying to reassigning zodiac (current %p, new party %p)", GetName(), get_pointer(m_pkZodiac), get_pointer(pkZodiac));
- }
- if (m_pkZodiac == pkZodiac)
- {
- return;
- }
- if (m_pkZodiac)
- {
- if (IsPC())
- {
- if (GetParty())
- {
- m_pkZodiac->DecPartyMember(GetParty(), this);
- }
- else
- {
- m_pkZodiac->DecMember(this);
- }
- }
- else if (IsMonster() || IsStone())
- {
- m_pkZodiac->DecMonster();
- }
- }
- m_pkZodiac = pkZodiac;
- if (pkZodiac)
- {
- sys_log(0, "%s ZODIAC set to %p, PARTY is %p", GetName(), get_pointer(pkZodiac), get_pointer(m_pkParty));
- if (IsPC())
- {
- if (GetParty())
- {
- m_pkZodiac->IncPartyMember(GetParty(), this);
- }
- else
- {
- m_pkZodiac->IncMember(this);
- }
- }
- else if (IsMonster() || IsStone())
- {
- m_pkZodiac->IncMonster();
- }
- }
- }
- #endif
- 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(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)
- {
- #ifdef ENABLE_FAKE_PC
- if (IsPC())
- {
- FakePC_Owner_ResetAfkEvent();
- }
- #endif
- m_dwLastMoveTime = get_dword_time();
- #ifdef ENABLE_FAKE_BUFF
- LPCHARACTER clone = FakeBuff_Owner_GetSpawn();
- LPCHARACTER character = this;
- if (clone)
- {
- float follow_distance = 300.0f;
- float run_distance = 900.0f;
- float respawn_distance = 4000.f;
- int approach = 200;
- long character_x_pos = character->GetX();
- long character_y_pos = character->GetY();
- long clone_x_pos = clone->GetX();
- long clone_y_pos = clone->GetY();
- float distance = DISTANCE_APPROX(clone_x_pos - character_x_pos, clone_y_pos - character_y_pos);
- if (distance >= respawn_distance)
- {
- float character_rotation = character->GetRotation() * 3.141592f / 180.f;
- float fx = -approach * cos(character_rotation);
- float fy = -approach * sin(character_rotation);
- if (!clone->Show(character->GetMapIndex(), character_x_pos + fx, character_y_pos + fy)) {}
- }
- if (distance >= follow_distance)
- {
- clone->SetNowWalking(distance >= run_distance ? false : true);
- if (distance <= approach)
- return;
- clone->SetRotationToXY(character_x_pos, character_y_pos);
- float fx, fy;
- float distance_to_go = distance - approach;
- GetDeltaByDegree(clone->GetRotation(), distance_to_go, &fx, &fy);
- if (!clone->Goto((int)(clone_x_pos + fx + 0.5f), (int)(clone_y_pos + fy + 0.5f)))
- {
- return;
- }
- clone->SendMovePacket(FUNC_WAIT, 0, 0, 0, 0, 0);
- }
- else
- {
- clone->SendMovePacket(FUNC_WAIT, 0, 0, 0, 0);
- }
- }
- #endif
- 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();
- }
- }
- mining_cancel();
- #ifdef ENABLE_PURGE_MOBS_IN_SAFEZONE
- #if defined(ENABLE_FAKE_PC) || defined(ENABLE_FAKE_BUFF)
- auto IsFakes = (GetRaceNum() >= MAIN_RACE_MOB_WARRIOR_M && GetRaceNum() <= MAIN_RACE_MOB_MAX_NUM);
- #endif
- SECTREE * sectree = GetSectree();
- if (sectree && sectree->IsAttr(GetX(), GetY(), ATTR_BANPK)
- && IsMonster()
- #if defined(ENABLE_FAKE_PC) || defined(ENABLE_FAKE_BUFF)
- && !IsFakes
- #endif
- )
- {
- M2_DESTROY_CHARACTER(this);
- }
- #endif
- #ifdef __ADMIN_MANAGER__
- if (IsPC())
- CAdminManager::instance().OnPlayerMove(this);
- else
- CAdminManager::instance().OnMonsterMove(this);
- #endif
- }
- void CHARACTER::OnClick(LPCHARACTER pkCharClicking)
- {
- if (!pkCharClicking)
- {
- 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(), pkCharClicking->GetName());
- #ifdef __MELEY_LAIR_DUNGEON__
- if ((IsNPC()) && (GetRaceNum() == (uint16_t) (MeleyLair::GATE_VNUM)) && (MeleyLair::CMgr::instance().IsMeleyMap (pkCharClicking->GetMapIndex())))
- {
- MeleyLair::CMgr::instance().Start (pkCharClicking, pkCharClicking->GetGuild());
- return;
- }
- #endif
- #ifdef ENABLE_ZODIAC_TEMPLE
- if (pkCharClicking != this && IsPC() && pkCharClicking->IsPC() && IsPolymorphed() && (GetMapIndex() >= 3580000 && GetMapIndex() < 3590000) && (pkCharClicking->GetMapIndex() >= 3580000 && pkCharClicking->GetMapIndex() < 3590000))
- {
- if (GetPolymorphVnum() >= 20470 && GetPolymorphVnum() <= 20481)
- {
- SetPolymorph(0);
- return;
- }
- }
- #endif
- if (pkCharClicking->GetMyShop() && pkCharClicking != this)
- {
- sys_err("OnClick Fail (%s->%s) - pc has shop", pkCharClicking->GetName(), GetName());
- return;
- }
- if (pkCharClicking->GetExchange())
- {
- if (test_server)
- {
- sys_err("OnClick Fail (%s->%s) - pc is exchanging", pkCharClicking->GetName(), GetName());
- }
- return;
- }
- if (IsPC())
- {
- if (!CTargetManager::instance().GetTargetInfo(pkCharClicking->GetPlayerID(), TARGET_TYPE_VID, GetVID()))
- {
- if (GetMyShop())
- {
- if (pkCharClicking->IsDead())
- {
- return;
- }
- if (pkCharClicking == this)
- {
- if ((GetExchange() || IsOpenSafebox() || GetShopOwner()) || IsCubeOpen()
- #ifdef ENABLE_COSTUME_AURA_SYSTEM
- || IsAuraRefineWindowOpen()
- #endif
- )
- {
- pkCharClicking->ChatInfoTrans(("YOU_CAN_NOT_OPEN_A_SHOP_WITH_ANOTHER_SHOP_OPEN"));
- return;
- }
- }
- else
- {
- if ((pkCharClicking->GetExchange() || pkCharClicking->IsOpenSafebox() || pkCharClicking->GetMyShop() || pkCharClicking->GetShopOwner()) || pkCharClicking->IsCubeOpen()
- #ifdef ENABLE_COSTUME_AURA_SYSTEM
- || pkCharClicking->IsAuraRefineWindowOpen()
- #endif
- )
- {
- pkCharClicking->ChatInfoTrans(("YOU_CAN_NOT_OPEN_A_SHOP_WITH_ANOTHER_SHOP_OPEN"));
- return;
- }
- if ((GetExchange() || IsOpenSafebox() || IsCubeOpen())
- #ifdef ENABLE_COSTUME_AURA_SYSTEM
- || IsAuraRefineWindowOpen()
- #endif
- )
- {
- pkCharClicking->ChatInfoTrans(("THIS_PLAYER_ALREADY_TRADE"));
- return;
- }
- }
- if (pkCharClicking->GetShop())
- {
- pkCharClicking->GetShop()->RemoveGuest(pkCharClicking);
- pkCharClicking->SetShop(NULL);
- }
- GetMyShop()->AddGuest(pkCharClicking, GetVID(), false);
- pkCharClicking->SetShopOwner(this);
- return;
- }
- if (test_server)
- {
- sys_err("%s.OnClickFailure(%s) - target is PC", pkCharClicking->GetName(), GetName());
- }
- return;
- }
- }
- pkCharClicking->SetQuestNPCID(GetVID());
- if (quest::CQuestManager::instance().Click(pkCharClicking->GetPlayerID(), this))
- {
- return;
- }
- if (!IsPC())
- {
- if (!m_triggerOnClick.pFunc)
- {
- return;
- }
- m_triggerOnClick.pFunc(this, pkCharClicking);
- }
- }
- BYTE CHARACTER::GetGMLevel(bool bIgnoreTestServer) const
- {
- if (bIgnoreTestServer && IsPC())
- return GM::get_level(GetName(), GetDesc()->GetAccountTable().login, true);
- 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()->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())
- {
- 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;
- p.dwActualHP = 0;
- p.dwMaxHP = 0;
- #ifdef ENABLE_ELEMENT_TARGET
- p.bElement = 0;
- #endif
- auto 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;
- }
- 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();
- #ifdef ENABLE_HIDE_COSTUME_PART
- p.bCostumeHide[ECostumePartTypes::HIDE_COSTUME_BODY] = m_pkChrTarget->GetQuestFlag("HIDE.COSTUME_BODY");
- p.bCostumeHide[ECostumePartTypes::HIDE_COSTUME_HAIR] = m_pkChrTarget->GetQuestFlag("HIDE.COSTUME_HAIR");
- #ifdef ENABLE_COSTUME_WEAPON_SYSTEM
- p.bCostumeHide[ECostumePartTypes::HIDE_COSTUME_WEAPON] = m_pkChrTarget->GetQuestFlag("HIDE.COSTUME_WEAPON");
- #endif
- #ifdef ENABLE_SHOULDER_SASH_SYSTEM
- p.bCostumeHide[ECostumePartTypes::HIDE_COSTUME_SASH] = m_pkChrTarget->GetQuestFlag("HIDE.COSTUME_SASH");
- #endif
- #endif
- #ifdef ENABLE_ELEMENT_TARGET
- if (m_pkChrTarget->IsPC())
- {
- LPITEM pkItem;
- pkItem = m_pkChrTarget->GetWear(WEAR_PENDANT);
- if (pkItem && (pkItem->GetVnum() >= 9600 && pkItem->GetVnum() <= 9800))
- {
- p.bElement = 2;
- }
- else if (pkItem && (pkItem->GetVnum() >= 9830 && pkItem->GetVnum() <= 10030))
- {
- p.bElement = 3;
- }
- else if (pkItem && (pkItem->GetVnum() >= 10060 && pkItem->GetVnum() <= 10260))
- {
- p.bElement = 5;
- }
- else if (pkItem && (pkItem->GetVnum() >= 10290 && pkItem->GetVnum() <= 10490))
- {
- p.bElement = 6;
- }
- else if (pkItem && (pkItem->GetVnum() >= 10520 && pkItem->GetVnum() <= 10720))
- {
- p.bElement = 4;
- }
- else if (pkItem && (pkItem->GetVnum() >= 10750 && pkItem->GetVnum() <= 10950))
- {
- p.bElement = 1;
- }
- else
- {
- p.bElement = 0;
- }
- }
- #endif
- if ((m_pkChrTarget->GetMaxHP() <= 0))
- {
- p.bHPPercent = 0;
- p.dwActualHP = 0;
- p.dwMaxHP = 0;
- }
- else if (m_pkChrTarget->IsPC() && !m_pkChrTarget->IsPolymorphed())
- {
- p.bHPPercent = MINMAX (0, (m_pkChrTarget->GetHP()* 100) / m_pkChrTarget->GetMaxHP(), 100);
- p.dwActualHP = m_pkChrTarget->GetHP();
- p.dwMaxHP = m_pkChrTarget->GetMaxHP();
- }
- 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)
- {
- p.bHPPercent = MINMAX(0, iHorseHealth * 100 / iHorseMaxHealth, 100);
- p.dwActualHP = 100;
- p.dwMaxHP = 100;
- }
- else
- {
- p.bHPPercent = 100;
- p.dwActualHP = 100;
- p.dwMaxHP = 100;
- }
- }
- else
- {
- p.bHPPercent = 100;
- p.dwActualHP = 100;
- p.dwMaxHP = 100;
- }
- }
- else
- {
- if (m_pkChrTarget->GetMaxHP() <= 0)
- {
- p.bHPPercent = 0;
- p.dwActualHP = 0;
- p.dwMaxHP = 0;
- }
- else
- {
- p.bHPPercent = MINMAX(0, (m_pkChrTarget->GetHP() * 100) / m_pkChrTarget->GetMaxHP(), 100);
- p.dwActualHP = m_pkChrTarget->GetHP();
- p.dwMaxHP = m_pkChrTarget->GetMaxHP();
- }
- }
- }
- }
- else
- {
- p.dwVID = 0;
- p.bHPPercent = 0;
- p.dwActualHP = 0;
- p.dwMaxHP = 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();
- #ifdef ENABLE_HIDE_COSTUME_PART
- p.bCostumeHide[ECostumePartTypes::HIDE_COSTUME_BODY] = GetQuestFlag("HIDE.COSTUME_BODY");
- p.bCostumeHide[ECostumePartTypes::HIDE_COSTUME_HAIR] = GetQuestFlag("HIDE.COSTUME_HAIR");
- #ifdef ENABLE_COSTUME_WEAPON_SYSTEM
- p.bCostumeHide[ECostumePartTypes::HIDE_COSTUME_WEAPON] = GetQuestFlag("HIDE.COSTUME_WEAPON");
- #endif
- #ifdef ENABLE_SHOULDER_SASH_SYSTEM
- p.bCostumeHide[ECostumePartTypes::HIDE_COSTUME_SASH] = GetQuestFlag("HIDE.COSTUME_SASH");
- #endif
- #endif
- if (GetMaxHP() <= 0)
- {
- p.bHPPercent = 0;
- p.dwActualHP = 0;
- p.dwMaxHP = 0;
- }
- else
- {
- p.bHPPercent = MINMAX (0, (GetHP()* 100) / GetMaxHP(), 100);
- p.dwActualHP = GetHP();
- p.dwMaxHP = GetMaxHP();
- }
- auto 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);
- }
- }
- void CHARACTER::SetWarpLocation(long lMapIndex, long x, long y)
- {
- m_posWarp.x = x * 100;
- m_posWarp.y = y * 100;
- m_lWarpMapIndex = lMapIndex;
- }
- void CHARACTER::ExitToSavedLocation()
- {
- sys_log(0, "ExitToSavedLocation");
- #ifdef ENABLE_DUNGEON_REJOIN
- if(GetQuestFlag("dungeon_rejoin.index") > 0)
- {
- if(GetMapIndex() >= 10000)
- SetQuestFlag("dungeon_rejoin.index", 0);
- }
- #endif
- WarpSet(m_posWarp.x, m_posWarp.y, m_lWarpMapIndex);
- m_posExit.x = m_posExit.y = m_posExit.z = 0;
- m_lExitMapIndex = 0;
- }
- void CHARACTER::SaveExitLocation()
- {
- m_posExit = GetXYZ();
- m_lExitMapIndex = GetMapIndex();
- }
- #ifdef ENABLE_P2P_WARP
- bool CHARACTER::WarpSet(long x, long y, long lPrivateMapIndex)
- {
- if (!IsPC())
- {
- return false;
- }
- long lAddr;
- long lMapIndex;
- uint16_t 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;
- }
- return WarpSet(x, y, lPrivateMapIndex, lMapIndex, lAddr, wPort);
- }
- bool CHARACTER::WarpSet(long x, long y, long lPrivateMapIndex, long lMapIndex, long lAddr, WORD wPort)
- {
- {
- long lCurAddr;
- long lCurMapIndex = 0;
- WORD wCurPort;
- CMapLocation::instance().Get(GetX(), GetY(), lCurMapIndex, lCurAddr, wCurPort);
- }
- if (lPrivateMapIndex >= 10000)
- {
- if (lPrivateMapIndex / 10000 != lMapIndex)
- {
- sys_err ("Invalid map index %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;
- #ifdef ENABLE_SWITCHBOT
- CSwitchbotManager::Instance().SetIsWarping(GetPlayerID(), true);
- if (p.wPort != mother_port)
- {
- CSwitchbotManager::Instance().P2PSendSwitchbot(GetPlayerID(), p.wPort);
- }
- #endif
- GetDesc()->Packet(&p, sizeof(TPacketGCWarp));
- char buf[256];
- snprintf(buf, sizeof(buf), "%s MapIdx %ld DestMapIdx%ld DestX%ld DestY%ld Empire%d", GetName(), GetMapIndex(), lPrivateMapIndex, x, y, GetEmpire());
- LogManager::instance().CharLog(this, 0, "WARP", buf);
- return true;
- }
- #else
- bool CHARACTER::WarpSet(long x, long y, long lPrivateMapIndex)
- {
- if (!IsPC())
- {
- return false;
- }
- long lAddr;
- long lMapIndex;
- uint16_t 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;
- }
- if (lPrivateMapIndex >= 10000)
- {
- if (lPrivateMapIndex / 10000 != lMapIndex)
- {
- sys_err ("Invalid map index %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;
- #ifdef ENABLE_SWITCHBOT
- CSwitchbotManager::Instance().SetIsWarping(GetPlayerID(), true);
- if (p.wPort != mother_port)
- {
- CSwitchbotManager::Instance().P2PSendSwitchbot(GetPlayerID(), p.wPort);
- }
- #endif
- GetDesc()->Packet(&p, sizeof(TPacketGCWarp));
- char buf[256];
- snprintf(buf, sizeof(buf), "%s MapIdx %ld DestMapIdx%ld DestX%ld DestY%ld Empire%d", GetName(), GetMapIndex(), lPrivateMapIndex, x, y, GetEmpire());
- LogManager::instance().CharLog(this, 0, "WARP", buf);
- return true;
- }
- #endif
- 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))
- {
- GoHome(); /*** When somebody going in a any map with wrong map_index, him come back to default empire ***/
- 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;
- {
- TPacketGGLogin p;
- p.bHeader = HEADER_GG_LOGIN;
- strlcpy(p.szName, GetName(), sizeof(p.szName));
- strlcpy(p.login, GetDesc()->GetAccountTable().login, sizeof(p.login));
- p.dwPID = GetPlayerID();
- p.bEmpire = GetEmpire();
- p.lMapIndex = SECTREE_MANAGER::instance().GetMapIndex(GetX(), GetY());
- p.bChannel = g_bChannel;
- p.sLevel = (short)GetLevel();
- #ifdef __ENABLE_FRIENDLIST_FLAG__
- std::string flag = GetLang();
- strlcpy(p.szFlag, flag.c_str(), MIN(sizeof(p.szFlag), flag.size()+1));
- #endif
- P2P_MANAGER::instance().Send(&p, sizeof(TPacketGGLogin));
- }
- }
- bool CHARACTER::Return(bool bCreatePosition)
- {
- if (!IsNPC())
- {
- return false;
- }
- int x, y;
- SetVictim(NULL);
- if (bCreatePosition)
- {
- x = m_pkMobInst->m_posCreate.x;
- y = m_pkMobInst->m_posCreate.y;
- }
- else
- {
- 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 (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;
- }
- #ifdef ENABLE_FAKE_PC
- if (IS_SET(m_pointsInstant.dwAIFlag, AIFLAG_NOMOVE) && !GetDungeon())
- #else
- if (IS_SET(m_pointsInstant.dwAIFlag, AIFLAG_NOMOVE))
- #endif
- {
- if (pkChr->IsPC())
- {
- if (!GetParty() || !GetParty()->GetLeader() || GetParty()->GetLeader() == this)
- {
- if (get_dword_time() - m_pkMobInst->m_dwLastAttackedTime >= 15000)
- {
- if (m_pkMobData->m_table.wAttackRange < DISTANCE_APPROX(pkChr->GetX() - GetX(), pkChr->GetY() - GetY()))
- {
- if (Return())
- {
- return true;
- }
- }
- }
- }
- }
- return false;
- }
- long x = pkChr->GetX();
- long y = pkChr->GetY();
- #ifdef ENABLE_FAKE_PC
- if (pkChr->IsPC() && IsMonster() && !FakePC_IsSupporter())
- #else
- if (pkChr->IsPC())
- #endif
- {
- if (!GetParty() || !GetParty()->GetLeader() || GetParty()->GetLeader() == this)
- {
- if (get_dword_time() - m_pkMobInst->m_dwLastAttackedTime >= 15000)
- {
- if (5000 < DISTANCE_APPROX(m_pkMobInst->m_posLastAttacked.x - GetX(), m_pkMobInst->m_posLastAttacked.y - GetY()))
- {
- if (Return())
- {
- return true;
- }
- }
- }
- }
- }
- if (GetMobRank() > 4)
- {
- if (5000 < DISTANCE_APPROX(m_pkMobInst->m_posCreate.x - GetX(), m_pkMobInst->m_posCreate.y - GetY()))
- {
- if (Return (true))
- {
- return true;
- }
- }
- }
- #ifdef ENABLE_FAKE_PC
- if (IsGuardNPC() || IS_SET(m_pointsInstant.dwAIFlag, AIFLAG_NOMOVE))
- #else
- if (IsGuardNPC())
- #endif
- {
- 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 && !IsPet()
- #ifdef ENABLE_NEW_PET_SYSTEM
- && !IsNewPet()
- #endif
- #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
- && !IsMountSystem()
- #endif
- )
- {
- 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(pkChr->GetXYZ(), GetXYZ());
- float fFollowSpeed = mySpeed - yourSpeed * cosf(rot_delta * (float)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);
- x += (long) fYourMoveEstimateX;
- y += (long) fYourMoveEstimateY;
- float fDistNew = sqrtf(((float)x - GetX())*(x - GetX()) + ((float)y - GetY())*(y - GetY()));
- if (fDist < fDistNew)
- {
- x = (long)(GetX() + (x - GetX()) * fDist / fDistNew);
- y = (long)(GetY() + (y - GetY()) * fDist / fDistNew);
- }
- }
- }
- }
- SetRotationToXY(x, y);
- float fDist = DISTANCE(pkChr->GetXYZ(), GetXYZ());
- if (fDist <= fMinDistance)
- {
- return false;
- }
- float fx, fy;
- if (IsChangeAttackPosition(pkChr) && GetMobRank() < MOB_RANK_BOSS)
- {
- SetChangeAttackPositionTime();
- //
- int retry = 16;
- int dx, dy;
- int rot = (int) GetDegreeFromPositionXY(x, y, GetX(), GetY());
- while (--retry)
- {
- if (fDist < 500.0f)
- {
- GetDeltaByDegree((float)((rot + number(-90, 90) + number(-90, 90)) % 360), fMinDistance, &fx, &fy);
- }
- else
- {
- GetDeltaByDegree((float)number(0, 359), fMinDistance, &fx, &fy);
- }
- 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;
- }
- }
- if (!Goto(dx, dy))
- {
- return false;
- }
- }
- else
- {
- float fDistToGo = fDist - fMinDistance;
- GetDeltaByDegree(GetRotation(), fDistToGo, &fx, &fy);
- if (!Goto(GetX() + (int) fx, GetY() + (int) fy))
- {
- return false;
- }
- }
- SendMovePacket(FUNC_WAIT, 0, 0, 0, 0);
- return true;
- }
- float CHARACTER::GetDistanceFromSafeboxOpen() const
- {
- return (float)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)
- {
- #ifdef __ADMIN_MANAGER__
- if (!GM::check_allow(GetGMLevel(), GM_ALLOW_USE_SAFEBOX))
- {
- ChatInfoTrans(("__YOU_CAN_NOT_DO_THIS_AS_GM__"));
- return;
- }
- #endif
- if (!*pszPassword || strlen(pszPassword) > SAFEBOX_PASSWORD_MAX_LEN)
- {
- ChatInfoTrans(("SAFEBOX__WRONG_PASSWORD"));
- return;
- }
- else if (m_pkSafebox)
- {
- ChatInfoTrans(("SAFEBOX__ALREADY_OPEN"));
- return;
- }
- int iPulse = thecore_pulse();
- if (iPulse - GetSafeboxLoadTime() < PASSES_PER_SEC (3)) /*** 3 Seconds for open again the Safebox ***/
- {
- ChatInfoTrans(("SAFEBOX__WAITING_TIME"));
- return;
- }
- else if (GetDistanceFromSafeboxOpen() > 1000)
- {
- ChatInfoTrans(("SAFEBOX__TOO_FAR"));
- 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;
- strlcpy(p.szLogin, GetDesc()->GetAccountTable().login, sizeof(p.szLogin));
- strlcpy(p.szPassword, pszPassword, sizeof(p.szPassword));
- 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;
- SetOpenSafebox(true);
- 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);
- #ifdef ENABLE_SPECULAR_SYSTEM
- item->SetSpecularColor(pItems->bSpecularColor);
- #endif
- #ifdef ENABLE_BINDING_SYSTEM
- item->SetSealDate(pItems->nSealDate);
- #endif
- if (!m_pkSafebox->Add(pItems->pos, item))
- {
- M2_DESTROY_ITEM(item);
- }
- else
- {
- item->SetSkipSave(false);
- }
- }
- }
- }
- void CHARACTER::ChangeSafeboxSize(BYTE bSize)
- {
- 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;
- }
- SetOpenSafebox(false);
- 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);
- #ifdef ENABLE_SPECULAR_SYSTEM
- item->SetSpecularColor(pItems->bSpecularColor);
- #endif
- #ifdef ENABLE_BINDING_SYSTEM
- item->SetSealDate(pItems->nSealDate);
- #endif
- 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();
- if (GetMaxHP() <= 0)
- {
- out.percent_hp = 0;
- }
- else
- {
- out.percent_hp = MINMAX(0, GetHP() * 100 / GetMaxHP(), 100);
- }
- 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)
- {
- out.affects[0] = GetParty()->GetPartyBonusExpPercent();
- 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 WHERE account_id = %u", GetDesc()->GetAccountTable().id);
- }
- }
- void CHARACTER::SetSafeboxSize(int iSize)
- {
- sys_log(1, "SetSafeboxSize: %s %d", GetName(), iSize);
- m_iSafeboxSize = iSize;
- DBManager::instance().Query("UPDATE safebox SET size = %d WHERE account_id = %u", iSize / SAFEBOX_PAGE_SIZE, GetDesc()->GetAccountTable().id);
- }
- int CHARACTER::GetSafeboxSize() const
- {
- return m_iSafeboxSize;
- }
- void CHARACTER::SetNowWalking(bool bWalkFlag)
- {
- if (m_bNowWalking != bWalkFlag)
- {
- if (bWalkFlag)
- {
- m_bNowWalking = true;
- m_dwWalkStartTime = get_dword_time();
- }
- else
- {
- m_bNowWalking = false;
- }
- {
- 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("Walking");
- }
- else
- {
- MonsterLog("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());
- }
- 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;
- }
- 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));
- SetRandomHP((iLv - 1) * number(JobInitialPoints[GetJob()].hp_per_lv_begin, JobInitialPoints[GetJob()].hp_per_lv_end));
- SetRandomSP((iLv - 1) * number(JobInitialPoints[GetJob()].sp_per_lv_begin, JobInitialPoints[GetJob()].sp_per_lv_end));
- PointChange(POINT_STAT, ((MINMAX(1, iLv, gPlayerMaxLevelStats) - 1) * 3) + GetPoint(POINT_LEVEL_STEP) - GetPoint(POINT_STAT));
- ComputePoints();
- 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)
- {
- extern const DWORD GetRandomSkillVnum(BYTE bJob = JOB_MAX_NUM);
- DWORD dwSkillVnum = 0;
- if (!number(0, 1))
- {
- dwSkillVnum = GetRandomSkillVnum(GetJob());
- }
- else
- {
- dwSkillVnum = GetRandomSkillVnum();
- }
- 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::BeginStateEmpty()
- {
- }
- 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[128])
- {
- TPacketGCSpecificEffect p;
- p.header = HEADER_GC_SPECIFIC_EFFECT;
- p.vid = GetVID();
- memcpy(p.effect_file, filename, 128);
- PacketAround(&p, sizeof(TPacketGCSpecificEffect));
- }
- void CHARACTER::MonsterChat(BYTE bMonsterChatType)
- {
- if (IsPC())
- {
- return;
- }
- char sbuf[256 + 1];
- if (IsMonster())
- {
- if (number(0, 60))
- {
- return;
- }
- snprintf(sbuf, sizeof(sbuf), "(locale.monster_chat[%i] and locale.monster_chat[%i][%d] or '')", GetRaceNum(), GetRaceNum(), bMonsterChatType * 3 + number(1, 3));
- }
- else
- {
- if (bMonsterChatType != MONSTER_CHAT_WAIT)
- {
- return;
- }
- if (IsGuardNPC())
- {
- if (number(0, 6))
- {
- return;
- }
- }
- else
- {
- if (number(0, 30))
- {
- 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;
- }
- SPacketGCChat pack_chat;
- pack_chat.header = HEADER_GC_CHAT;
- pack_chat.size = sizeof(struct SPacketGCChat) + 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 SPacketGCChat));
- 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 && !m_pkDungeon)
- {
- return CDungeonManager::instance().FindByMapIndex(m_lWarpMapIndex);
- }
- return m_pkDungeon;
- }
- #ifdef ENABLE_ZODIAC_TEMPLE
- LPZODIAC CHARACTER::GetZodiacForce() const
- {
- if (m_lWarpMapIndex > 10000)
- {
- return CZodiacManager::instance().FindByMapIndex(m_lWarpMapIndex);
- }
- return m_pkZodiac;
- }
- #endif
- void CHARACTER::SetBlockMode(DWORD 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);
- // SetQuestFlag("game_option.block_view_equip", bFlag & BLOCK_VIEW_EQUIP ? 1 : 0);
- #ifdef ENABLE_TELEPORT_TO_A_FRIEND
- SetQuestFlag("game_option.block_warp_request", bFlag & BLOCK_WARP_REQUEST ? 1 : 0);
- #endif
- }
- void CHARACTER::SetBlockModeForce(DWORD 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;
- }
- }
- return aiPolymorphPowerByLevel[MINMAX(0, GetSkillLevel(SKILL_POLYMORPH), 40)];
- }
- 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);
- #ifdef ENABLE_FAKE_PC
- FakePC_Owner_DespawnAll();
- #endif
- 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);
- }
- ComputeBattlePoints();
- }
- int CHARACTER::GetQuestFlag(const std::string& flag) const
- {
- if (!IsPC())
- {
- return 0;
- }
- DWORD pid = GetPlayerID();
- quest::CQuestManager &q = quest::CQuestManager::instance();
- quest::PC* pPC = q.GetPC(pid);
- if (!pPC)
- {
- return 0;
- }
- return pPC->GetFlag(flag);
- }
- void CHARACTER::SetQuestFlag(const std::string& flag, int value)
- {
- DWORD pid = GetPlayerID();
- quest::CQuestManager &q = quest::CQuestManager::instance();
- quest::PC* pPC = q.GetPC(pid);
- if (!pPC)
- {
- return;
- }
- pPC->SetFlag(flag, value);
- }
- void CHARACTER::DetermineDropMetinStone()
- {
- static const DWORD c_adwMetin[] =
- {
- /*** From here change "+ how drop stone" ***/
- /*** E.g : 28030 (stone +0) / 28430 (stone +4) ***/
- 28030,
- 28031,
- 28032,
- 28033,
- 28034,
- 28035,
- 28036,
- 28037,
- 28038,
- 28039,
- 28040,
- 28041,
- 28042,
- 28043,
- #ifdef ENABLE_WOLFMAN
- 28012,
- #endif
- };
- 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;
- {
- m_dwDropMetinStone = c_adwMetin[number(0, sizeof(c_adwMetin)/sizeof(DWORD) - 1)];
- int iGradePct = number(1, 100);
- 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;
- }
- }
- }
- }
- }
- 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();
- #ifdef ENABLE_EXTENDED_COUNT_ITEMS
- p.equips[i].count = (uint16_t)item->GetCount();
- #else
- p.equips[i].count = (BYTE)item->GetCount();
- #endif
- thecore_memcpy(p.equips[i].alSockets, item->GetSockets(), sizeof(p.equips[i].alSockets));
- thecore_memcpy(p.equips[i].aAttr, item->GetAttributes(), sizeof(p.equips[i].aAttr));
- }
- else
- {
- p.equips[i].vnum = 0;
- }
- }
- ch->GetDesc()->Packet(&p, sizeof(p));
- }
- bool CHARACTER::CanSummon(int iLeaderShip)
- {
- return (iLeaderShip >= 30 && m_dwLastDeadTime + 300 > get_dword_time());
- }
- void CHARACTER::MountVnum(DWORD vnum)
- {
- if (vnum && !IS_MOUNTABLE_ZONE (GetMapIndex(), vnum == GetMyHorseVnum()))
- {
- ChatInfoTrans(("RIDING_IS_BLOCKED_HERE"));
- return;
- }
- if (m_dwMountVnum == vnum)
- {
- return;
- }
- if ((m_dwMountVnum != 0) && (vnum != 0))
- {
- MountVnum(0);
- }
- m_dwMountVnum = vnum;
- m_dwMountTime = get_dword_time();
- if (m_bIsObserver)
- {
- return;
- }
- m_posDest.x = m_posStart.x = GetX();
- m_posDest.y = m_posStart.y = GetY();
- EncodeInsertPacket(this);
- auto it = m_map_view.begin();
- while (it != m_map_view.end())
- {
- LPENTITY entity = (it++)->first;
- EncodeInsertPacket(entity);
- }
- #ifdef ENABLE_FAKE_PC
- if (LPCHARACTER pkSup = FakePC_Owner_GetSupporter())
- {
- pkSup->ViewReencode();
- }
- #endif
- 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];
- if (3 != sscanf(pkWarp->GetName(), " %s %ld %ld ", szTmp, &m_lTargetX, &m_lTargetY)
- #ifdef ENABLE_HYDRA_DUNGEON
- && pkWarp->GetRaceNum() != 3949
- #endif
- )
- {
- if (number(1, 100) < 5)
- {
- 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;
- }
- #ifdef ENABLE_HYDRA_DUNGEON
- pkWarps = pkWarp;
- #endif
- }
- 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)
- {
- #ifdef ENABLE_HYDRA_DUNGEON
- {
- if (pkWarps->GetRaceNum() == 3949)
- {
- pkChr->WarpSet(168600, 611200);
- }
- else
- {
- pkChr->WarpSet(m_lTargetX, m_lTargetY);
- }
- }
- #else
- pkChr->WarpSet(m_lTargetX, m_lTargetY);
- #endif
- }
- else
- {
- pkChr->Show(pkChr->GetMapIndex(), m_lTargetX, m_lTargetY);
- pkChr->Stop();
- }
- }
- bool m_bInvalid;
- bool m_bUseWarp;
- long m_lX;
- long m_lY;
- long m_lTargetX;
- long m_lTargetY;
- BYTE m_bEmpire;
- #ifdef ENABLE_HYDRA_DUNGEON
- LPCHARACTER pkWarps;
- #endif
- };
- }
- 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)
- {
- 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()
- #ifdef ENABLE_HYDRA_DUNGEON
- && GetRaceNum() != 3949
- #endif
- )
- {
- 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;
- }
- TMarriage* pMarriage = CMarriageManager::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;
- strlcpy(p.msg, szMsg, sizeof(p.msg));
- 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();
- }
- #ifdef ENABLE_TELEPORT_TO_A_FRIEND
- bool CHARACTER::SummonCharacter(LPCHARACTER victim)
- {
- if (!IsAllowedMapIndex(GetMapIndex()))
- {
- victim->ChatInfoTrans(("CANNOT_WARP_TO_YOUR_FRIEND_BECOUSE_OF_UNALLOWED_MAP_INDEX"));
- return false;
- }
- if ((victim = (CHARACTER_MANAGER::instance().FindByPID(victim->GetPlayerID()))))
- {
- int mapIdx = victim->GetMapIndex();
- if (IS_SUMMONABLE_ZONE(mapIdx))
- {
- if (CAN_ENTER_ZONE(this, mapIdx))
- {
- victim->WarpSet(GetX(), GetY());
- }
- else
- {
- ChatInfoTrans(("CANNOT_WARP_TO_THIS_PLAYER"));
- return false;
- }
- }
- else
- {
- ChatInfoTrans(("CANNOT_WARP_TO_THIS_PLAYER"));
- return false;
- }
- }
- else
- {
- CCI * pcci = P2P_MANAGER::instance().FindByPID(victim->GetPlayerID());
- if (!pcci)
- {
- ChatInfoTrans(("PLAYER_IS_NOT_ONLINE"));
- return false;
- }
- if (!IS_SUMMONABLE_ZONE(pcci->lMapIndex))
- {
- ChatInfoTrans(("CANNOT_WARP_TO_THIS_PLAYER"));
- return false;
- }
- #ifndef ENABLE_P2P_WARP
- else if (pcci->bChannel != g_bChannel)
- {
- ChatInfoTrans(("PLAYER_IS_ON_CHANNEL_%d_YOU_ARE_ON_%d"), pcci->bChannel, g_bChannel);
- return false;
- }
- #endif
- else
- {
- if (!CAN_ENTER_ZONE(this, pcci->lMapIndex))
- {
- ChatInfoTrans(("CANNOT_WARP_TO_THIS_PLAYER"));
- return false;
- }
- TPacketGGFindPosition p;
- p.header = HEADER_GG_FIND_POSITION;
- p.dwFromPID = GetPlayerID();
- p.dwTargetPID = victim->GetPlayerID();
- pcci->pkDesc->Packet(&p, sizeof(TPacketGGFindPosition));
- }
- }
- return true;
- }
- bool CHARACTER::IsAllowedMapIndex(int mapindex)
- {
- switch(mapindex)
- {
- case 1: // m2_shinsoo_map1
- case 3: // m2_shinsoo_map2
- case 4: // m2_dino
- case 6: // m2_forrest
- case 41: // m2_jinno_map1
- case 42: // m2_valley_of_orcs
- case 43: // m2_jinno_map2
- case 44: // m2_naga
- case 45: // m2_monkey
- case 61: // m2_snow
- case 62: // m2_flame
- case 63: // m2_desert
- case 65: // m2_milgyo
- case 68: // m2_red_forest
- case 71: // m2_sd1_and_sd2
- case 72: // m2_v3
- case 73: // m2_v4
- case 218: // m2_capedragonhead
- case 250: // m2_dawnmistwood_dungeon
- case 251: // m2_mt_thunder_dungeon
- case 255: // m2_mining_map
- case 302: // m2_dawnmistwood
- case 303: // m2_bayblacksand
- case 304: // m2_mt_thunder
- return true;
- }
- return false;
- }
- #endif
- 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(), mapIdx);
- }
- else
- {
- ChatInfoTrans(("CANNOT_WARP_TO_THIS_PLAYER"));
- return false;
- }
- }
- else
- {
- ChatInfoTrans(("CANNOT_WARP_TO_THIS_PLAYER"));
- return false;
- }
- }
- else
- {
- CCI* pcci = P2P_MANAGER::instance().FindByPID(dwPID);
- if (!pcci)
- {
- ChatInfoTrans(("PLAYER_IS_NOT_ONLINE"));
- return false;
- }
- if (!IS_SUMMONABLE_ZONE(pcci->lMapIndex))
- {
- ChatInfoTrans(("CANNOT_WARP_TO_THIS_PLAYER"));
- return false;
- }
- #ifndef ENABLE_P2P_WARP
- else if (pcci->bChannel != g_bChannel)
- {
- ChatInfoTrans(("PLAYER_IS_ON_CHANNEL_%d_YOU_ARE_ON_%d"), pcci->bChannel, g_bChannel);
- return false;
- }
- #endif
- else
- {
- if (!CAN_ENTER_ZONE(this, pcci->lMapIndex))
- {
- ChatInfoTrans(("CANNOT_WARP_TO_THIS_PLAYER"));
- return false;
- }
- TPacketGGFindPosition p;
- p.header = HEADER_GG_FIND_POSITION;
- p.dwFromPID = GetPlayerID();
- p.dwTargetPID = dwPID;
- pcci->pkDesc->Packet(&p, sizeof(TPacketGGFindPosition));
- }
- }
- return true;
- }
- CGuild* CHARACTER::GetRefineGuild() const
- {
- LPCHARACTER chRefineNPC = GetRefineNPC();
- return (chRefineNPC ? chRefineNPC->GetGuild() : NULL);
- }
- LPCHARACTER CHARACTER::GetRefineNPC() const
- {
- if (!m_dwRefineNPCVID)
- {
- return NULL;
- }
- return CHARACTER_MANAGER::instance().Find(m_dwRefineNPCVID);
- }
- 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;
- }
- LPCHARACTER chRefineNPC = GetRefineNPC();
- 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)
- {
- if (pGuild != GetGuild())
- {
- pGuild->RequestDepositMoney(this, iFee);
- iRemain -= iFee;
- }
- }
- ChangeGold(-iRemain);
- }
- bool CHARACTER::IsHack(bool bSendMsg, bool bCheckShopOwner, int limittime)
- {
- const int iPulse = thecore_pulse();
- if (test_server)
- {
- bSendMsg = true;
- }
- if (iPulse - GetSafeboxLoadTime() < PASSES_PER_SEC(limittime))
- {
- if (bSendMsg)
- {
- ChatInfoTrans(("SAFEBOX__WAITING_TIME_CANNOT_MOVE_%d"), limittime);
- }
- if (test_server)
- {
- ChatInfo( "[TestOnly]Pulse %d LoadTime %d PASS %d", iPulse, GetSafeboxLoadTime(), PASSES_PER_SEC(limittime));
- }
- return true;
- }
- if (bCheckShopOwner)
- {
- if (GetExchange() || GetMyShop() || GetShopOwner() || IsOpenSafebox() || IsCubeOpen()
- #ifdef ENABLE_COSTUME_AURA_SYSTEM
- || IsAuraRefineWindowOpen()
- #endif
- )
- {
- if (bSendMsg)
- {
- ChatInfoTrans(("EXCHANGE__CANNOT_MOVE"));
- }
- return true;
- }
- }
- else
- {
- if (GetExchange() || GetMyShop() || IsOpenSafebox() || IsCubeOpen()
- #ifdef ENABLE_COSTUME_AURA_SYSTEM
- || IsAuraRefineWindowOpen()
- #endif
- )
- {
- if (bSendMsg)
- {
- ChatInfoTrans(("EXCHANGE__CANNOT_MOVE"));
- }
- return true;
- }
- }
- if (iPulse - GetExchangeTime() < PASSES_PER_SEC(limittime))
- {
- if (bSendMsg)
- {
- ChatInfoTrans(("EXCHANGE__CANNOT_MOVE_%d"), limittime );
- }
- return true;
- }
- if (iPulse - GetMyShopTime() < PASSES_PER_SEC(limittime))
- {
- if (bSendMsg)
- {
- ChatInfoTrans(("EXCHANGE__CANNOT_MOVE_%d"), limittime );
- }
- return true;
- }
- if (iPulse - GetRefineTime() < PASSES_PER_SEC(limittime))
- {
- if (bSendMsg)
- {
- ChatInfoTrans(("EXCHANGE__CANNOT_MOVE_%d_SCROLL"), limittime);
- }
- return true;
- }
- return false;
- }
- 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());
- }
- }
- void CHARACTER::UpdateDepositPulse()
- {
- m_deposit_pulse = thecore_pulse() + PASSES_PER_SEC(60 * 5);
- }
- 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:
- #ifdef ENABLE_WOLFMAN
- case MAIN_RACE_WOLFMAN_M:
- #endif
- 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;
- }
- return SEX_MALE;
- }
- int CHARACTER::GetHPPct() const
- {
- if (GetMaxHP() <= 0)
- {
- return 0;
- }
- 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)
- {
- SetPoint(POINT_ATT_SPEED, 250);
- }
- else
- {
- SetPoint(POINT_ATT_SPEED, m_pkMobData->m_table.sAttackSpeed);
- }
- }
- }
- bool CHARACTER::IsDeathBlow() const
- {
- if (GetHPPct() > 50)
- {
- return false;
- }
- return (number(1, 100) <= m_pkMobData->m_table.bDeathBlowPoint);
- }
- struct FFindReviver
- {
- FFindReviver()
- {
- pChar = NULL;
- HasReviver = false;
- }
- void operator()(LPCHARACTER ch)
- {
- if (ch->IsMonster() != true)
- {
- return;
- }
- if (ch->IsReviver() && pChar != ch && ch->IsDead() != true)
- {
- if (number(1, 100) <= ch->GetMobTable().bRevivePoint)
- {
- 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;
- }
- }
- 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)
- {
- 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;
- }
- auto info = new char_event_info;
- info->ch = this;
- m_pkDestroyWhenIdleEvent = event_create(destroy_when_idle_event, info, PASSES_PER_SEC(300));
- }
- DWORD CHARACTER::GetSkipComboAttackByTime() const
- {
- return m_dwSkipComboAttackByTime;
- }
- //src_flr
- void CHARACTER::ResetChatCounter()
- {
- m_bChatCounter = 0;
- }
- BYTE CHARACTER::IncreaseChatCounter()
- {
- return ++m_bChatCounter;
- }
- BYTE CHARACTER::GetChatCounter() const
- {
- return m_bChatCounter;
- }
- //src_flr (i think it's a protection anti kick hack, i forgot that)
- bool CHARACTER::IsRiding() const
- {
- #ifdef ENABLE_FAKE_PC
- if (FakePC_Check())
- {
- return FakePC_GetOwner()->IsRiding();
- }
- #endif
- 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()
- #ifdef ENABLE_COSTUME_AURA_SYSTEM
- || IsAuraRefineWindowOpen()
- #endif
- )
- {
- return false;
- }
- #ifdef ENABLE_SHOULDER_SASH_SYSTEM
- if ((m_bSashCombination) || (m_bSashAbsorption))
- {
- return false;
- }
- #endif
- #ifdef __ENABLE_NEW_OFFLINESHOP__
- if (iPulse - GetOfflineShopUseTime() < limit_time)
- {
- return false;
- }
- // if (GetOfflineShopGuest() || GetAuctionGuest())
- // {
- // return false;
- // }
- #endif
- return true;
- }
- DWORD CHARACTER::GetNextExp() const
- {
- return exp_table[GetLevel()];
- }
- #ifdef ENABLE_NEW_PET_SYSTEM
- void CHARACTER::SendPetLevelUpEffect(int vid, int type, int value, int amount)
- {
- struct SPacketGCPointChange pack;
- pack.header = HEADER_GC_CHARACTER_POINT_CHANGE;
- pack.dwVID = vid;
- pack.type = type;
- pack.value = value;
- pack.amount = amount;
- PacketAround(&pack, sizeof (pack));
- }
- uint32_t CHARACTER::PetGetNextExp() const
- {
- if (gPlayerMaxLevel < GetLevel())
- return 2500000000u;
- else
- return exppet_table[GetLevel()];
- }
- #endif
- #ifdef __ENABLE_ITEMSHOP_IN_GAME__
- void CHARACTER::SendItemShop()
- {
- extern itemShopVector g_itemShopVector;
- itemShopVector::iterator it = g_itemShopVector.begin();
- ChatPacket(CHAT_TYPE_COMMAND, "ClearItemShop");
- while (it != g_itemShopVector.end())
- {
- ChatPacket(CHAT_TYPE_COMMAND, "RecvItemShop %d %d %d %d %d %d", it->byCategory, it->dwNum, it->dwVnum, it->wCount, it->iPrice, it->byCurrency);
- it++;
- }
- ChatPacket(CHAT_TYPE_COMMAND, "RefreshItemShop");
- }
- #endif
- int CHARACTER::GetSkillPowerByLevel(int level, bool bMob) const
- {
- return CTableBySkill::instance().GetSkillPowerByLevelFromType(GetJob(), GetSkillGroup(), MINMAX(0, level, SKILL_MAX_LEVEL), bMob);
- }
- #ifdef ENABLE_KICK_HACK_SECURITY
- void CHARACTER::SetLastPMPulse (void)
- {
- m_iLastPMPulse = thecore_pulse() + 25;
- }
- #endif
- #ifdef ENABLE_SHOULDER_SASH_SYSTEM
- void CHARACTER::OpenSash (bool bCombination)
- {
- if (isSashOpened (bCombination))
- {
- ChatInfoTrans(("__SASH__WINDOW_FOR_SASH_IS_ALREADY_OPEN"));
- return;
- }
- if (bCombination)
- {
- if (m_bSashAbsorption)
- {
- ChatInfoTrans(("__SASH__WE_WILL_CLOSE_FIRST_THE_ABSORBTION_WINDOW"));
- return;
- }
- m_bSashCombination = true;
- }
- else
- {
- if (m_bSashCombination)
- {
- ChatInfoTrans(("__SASH__WE_WILL_CLOSE_FIRST_THE_COMBINATION_WINDOW"));
- return;
- }
- m_bSashAbsorption = true;
- }
- TItemPos tPos;
- tPos.window_type = INVENTORY;
- tPos.cell = 0;
- TPacketSash sPacket;
- sPacket.header = HEADER_GC_SASH;
- sPacket.subheader = SASH_SUBHEADER_GC_OPEN;
- sPacket.bWindow = bCombination;
- sPacket.ullPrice = 0;
- sPacket.bPos = 0;
- sPacket.tPos = tPos;
- sPacket.dwItemVnum = 0;
- sPacket.dwMinAbs = 0;
- sPacket.dwMaxAbs = 0;
- GetDesc()->Packet (&sPacket, sizeof (TPacketSash));
- ClearSashMaterials();
- }
- void CHARACTER::CloseSash()
- {
- if ((!m_bSashCombination) && (!m_bSashAbsorption))
- {
- return;
- }
- bool bWindow = (m_bSashCombination == true ? true : false);
- TItemPos tPos;
- tPos.window_type = INVENTORY;
- tPos.cell = 0;
- TPacketSash sPacket;
- sPacket.header = HEADER_GC_SASH;
- sPacket.subheader = SASH_SUBHEADER_GC_CLOSE;
- sPacket.bWindow = bWindow;
- sPacket.ullPrice = 0;
- sPacket.bPos = 0;
- sPacket.tPos = tPos;
- sPacket.dwItemVnum = 0;
- sPacket.dwMinAbs = 0;
- sPacket.dwMaxAbs = 0;
- GetDesc()->Packet (&sPacket, sizeof (TPacketSash));
- if (bWindow)
- {
- m_bSashCombination = false;
- }
- else
- {
- m_bSashAbsorption = false;
- }
- ClearSashMaterials();
- }
- void CHARACTER::ClearSashMaterials()
- {
- LPITEM* pkItemMaterial;
- pkItemMaterial = GetSashMaterials();
- for (int i = 0; i < SASH_WINDOW_MAX_MATERIALS; ++i)
- {
- if (!pkItemMaterial[i])
- {
- continue;
- }
- pkItemMaterial[i]->Lock (false);
- pkItemMaterial[i] = NULL;
- }
- }
- bool CHARACTER::SashIsSameGrade (long lGrade)
- {
- LPITEM* pkItemMaterial;
- pkItemMaterial = GetSashMaterials();
- if (!pkItemMaterial[0])
- {
- return false;
- }
- bool bReturn = (pkItemMaterial[0]->GetValue (SASH_GRADE_VALUE_FIELD) == lGrade ? true : false);
- return bReturn;
- }
- DWORD CHARACTER::GetSashCombinePrice (long lGrade)
- {
- unsigned long long ullPrice = 0;
- switch (lGrade)
- {
- case 2:
- {
- ullPrice = SASH_GRADE_2_PRICE;
- }
- break;
- case 3:
- {
- ullPrice = SASH_GRADE_3_PRICE;
- }
- break;
- case 4:
- {
- ullPrice = SASH_GRADE_4_PRICE;
- }
- break;
- default:
- {
- ullPrice = SASH_GRADE_1_PRICE;
- }
- break;
- }
- return ullPrice;
- }
- BYTE CHARACTER::CheckEmptyMaterialSlot()
- {
- LPITEM* pkItemMaterial;
- pkItemMaterial = GetSashMaterials();
- for (int i = 0; i < SASH_WINDOW_MAX_MATERIALS; ++i)
- {
- if (!pkItemMaterial[i])
- {
- return i;
- }
- }
- return UCHAR_MAX;
- }
- void CHARACTER::GetSashCombineResult (DWORD & dwItemVnum, DWORD & dwMinAbs, DWORD & dwMaxAbs)
- {
- LPITEM* pkItemMaterial;
- pkItemMaterial = GetSashMaterials();
- if (m_bSashCombination)
- {
- if ((pkItemMaterial[0]) && (pkItemMaterial[1]))
- {
- long lVal = pkItemMaterial[0]->GetValue (SASH_GRADE_VALUE_FIELD);
- if (lVal == 4)
- {
- dwItemVnum = pkItemMaterial[0]->GetOriginalVnum();
- dwMinAbs = pkItemMaterial[0]->GetSocket (SASH_ABSORPTION_SOCKET);
- DWORD dwMaxAbsCalc = (dwMinAbs + SASH_GRADE_4_ABS_RANGE > SASH_GRADE_4_ABS_MAX ? SASH_GRADE_4_ABS_MAX : (dwMinAbs + SASH_GRADE_4_ABS_RANGE));
- dwMaxAbs = dwMaxAbsCalc;
- }
- else
- {
- DWORD dwMaskVnum = pkItemMaterial[0]->GetOriginalVnum();
- TItemTable* pTable = ITEM_MANAGER::instance().GetTable (dwMaskVnum + 1);
- if (pTable)
- {
- dwMaskVnum += 1;
- }
- dwItemVnum = dwMaskVnum;
- switch (lVal)
- {
- case 2:
- {
- dwMinAbs = SASH_GRADE_3_ABS;
- dwMaxAbs = SASH_GRADE_3_ABS;
- }
- break;
- case 3:
- {
- dwMinAbs = SASH_GRADE_4_ABS_MIN;
- dwMaxAbs = SASH_GRADE_4_ABS_MAX_COMB;
- }
- break;
- default:
- {
- dwMinAbs = SASH_GRADE_2_ABS;
- dwMaxAbs = SASH_GRADE_2_ABS;
- }
- break;
- }
- }
- }
- else
- {
- dwItemVnum = 0;
- dwMinAbs = 0;
- dwMaxAbs = 0;
- }
- }
- else
- {
- if ((pkItemMaterial[0]) && (pkItemMaterial[1]))
- {
- dwItemVnum = pkItemMaterial[0]->GetOriginalVnum();
- dwMinAbs = pkItemMaterial[0]->GetSocket (SASH_ABSORPTION_SOCKET);
- dwMaxAbs = dwMinAbs;
- }
- else
- {
- dwItemVnum = 0;
- dwMinAbs = 0;
- dwMaxAbs = 0;
- }
- }
- }
- void CHARACTER::AddSashMaterial (TItemPos tPos, BYTE bPos)
- {
- if (bPos >= SASH_WINDOW_MAX_MATERIALS)
- {
- if (bPos == UCHAR_MAX)
- {
- bPos = CheckEmptyMaterialSlot();
- if (bPos >= SASH_WINDOW_MAX_MATERIALS)
- {
- return;
- }
- }
- else
- {
- return;
- }
- }
- LPITEM pkItem = GetItem (tPos);
- if (!pkItem)
- {
- return;
- }
- else if ((pkItem->GetCell() >= INVENTORY_MAX_NUM) || (pkItem->IsEquipped()) || (tPos.IsBeltInventoryPosition()) || (pkItem->IsDragonSoul()))
- {
- return;
- }
- else if ((pkItem->GetType() != ITEM_COSTUME) && (m_bSashCombination))
- {
- return;
- }
- else if ((pkItem->GetType() != ITEM_COSTUME) && (bPos == 0) && (m_bSashAbsorption))
- {
- return;
- }
- #ifdef ENABLE_BINDING_SYSTEM
- else if (pkItem->IsSealed())
- {
- ChatInfoTrans(("ITEM_IS_SEALED_CANNOT_DO"));
- return;
- }
- #endif
- else if (pkItem->isLocked())
- {
- ChatInfoTrans(("__SASH__YOU_CAN_NOT_ADD_BLOCK_ITEMS"));
- return;
- }
- else if ((m_bSashCombination) && (bPos == 1) && (!SashIsSameGrade (pkItem->GetValue (SASH_GRADE_VALUE_FIELD))))
- {
- ChatInfoTrans(("__SASH__YOU_CAN_ONLY_COMBINE_SASH_OF_THE_SAME_GRADES"));
- return;
- }
- else if ((m_bSashCombination) && (pkItem->GetSocket (SASH_ABSORPTION_SOCKET) >= SASH_GRADE_4_ABS_MAX))
- {
- ChatInfoTrans(("__SASH__THIS_SASH_HAS_ALREADY_RECIEVED_THE_MAXIMUM_POINTS_OF_ABSORTION_BONUS"));
- return;
- }
- else if ((bPos == 1) && (m_bSashAbsorption))
- {
- if ((pkItem->GetType() != ITEM_WEAPON) && (pkItem->GetType() != ITEM_ARMOR))
- {
- ChatInfoTrans(("__SASH__YOU_CAN_ONLY_ABSORB_BONUSES_FROM_WEAPON_AND_ARMOR"));
- return;
- }
- else if ((pkItem->GetType() == ITEM_ARMOR) && (pkItem->GetSubType() != ARMOR_BODY))
- {
- ChatInfoTrans(("__SASH__YOU_CAN_ONLY_ABSORB_BONUSES_FROM_WEAPON_AND_ARMOR"));
- return;
- }
- }
- else if ((pkItem->GetSubType() != COSTUME_SASH) && (m_bSashCombination))
- {
- return;
- }
- else if ((pkItem->GetSubType() != COSTUME_SASH) && (bPos == 0) && (m_bSashAbsorption))
- {
- return;
- }
- else if ((pkItem->GetSocket (SASH_ABSORBED_SOCKET) > 0) && (bPos == 0) && (m_bSashAbsorption))
- {
- return;
- }
- LPITEM* pkItemMaterial;
- pkItemMaterial = GetSashMaterials();
- if ((bPos == 1) && (!pkItemMaterial[0]))
- {
- return;
- }
- if (pkItemMaterial[bPos])
- {
- return;
- }
- pkItemMaterial[bPos] = pkItem;
- pkItemMaterial[bPos]->Lock (true);
- DWORD dwItemVnum, dwMinAbs, dwMaxAbs;
- GetSashCombineResult (dwItemVnum, dwMinAbs, dwMaxAbs);
- TPacketSash sPacket;
- sPacket.header = HEADER_GC_SASH;
- sPacket.subheader = SASH_SUBHEADER_GC_ADDED;
- sPacket.bWindow = m_bSashCombination == true ? true : false;
- sPacket.ullPrice = GetSashCombinePrice (pkItem->GetValue (SASH_GRADE_VALUE_FIELD));
- sPacket.bPos = bPos;
- sPacket.tPos = tPos;
- sPacket.dwItemVnum = dwItemVnum;
- sPacket.dwMinAbs = dwMinAbs;
- sPacket.dwMaxAbs = dwMaxAbs;
- GetDesc()->Packet (&sPacket, sizeof (TPacketSash));
- }
- void CHARACTER::RemoveSashMaterial (BYTE bPos)
- {
- if (bPos >= SASH_WINDOW_MAX_MATERIALS)
- {
- return;
- }
- LPITEM* pkItemMaterial;
- pkItemMaterial = GetSashMaterials();
- unsigned long long ullPrice = 0;
- if (bPos == 1)
- {
- if (pkItemMaterial[bPos])
- {
- pkItemMaterial[bPos]->Lock (false);
- pkItemMaterial[bPos] = NULL;
- }
- if (pkItemMaterial[0])
- {
- ullPrice = GetSashCombinePrice (pkItemMaterial[0]->GetValue (SASH_GRADE_VALUE_FIELD));
- }
- }
- else
- {
- ClearSashMaterials();
- }
- TItemPos tPos;
- tPos.window_type = INVENTORY;
- tPos.cell = 0;
- TPacketSash sPacket;
- sPacket.header = HEADER_GC_SASH;
- sPacket.subheader = SASH_SUBHEADER_GC_REMOVED;
- sPacket.bWindow = m_bSashCombination == true ? true : false;
- sPacket.ullPrice = ullPrice;
- sPacket.bPos = bPos;
- sPacket.tPos = tPos;
- sPacket.dwItemVnum = 0;
- sPacket.dwMinAbs = 0;
- sPacket.dwMaxAbs = 0;
- GetDesc()->Packet (&sPacket, sizeof (TPacketSash));
- }
- BYTE CHARACTER::CanRefineSashMaterials()
- {
- BYTE bReturn = 0;
- LPITEM* pkItemMaterial;
- pkItemMaterial = GetSashMaterials();
- if (m_bSashCombination)
- {
- for (int i = 0; i < SASH_WINDOW_MAX_MATERIALS; ++i)
- {
- if (pkItemMaterial[i])
- {
- if ((pkItemMaterial[i]->GetType() == ITEM_COSTUME) && (pkItemMaterial[i]->GetSubType() == COSTUME_SASH))
- {
- bReturn = 1;
- }
- else
- {
- bReturn = 0;
- break;
- }
- }
- else
- {
- bReturn = 0;
- break;
- }
- }
- }
- else if (m_bSashAbsorption)
- {
- if ((pkItemMaterial[0]) && (pkItemMaterial[1]))
- {
- if ((pkItemMaterial[0]->GetType() == ITEM_COSTUME) && (pkItemMaterial[0]->GetSubType() == COSTUME_SASH))
- {
- bReturn = 2;
- }
- else
- {
- bReturn = 0;
- }
- if ((pkItemMaterial[1]->GetType() == ITEM_WEAPON) || ((pkItemMaterial[1]->GetType() == ITEM_ARMOR) && (pkItemMaterial[1]->GetSubType() == ARMOR_BODY)))
- {
- bReturn = 2;
- }
- else
- {
- bReturn = 0;
- }
- if (pkItemMaterial[0]->GetSocket (SASH_ABSORBED_SOCKET) > 0)
- {
- bReturn = 0;
- }
- }
- else
- {
- bReturn = 0;
- }
- }
- return bReturn;
- }
- void CHARACTER::RefineSashMaterials()
- {
- BYTE bCan = CanRefineSashMaterials();
- if (bCan == 0)
- {
- return;
- }
- LPITEM* pkItemMaterial;
- pkItemMaterial = GetSashMaterials();
- DWORD dwItemVnum, dwMinAbs, dwMaxAbs;
- GetSashCombineResult (dwItemVnum, dwMinAbs, dwMaxAbs);
- unsigned long long ullPrice = GetSashCombinePrice (pkItemMaterial[0]->GetValue (SASH_GRADE_VALUE_FIELD));
- if (bCan == 1)
- {
- int iSuccessChance = 0;
- long lVal = pkItemMaterial[0]->GetValue (SASH_GRADE_VALUE_FIELD);
- switch (lVal)
- {
- case 2:
- {
- iSuccessChance = SASH_COMBINE_GRADE_2;
- }
- break;
- case 3:
- {
- iSuccessChance = SASH_COMBINE_GRADE_3;
- }
- break;
- case 4:
- {
- iSuccessChance = SASH_COMBINE_GRADE_4;
- }
- break;
- default:
- {
- iSuccessChance = SASH_COMBINE_GRADE_1;
- }
- break;
- }
- if (GetGold() < ullPrice)
- {
- ChatInfoTrans(("ITEM_REFINING_NOT_ENOUGH_GOLD"));
- return;
- }
- int iChance = number (1, 100);
- bool bSucces = (iChance <= iSuccessChance ? true : false);
- if (bSucces)
- {
- LPITEM pkItem = ITEM_MANAGER::instance().CreateItem (dwItemVnum, 1, 0, false);
- if (!pkItem)
- {
- sys_err ("%d can't be created.", dwItemVnum);
- return;
- }
- ITEM_MANAGER::CopyAllAttrTo (pkItemMaterial[0], pkItem);
- DWORD dwAbs = (dwMinAbs == dwMaxAbs ? dwMinAbs : number (dwMinAbs + 1, dwMaxAbs));
- pkItem->SetSocket (SASH_ABSORPTION_SOCKET, dwAbs);
- pkItem->SetSocket (SASH_ABSORBED_SOCKET, pkItemMaterial[0]->GetSocket (SASH_ABSORBED_SOCKET));
- ChangeGold(-ullPrice);
- DBManager::instance().SendMoneyLog (MONEY_LOG_REFINE, pkItemMaterial[0]->GetVnum(), -ullPrice);
- uint16_t wCell = pkItemMaterial[0]->GetCell();
- ITEM_MANAGER::instance().RemoveItem (pkItemMaterial[0], "COMBINE (REFINE SUCCESS)");
- ITEM_MANAGER::instance().RemoveItem (pkItemMaterial[1], "COMBINE (REFINE SUCCESS)");
- pkItem->AddToCharacter (this, TItemPos (INVENTORY, wCell));
- ITEM_MANAGER::instance().FlushDelayedSave (pkItem);
- pkItem->AttrLog();
- if (lVal == 4)
- {
- ChatInfoTrans(("__SASH__NEW_ABSORTION_RATE_%d%"), dwAbs);
- }
- else
- {
- ChatInfoTrans(("__SASH__SUCCES"));
- }
- EffectPacket (SE_EFFECT_SASH_SUCCEDED);
- LogManager::instance().SashLog (GetPlayerID(), GetX(), GetY(), dwItemVnum, pkItem->GetID(), 1, dwAbs, 1);
- ClearSashMaterials();
- }
- else
- {
- ChangeGold(-ullPrice);
- DBManager::instance().SendMoneyLog (MONEY_LOG_REFINE, pkItemMaterial[0]->GetVnum(), -ullPrice);
- ITEM_MANAGER::instance().RemoveItem (pkItemMaterial[1], "COMBINE (REFINE FAIL)");
- if (lVal == 4)
- {
- ChatInfoTrans(("__SASH__NEW_ABSORTION_RATE_%d%"), pkItemMaterial[0]->GetSocket(SASH_ABSORPTION_SOCKET));
- }
- else
- {
- ChatInfoTrans(("__SASH__FAIL"));
- }
- LogManager::instance().SashLog (GetPlayerID(), GetX(), GetY(), dwItemVnum, 0, 0, 0, 0);
- pkItemMaterial[1] = NULL;
- }
- TItemPos tPos;
- tPos.window_type = INVENTORY;
- tPos.cell = 0;
- TPacketSash sPacket;
- sPacket.header = HEADER_GC_SASH;
- sPacket.subheader = SASH_SUBHEADER_GC_REFINED;
- sPacket.bWindow = m_bSashCombination == true ? true : false;
- sPacket.ullPrice = ullPrice;
- sPacket.bPos = 0;
- sPacket.tPos = tPos;
- sPacket.dwItemVnum = 0;
- sPacket.dwMinAbs = 0;
- if (bSucces)
- {
- sPacket.dwMaxAbs = 100;
- }
- else
- {
- sPacket.dwMaxAbs = 0;
- }
- GetDesc()->Packet (&sPacket, sizeof (TPacketSash));
- }
- else
- {
- pkItemMaterial[1]->CopyAttributeTo (pkItemMaterial[0]);
- pkItemMaterial[0]->SetSocket (SASH_ABSORBED_SOCKET, pkItemMaterial[1]->GetOriginalVnum());
- for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; ++i)
- {
- if (pkItemMaterial[0]->GetAttributeValue (i) < 0)
- {
- pkItemMaterial[0]->SetForceAttribute (i, pkItemMaterial[0]->GetAttributeType (i), 0);
- }
- }
- ITEM_MANAGER::instance().RemoveItem (pkItemMaterial[1], "ABSORBED (REFINE SUCCESS)");
- ITEM_MANAGER::instance().FlushDelayedSave (pkItemMaterial[0]);
- pkItemMaterial[0]->AttrLog();
- ChatInfoTrans(("__SASH__SUCCES"));
- ClearSashMaterials();
- TItemPos tPos;
- tPos.window_type = INVENTORY;
- tPos.cell = 0;
- TPacketSash sPacket;
- sPacket.header = HEADER_GC_SASH;
- sPacket.subheader = SASH_SUBHEADER_GC_REFINED;
- sPacket.bWindow = m_bSashCombination == true ? true : false;
- sPacket.ullPrice = ullPrice;
- sPacket.bPos = UCHAR_MAX;
- sPacket.tPos = tPos;
- sPacket.dwItemVnum = 0;
- sPacket.dwMinAbs = 0;
- sPacket.dwMaxAbs = 1;
- GetDesc()->Packet (&sPacket, sizeof (TPacketSash));
- }
- }
- bool CHARACTER::CleanSashAttr (LPITEM pkItem, LPITEM pkTarget)
- {
- if (!CanHandleItem())
- {
- return false;
- }
- else if ((!pkItem) || (!pkTarget))
- {
- return false;
- }
- else if ((pkTarget->GetType() != ITEM_COSTUME) && (pkTarget->GetSubType() != COSTUME_SASH))
- {
- return false;
- }
- if (pkTarget->GetSocket (SASH_ABSORBED_SOCKET) <= 0)
- {
- return false;
- }
- pkTarget->SetSocket (SASH_ABSORBED_SOCKET, 0);
- for (int i = 0; i < ITEM_ATTRIBUTE_MAX_NUM; ++i)
- {
- pkTarget->SetForceAttribute(i, 0, 0);
- }
- pkItem->SetCount((uint16_t)pkItem->GetCount() - 1);
- return true;
- }
- #endif
- bool CHARACTER::CanFall()
- {
- if (IsAffectFlag(AFF_CHEONGEUN) && !IsAffectFlag(AFF_CHEONGEUN_WITH_FALL))
- {
- return false;
- }
- if (IsImmune(IMMUNE_FALL))
- {
- return false;
- }
- if (!IsPC() &&
- GetRaceNum() == 1097 &&
- GetRaceNum() == 1098 &&
- GetRaceNum() == 1099 &&
- GetRaceNum() == 2496 &&
- GetRaceNum() == 2497 &&
- GetRaceNum() == 2498
- )
- return false;
- return true;
- }
- bool CHARACTER::IsInSafezone() const
- {
- LPSECTREE sectree = GetSectree();
- return (sectree && sectree->IsAttr(GetX(), GetY(), ATTR_BANPK));
- }
- void CHARACTER::LoadActivity(TActivityTable * data)
- {
- if (!m_activityHandler)
- {
- return;
- }
- m_activityHandler->Load(data);
- }
- int CHARACTER::GetActivity() const
- {
- if (!IsPC())
- {
- sys_err("Trying to get activity from a non-player character? (%lu)", GetRaceNum());
- return 0;
- }
- if (!m_activityHandler)
- {
- sys_err("No activity handler!", GetPlayerID());
- return 0;
- }
- return m_activityHandler->GetActivity();
- }
- void CHARACTER::ApplyOnDuels(std::function<void(CPVP*)> f)
- {
- std::unordered_set<CPVP*> activeDuels = CPVPManager::instance().GetMyDuels(this);
- for (CPVP* duel : activeDuels)
- {
- if (duel->IsFight())
- {
- f(duel);
- }
- }
- }
- #ifdef ENABLE_GLOBAL_LANGUAGE
- std::string CHARACTER::GetLang()
- {
- if (GetDesc() != NULL)
- {
- return GetDesc()->GetAccountTable().language;
- }
- return {};
- }
- void CHARACTER::SetLanguage(std::string language)
- {
- if (GetDesc() != NULL)
- {
- strlcpy(GetDesc()->GetAccountTable().language, language.c_str(), sizeof(GetDesc()->GetAccountTable().language));
- }
- }
- #endif
- void CHARACTER::ChangeChannel(DWORD channelId)
- {
- //* START DUPLICATION FIX
- //* prevent problems about duplication of items
- //* using safebox/exchange/shop/acce/aura/offlineshop
- if(!CanWarp())
- {
- return;
- }
- //* END DUPLICATION FIX
- long lAddr;
- long lMapIndex;
- uint16_t wPort;
- long x = this->GetX();
- long y = this->GetY();
- 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;
- }
- if(lMapIndex >= 10000)
- {
- this->ChatInfoTrans(("YOU_CANNOT_CHANGE_CH_WHILE_IN_A_DUNGEON"));
- return;
- }
- Stop();
- Save();
- if(GetSectree())
- {
- GetSectree()->RemoveEntity(this);
- ViewCleanup();
- EncodeRemovePacket(this);
- }
- TPacketGCWarp p;
- p.bHeader = HEADER_GC_WARP;
- p.lX = x;
- p.lY = y;
- p.lAddr = lAddr;
- p.wPort = (wPort - 1000*(g_bChannel-1) + 1000*(channelId-1));
- GetDesc()->Packet(&p, sizeof(TPacketGCWarp));
- }
- #ifdef __ENABLE_NEW_OFFLINESHOP__
- void CHARACTER::SetShopSafebox(offlineshop::CShopSafebox* pk)
- {
- if(m_pkShopSafebox && pk==NULL)
- {
- m_pkShopSafebox->SetOwner(NULL);
- }
- else if(m_pkShopSafebox==NULL && pk)
- {
- pk->SetOwner(this);
- }
- m_pkShopSafebox = pk;
- }
- #endif
- #ifdef __ENABLE_COMMON_DROP_IN_INVENTORY__
- static bool FN_check_item_socket(LPITEM item)
- {
- for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i)
- {
- if (item->GetSocket(i) != item->GetProto()->alSockets[i])
- {
- return false;
- }
- }
- return true;
- }
- bool CHARACTER::NewAutoGiveStackDefaultInventory(LPITEM item)
- {
- if(!item->IsStackable() || IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK) || CountSpecifyItem(item->GetVnum()) == 0)
- {
- TItemPos pos;
- if(!CanTakeInventoryItem(item, &pos))
- {
- return false;
- }
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToCharacter(this, pos);
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- return true;
- }
- for (int i = 0; i < INVENTORY_MAX_NUM; ++i)
- {
- LPITEM itemSearch = GetInventoryItem(i);
- if(itemSearch && item->GetVnum() == itemSearch->GetVnum())
- {
- uint16_t count = itemSearch->GetCount();
- if(count + item->GetCount() > ITEM_MAX_COUNT)
- {
- itemSearch->SetCount(ITEM_MAX_COUNT);
- item->SetCount(item->GetCount() - (ITEM_MAX_COUNT - count ));
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- }
- else
- {
- itemSearch->SetCount(count + item->GetCount());
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- M2_DESTROY_ITEM(item);
- return true;
- }
- }
- }
- TItemPos pos;
- if(!CanTakeInventoryItem(item, &pos))
- {
- PIXEL_POSITION pixel = GetXYZ();
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToGround(GetMapIndex(), pixel);
- if (!CBattleArena::instance().IsBattleArenaMap(GetMapIndex()))
- {
- item->SetOwnership(this);
- }
- item->StartDestroyEvent();
- }
- else
- {
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToCharacter(this, pos);
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- }
- return true;
- }
- bool CHARACTER::NewAutoGiveStackDragonSoulInventory(LPITEM item)
- {
- if(!item->IsStackable() || IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK) || CountSpecifyItem(item->GetVnum()) == 0)
- {
- TItemPos pos;
- if(!CanTakeInventoryItem(item, &pos))
- {
- return false;
- }
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToCharacter(this, pos);
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- return true;
- }
- for (int i = 0; i < DRAGON_SOUL_BOX_SIZE; ++i)
- {
- LPITEM itemSearch = GetDragonSoulItem(i);
- if(itemSearch && item->GetVnum() == itemSearch->GetVnum())
- {
- uint16_t count = itemSearch->GetCount();
- if(count + item->GetCount() > ITEM_MAX_COUNT)
- {
- itemSearch->SetCount(ITEM_MAX_COUNT);
- item->SetCount(item->GetCount() - (ITEM_MAX_COUNT - count ));
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- }
- else
- {
- itemSearch->SetCount(count + item->GetCount());
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- M2_DESTROY_ITEM(item);
- return true;
- }
- }
- }
- TItemPos pos;
- if(!CanTakeInventoryItem(item, &pos))
- {
- PIXEL_POSITION pixel = GetXYZ();
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToGround(GetMapIndex(), pixel);
- if (!CBattleArena::instance().IsBattleArenaMap(GetMapIndex()))
- {
- item->SetOwnership(this);
- }
- item->StartDestroyEvent();
- }
- else
- {
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToCharacter(this, pos);
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- }
- return true;
- }
- #ifdef ENABLE_SPECIAL_STORAGE
- bool CHARACTER::NewAutoGiveStackBookInventory(LPITEM item)
- {
- if(!item->IsStackable() || IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK) || CountSpecifyItem(item->GetVnum()) == 0)
- {
- TItemPos pos;
- if(!CanTakeInventoryItem(item, &pos))
- {
- return false;
- }
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- item->AddToCharacter(this, pos);
- return true;
- }
- for (int i = SKILL_BOOK_INVENTORY_SLOT_START; i < SKILL_BOOK_INVENTORY_SLOT_END; ++i)
- {
- LPITEM itemSearch = GetInventoryItem(i);
- if(itemSearch && item->GetVnum() == itemSearch->GetVnum() && (FN_check_item_socket(item) || itemSearch->GetSocket(0) == item->GetSocket(0)))
- {
- uint16_t count = itemSearch->GetCount();
- if(count + item->GetCount() > ITEM_MAX_COUNT)
- {
- itemSearch->SetCount(ITEM_MAX_COUNT);
- item->SetCount(item->GetCount() - (ITEM_MAX_COUNT - count ));
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- }
- else
- {
- itemSearch->SetCount(count + item->GetCount());
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- M2_DESTROY_ITEM(item);
- return true;
- }
- }
- }
- TItemPos pos;
- if(!CanTakeInventoryItem(item, &pos))
- {
- PIXEL_POSITION pixel = GetXYZ();
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToGround(GetMapIndex(), pixel);
- if (!CBattleArena::instance().IsBattleArenaMap(GetMapIndex()))
- {
- item->SetOwnership(this);
- }
- item->StartDestroyEvent();
- }
- else
- {
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToCharacter(this, pos);
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- }
- return true;
- }
- bool CHARACTER::NewAutoGiveStackUpgradeItemsInventory(LPITEM item)
- {
- if(!item->IsStackable() || IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK) || CountSpecifyItem(item->GetVnum()) == 0)
- {
- TItemPos pos;
- if(!CanTakeInventoryItem(item, &pos))
- {
- return false;
- }
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToCharacter(this, pos);
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- return true;
- }
- for (int i = UPGRADE_ITEMS_INVENTORY_SLOT_START; i < UPGRADE_ITEMS_INVENTORY_SLOT_END; ++i)
- {
- LPITEM itemSearch = GetInventoryItem(i);
- if(itemSearch && item->GetVnum() == itemSearch->GetVnum())
- {
- uint16_t count = itemSearch->GetCount();
- if(count + item->GetCount() > ITEM_MAX_COUNT)
- {
- itemSearch->SetCount(ITEM_MAX_COUNT);
- item->SetCount(item->GetCount() - (ITEM_MAX_COUNT - count ));
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- }
- else
- {
- itemSearch->SetCount(count + item->GetCount());
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- M2_DESTROY_ITEM(item);
- return true;
- }
- }
- }
- TItemPos pos;
- if(!CanTakeInventoryItem(item, &pos))
- {
- PIXEL_POSITION pixel = GetXYZ();
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToGround(GetMapIndex(), pixel);
- if (!CBattleArena::instance().IsBattleArenaMap(GetMapIndex()))
- {
- item->SetOwnership(this);
- }
- item->StartDestroyEvent();
- }
- else
- {
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToCharacter(this, pos);
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- }
- return true;
- }
- bool CHARACTER::NewAutoGiveStackStoneInventory(LPITEM item)
- {
- if(!item->IsStackable() || IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK) || CountSpecifyItem(item->GetVnum()) == 0)
- {
- TItemPos pos;
- if(!CanTakeInventoryItem(item, &pos))
- {
- return false;
- }
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToCharacter(this, pos);
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- return true;
- }
- for (int i = STONE_INVENTORY_SLOT_START; i < STONE_INVENTORY_SLOT_END; ++i)
- {
- LPITEM itemSearch = GetInventoryItem(i);
- if(itemSearch && item->GetVnum() == itemSearch->GetVnum())
- {
- uint16_t count = itemSearch->GetCount();
- if(count + item->GetCount() > ITEM_MAX_COUNT)
- {
- itemSearch->SetCount(ITEM_MAX_COUNT);
- item->SetCount(item->GetCount() - (ITEM_MAX_COUNT - count ));
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- }
- else
- {
- itemSearch->SetCount(count + item->GetCount());
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- M2_DESTROY_ITEM(item);
- return true;
- }
- }
- }
- TItemPos pos;
- if(!CanTakeInventoryItem(item, &pos))
- {
- PIXEL_POSITION pixel = GetXYZ();
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToGround(GetMapIndex(), pixel);
- if (!CBattleArena::instance().IsBattleArenaMap(GetMapIndex()))
- {
- item->SetOwnership(this);
- }
- item->StartDestroyEvent();
- }
- else
- {
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToCharacter(this, pos);
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- }
- return true;
- }
- bool CHARACTER::NewAutoGiveStackBonusInventory(LPITEM item)
- {
- if(!item->IsStackable() || IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK) || CountSpecifyItem(item->GetVnum()) == 0)
- {
- TItemPos pos;
- if(!CanTakeInventoryItem(item, &pos))
- {
- return false;
- }
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToCharacter(this, pos);
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- return true;
- }
- for (int i = BONUS_INVENTORY_SLOT_START; i < BONUS_INVENTORY_SLOT_END; ++i)
- {
- LPITEM itemSearch = GetInventoryItem(i);
- if(itemSearch && item->GetVnum() == itemSearch->GetVnum())
- {
- uint16_t count = itemSearch->GetCount();
- if(count + item->GetCount() > ITEM_MAX_COUNT)
- {
- itemSearch->SetCount(ITEM_MAX_COUNT);
- item->SetCount(item->GetCount() - (ITEM_MAX_COUNT - count ));
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- }
- else
- {
- itemSearch->SetCount(count + item->GetCount());
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- M2_DESTROY_ITEM(item);
- return true;
- }
- }
- }
- TItemPos pos;
- if(!CanTakeInventoryItem(item, &pos))
- {
- PIXEL_POSITION pixel = GetXYZ();
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToGround(GetMapIndex(), pixel);
- if (!CBattleArena::instance().IsBattleArenaMap(GetMapIndex()))
- {
- item->SetOwnership(this);
- }
- item->StartDestroyEvent();
- }
- else
- {
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToCharacter(this, pos);
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- }
- return true;
- }
- bool CHARACTER::NewAutoGiveStackChestInventory(LPITEM item)
- {
- if(!item->IsStackable() || IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK) || CountSpecifyItem(item->GetVnum()) == 0)
- {
- TItemPos pos;
- if(!CanTakeInventoryItem(item, &pos))
- {
- return false;
- }
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToCharacter(this, pos);
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- return true;
- }
- for (int i = CHEST_INVENTORY_SLOT_START; i < CHEST_INVENTORY_SLOT_END; ++i)
- {
- LPITEM itemSearch = GetInventoryItem(i);
- if(itemSearch && item->GetVnum() == itemSearch->GetVnum())
- {
- uint16_t count = itemSearch->GetCount();
- if(count + item->GetCount() > ITEM_MAX_COUNT)
- {
- itemSearch->SetCount(ITEM_MAX_COUNT);
- item->SetCount(item->GetCount() - (ITEM_MAX_COUNT - count ));
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- if (item->GetVnum() == 50037 || item->GetVnum() == 50033 || item->GetVnum() == 50034 || item->GetVnum() == 50134 || item->GetVnum() == 50135) {}
- else if (item->GetVnum() == itemSearch->GetVnum())
- {
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- }
- }
- else
- {
- itemSearch->SetCount(count + item->GetCount());
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- if (item->GetVnum() == 50037 || item->GetVnum() == 50033 || item->GetVnum() == 50034 || item->GetVnum() == 50134 || item->GetVnum() == 50135) {}
- else if (item->GetVnum() == itemSearch->GetVnum())
- {
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- }
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- M2_DESTROY_ITEM(item);
- return true;
- }
- }
- }
- TItemPos pos;
- if(!CanTakeInventoryItem(item, &pos))
- {
- PIXEL_POSITION pixel = GetXYZ();
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToGround(GetMapIndex(), pixel);
- if (!CBattleArena::instance().IsBattleArenaMap(GetMapIndex()))
- {
- item->SetOwnership(this);
- }
- item->StartDestroyEvent();
- }
- else
- {
- if(item->GetOwner())
- {
- item->RemoveFromCharacter();
- }
- item->AddToCharacter(this, pos);
- const std::string& item_name = find_itemnames(item->GetVnum(), GetLang());
- ChatInfoTrans(("GAINED_%s"), item_name.c_str());
- }
- return true;
- }
- #endif
- bool CHARACTER::NewAutoGiveStack(LPITEM item)
- {
- if (item->IsDragonSoul())
- {
- return NewAutoGiveStackDragonSoulInventory(item);
- }
- #ifdef ENABLE_SPECIAL_STORAGE
- else if (item->IsSkillBook())
- {
- return NewAutoGiveStackBookInventory(item);
- }
- else if (item->IsUpgradeItem())
- {
- return NewAutoGiveStackUpgradeItemsInventory(item);
- }
- else if (item->IsStone())
- {
- return NewAutoGiveStackStoneInventory(item);
- }
- else if (item->IsBonus())
- {
- return NewAutoGiveStackBonusInventory(item);
- }
- else if (item->IsChest())
- {
- return NewAutoGiveStackChestInventory(item);
- }
- #endif
- else
- {
- return NewAutoGiveStackDefaultInventory(item);
- }
- }
- #endif
- /*** Ikarus function created for offlineshop & special inventory ***/
- bool CHARACTER::CanTakeInventoryItem(LPITEM item, TItemPos* cell)
- {
- int iEmpty=-1;
- if (item->IsDragonSoul())
- {
- cell->window_type = DRAGON_SOUL_INVENTORY;
- cell->cell = iEmpty = GetEmptyDragonSoulInventory(item);
- }
- #ifdef ENABLE_SPECIAL_STORAGE
- else if (item->IsSkillBook())
- {
- cell->window_type = INVENTORY;
- cell->cell = iEmpty = GetEmptySkillBookInventory(item->GetSize());
- }
- else if (item->IsUpgradeItem())
- {
- cell->window_type = INVENTORY;
- cell->cell = iEmpty = GetEmptyUpgradeItemsInventory(item->GetSize());
- }
- else if (item->IsStone())
- {
- cell->window_type = INVENTORY;
- cell->cell = iEmpty = GetEmptyStoneInventory(item->GetSize());
- }
- else if (item->IsBonus())
- {
- cell->window_type = INVENTORY;
- cell->cell = iEmpty = GetEmptyBonusInventory(item->GetSize());
- }
- else if (item->IsChest())
- {
- cell->window_type = INVENTORY;
- cell->cell = iEmpty = GetEmptyChestInventory(item->GetSize());
- }
- #endif
- else
- {
- cell->window_type = INVENTORY;
- cell->cell = iEmpty = GetEmptyInventory(item->GetSize());
- }
- return iEmpty != -1;
- }
- /*** End ***/
- #ifdef ENABLE_BATTLE_PASS
- void CHARACTER::LoadBattlePass(DWORD dwCount, TPlayerBattlePassMission * data)
- {
- m_bIsLoadedBattlePass = false;
- for (int i = 0; i < dwCount; ++i, ++data)
- {
- TPlayerBattlePassMission * newMission = new TPlayerBattlePassMission;
- newMission->dwPlayerId = data->dwPlayerId;
- newMission->dwMissionId = data->dwMissionId;
- newMission->dwBattlePassId = data->dwBattlePassId;
- newMission->dwExtraInfo = data->dwExtraInfo;
- newMission->bCompleted = data->bCompleted;
- newMission->bIsUpdated = data->bIsUpdated;
- m_listBattlePass.push_back(newMission);
- }
- m_bIsLoadedBattlePass = true;
- }
- DWORD CHARACTER::GetMissionProgress(DWORD dwMissionID, DWORD dwBattlePassID)
- {
- auto it = m_listBattlePass.begin();
- while (it != m_listBattlePass.end())
- {
- TPlayerBattlePassMission * pkMission = *it++;
- if(pkMission->dwMissionId == dwMissionID && pkMission->dwBattlePassId == dwBattlePassID)
- return pkMission->dwExtraInfo;
- }
- return 0;
- }
- bool CHARACTER::IsCompletedMission(BYTE bMissionType)
- {
- auto it = m_listBattlePass.begin();
- while (it != m_listBattlePass.end())
- {
- TPlayerBattlePassMission * pkMission = *it++;
- if(pkMission->dwMissionId == bMissionType)
- return (pkMission->bCompleted ? true : false);
- }
- return false;
- }
- void CHARACTER::UpdateMissionProgress(DWORD dwMissionID, DWORD dwBattlePassID, DWORD dwUpdateValue, DWORD dwTotalValue, bool isOverride)
- {
- if(!m_bIsLoadedBattlePass)
- return;
- bool foundMission = false;
- DWORD dwSaveProgress = 0;
- auto it = m_listBattlePass.begin();
- while (it != m_listBattlePass.end())
- {
- TPlayerBattlePassMission * pkMission = *it++;
- if(pkMission->dwMissionId == dwMissionID && pkMission->dwBattlePassId == dwBattlePassID)
- {
- pkMission->bIsUpdated = 1;
- if(isOverride)
- pkMission->dwExtraInfo = dwUpdateValue;
- else
- pkMission->dwExtraInfo += dwUpdateValue;
- if(pkMission->dwExtraInfo >= dwTotalValue)
- {
- pkMission->dwExtraInfo = dwTotalValue;
- pkMission->bCompleted = 1;
- std::string stMissionName = CBattlePass::instance().GetMissionNameByType(pkMission->dwMissionId);
- std::string stBattlePassName = CBattlePass::instance().GetBattlePassNameByID(pkMission->dwBattlePassId);
- ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT_TRANS(("__YOU_SUCCESFULLY_FINISHED_%s_MISSION_FROM_BATTLE_PASS_%s__"), GetLang()), LC_TEXT_TRANS((stMissionName.c_str()), GetLang()), LC_TEXT_TRANS((stBattlePassName.c_str()), GetLang()));
- CBattlePass::instance().BattlePassRewardMission(this, dwMissionID, dwBattlePassID);
- }
- dwSaveProgress = pkMission->dwExtraInfo;
- foundMission = true;
- break;
- }
- }
- if(!foundMission)
- {
- TPlayerBattlePassMission * newMission = new TPlayerBattlePassMission;
- newMission->dwPlayerId = GetPlayerID();
- newMission->dwMissionId = dwMissionID;
- newMission->dwBattlePassId = dwBattlePassID;
- if(dwUpdateValue >= dwTotalValue)
- {
- newMission->dwExtraInfo = dwTotalValue;
- newMission->bCompleted = 1;
- CBattlePass::instance().BattlePassRewardMission(this, dwMissionID, dwBattlePassID);
- dwSaveProgress = dwTotalValue;
- }
- else
- {
- newMission->dwExtraInfo = dwUpdateValue;
- newMission->bCompleted = 0;
- dwSaveProgress = dwUpdateValue;
- }
- newMission->bIsUpdated = 1;
- m_listBattlePass.push_back(newMission);
- }
- if(!GetDesc())
- return;
- TPacketGCBattlePassUpdate packet;
- packet.bHeader = HEADER_GC_BATTLE_PASS_UPDATE;
- packet.bMissionType = dwMissionID;
- packet.dwNewProgress = dwSaveProgress;
- GetDesc()->Packet(&packet, sizeof(TPacketGCBattlePassUpdate));
- }
- BYTE CHARACTER::GetBattlePassId()
- {
- CAffect * pAffect = FindAffect(AFFECT_BATTLE_PASS, POINT_BATTLE_PASS_ID);
- if (!pAffect)
- {
- return 0;
- }
- return pAffect->lApplyValue;
- }
- #endif
- #ifdef ENABLE_HIDE_COSTUME_PART
- void CHARACTER::UpdateCostumeVisibilityStatus()
- {
- if (!IsPC())
- {
- return;
- }
- LPDESC d = GetDesc();
- if (d)
- {
- TPacketGCUpdateCostumeVisibilityStatus pack;
- pack.bHeader = HEADER_GC_UPDATE_COSTUME_VISIBILITY_STATUS;
- pack.type[ECostumePartTypes::HIDE_COSTUME_BODY] = GetQuestFlag("HIDE.COSTUME_BODY");
- pack.type[ECostumePartTypes::HIDE_COSTUME_HAIR] = GetQuestFlag("HIDE.COSTUME_HAIR");
- #ifdef ENABLE_COSTUME_WEAPON_SYSTEM
- pack.type[ECostumePartTypes::HIDE_COSTUME_WEAPON] = GetQuestFlag("HIDE.COSTUME_WEAPON");
- #endif
- #ifdef ENABLE_SHOULDER_SASH_SYSTEM
- pack.type[ECostumePartTypes::HIDE_COSTUME_SASH] = GetQuestFlag("HIDE.COSTUME_SASH");
- #endif
- d->Packet(&pack, sizeof(TPacketGCUpdateCostumeVisibilityStatus));
- }
- }
- #endif
- #ifdef ENABLE_FAKE_PC
- bool CHARACTER::IsNoDamage() const
- {
- return IS_SET(GetAIFlag(), AIFLAG_NODAMAGE);
- }
- bool CHARACTER::CanUseHPPotion() const
- {
- if (IsHealPotionDisabled())
- {
- return false;
- }
- if (FakePC_Check())
- {
- if (!FakePC_IsSupporter())
- {
- return false;
- }
- return true;
- }
- if (GetMapIndex() == 254) // m2_kingdomwar
- {
- return false;
- }
- if (GetMapIndex() == 110) // m2_t3
- {
- return false;
- }
- if (GetMapIndex() == 112) // m2_duelmap
- {
- return false;
- }
- return true;
- }
- void CHARACTER::SetComboSequence(BYTE seq)
- {
- m_bComboSequence = seq;
- }
- void CHARACTER::SetValidComboInterval(int interval)
- {
- m_iValidComboInterval = interval;
- }
- void CHARACTER::SetLastComboTime(DWORD time)
- {
- m_dwLastComboTime = time;
- }
- BYTE CHARACTER::GetComboSequence() const
- {
- return m_bComboSequence;
- }
- DWORD CHARACTER::GetLastComboTime() const
- {
- return m_dwLastComboTime;
- }
- int CHARACTER::GetValidComboInterval() const
- {
- return m_iValidComboInterval;
- }
- #endif
- #ifdef ENABLE_ZODIAC_TEMPLE
- void CHARACTER::BeadTime()
- {
- int Animasfer = GetAnimasfer();
- int LastTime = GetQuestFlag("zodiac.beadtime");
- if (Animasfer == 0 && (LastTime == 0))
- {
- SetAnimasfer(36);
- SetQuestFlag("zodiac.beadtime", get_global_time());
- ChatPacket(CHAT_TYPE_COMMAND, "Bead_count %d", GetAnimasfer());
- return;
- }
- if (Animasfer < 36 && ((get_global_time() - LastTime) > 3600))
- {
- int time1 = get_global_time() - LastTime;
- int count = time1/3600;
- if ((Animasfer+count) <= 36)
- {
- SetAnimasfer(count);
- }
- else if ((Animasfer+count) > 36)
- {
- int countt = 36-Animasfer;
- if (countt <= 36)
- {
- SetAnimasfer(countt);
- }
- }
- SetQuestFlag("zodiac.beadtime", get_global_time());
- ChatPacket(CHAT_TYPE_COMMAND, "Bead_count %d", GetAnimasfer());
- return;
- }
- ChatPacket(CHAT_TYPE_COMMAND, "Bead_count %d", Animasfer);
- }
- void CHARACTER::CzCheckBox()
- {
- std::unique_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT id FROM player.zodiac_point WHERE id = '%d'", GetPlayerID()));
- if (pMsg->Get()->uiNumRows == 0)
- {
- char szQuery[512];
- snprintf(szQuery, sizeof(szQuery), "INSERT INTO player.zodiac_point(id, yellowmark, greenmark, yellowreward, greenreward, goldreward) VALUES(%u, %u, %u, %u, %u, %u)", GetPlayerID(), 0, 0, 0, 0, 0);
- DBManager::Instance().DirectQuery(szQuery);
- }
- }
- int CHARACTER::GetAnimasfer()
- {
- std::unique_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT bead FROM player.player WHERE id = '%d';", GetPlayerID()));
- if (pMsg->Get()->uiNumRows == 0)
- {
- return 0;
- }
- MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
- int bBead = 0;
- str_to_number(bBead, row[0]);
- return bBead;
- }
- void CHARACTER::SetAnimasfer(int amount)
- {
- int value = abs(amount);
- if (amount > 0)
- {
- DBManager::instance().DirectQuery("UPDATE player.player SET bead = bead + '%d' WHERE id = '%d'", value, GetPlayerID());
- }
- else
- {
- SetQuestFlag("zodiac.beadtime", get_global_time());
- DBManager::instance().DirectQuery("UPDATE player.player SET bead = bead - '%d' WHERE id = '%d'", value, GetPlayerID());
- }
- ChatPacket(CHAT_TYPE_COMMAND, "Bead_count %d", GetAnimasfer());
- }
- void CHARACTER::SetYellowmark(int amount)
- {
- if (amount > 0)
- {
- DBManager::instance().DirectQuery("UPDATE player.zodiac_point SET yellowmark = yellowmark + '%d' WHERE id = '%d';", amount, GetPlayerID());
- }
- else
- {
- DBManager::instance().DirectQuery("UPDATE player.zodiac_point SET yellowmark = yellowmark - '%d' WHERE id = '%d';", amount, GetPlayerID());
- }
- }
- void CHARACTER::ClearYellowMark()
- {
- DBManager::instance().DirectQuery("UPDATE player.zodiac_point SET yellowmark = '0' WHERE id = '%d';", GetPlayerID());
- }
- int CHARACTER::GetYellowmark()
- {
- std::unique_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT yellowmark FROM player.zodiac_point WHERE id = '%d';", GetPlayerID()));
- if (pMsg->Get()->uiNumRows == 0)
- {
- return 0;
- }
- MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
- int iMark = 0;
- str_to_number(iMark, row[0]);
- return iMark;
- }
- void CHARACTER::SetGreenmark(int amount)
- {
- if (amount > 0)
- {
- DBManager::instance().DirectQuery("UPDATE player.zodiac_point SET greenmark = greenmark + '%d' WHERE id = '%d';", amount, GetPlayerID());
- }
- else
- {
- DBManager::instance().DirectQuery("UPDATE player.zodiac_point SET greenmark = greenmark - '%d' WHERE id = '%d';", amount, GetPlayerID());
- }
- }
- void CHARACTER::ClearGreenMark()
- {
- DBManager::instance().DirectQuery("UPDATE player.zodiac_point SET greenmark = '0' WHERE id = '%d';", GetPlayerID());
- }
- int CHARACTER::GetGreenmark()
- {
- std::unique_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT greenmark FROM player.zodiac_point WHERE id = '%d';", GetPlayerID()));
- if (pMsg->Get()->uiNumRows == 0)
- {
- return 0;
- }
- MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
- int iMark = 0;
- str_to_number(iMark, row[0]);
- return iMark;
- }
- void CHARACTER::SetYellowreward(int amount)
- {
- if (amount > 0)
- {
- DBManager::instance().DirectQuery("UPDATE player.zodiac_point SET yellowreward = yellowreward + '%d' WHERE id = '%d';", amount, GetPlayerID());
- }
- else
- {
- DBManager::instance().DirectQuery("UPDATE player.zodiac_point SET yellowreward = yellowreward - '%d' WHERE id = '%d';", amount, GetPlayerID());
- }
- }
- int CHARACTER::GetYellowreward()
- {
- std::unique_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT yellowreward FROM player.zodiac_point WHERE id = '%d';", GetPlayerID()));
- if (pMsg->Get()->uiNumRows == 0)
- {
- return 0;
- }
- MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
- int iMark = 0;
- str_to_number(iMark, row[0]);
- return iMark;
- }
- void CHARACTER::SetGreenreward(int amount)
- {
- if (amount > 0)
- {
- DBManager::instance().DirectQuery("UPDATE player.zodiac_point SET greenreward = greenreward + '%d' WHERE id = '%d';", amount, GetPlayerID());
- }
- else
- {
- DBManager::instance().DirectQuery("UPDATE player.zodiac_point SET greenreward = greenreward - '%d' WHERE id = '%d';", amount, GetPlayerID());
- }
- }
- int CHARACTER::GetGreenreward()
- {
- std::unique_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT greenreward FROM player.zodiac_point WHERE id = '%d';", GetPlayerID()));
- if (pMsg->Get()->uiNumRows == 0)
- {
- return 0;
- }
- MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
- int iMark = 0;
- str_to_number(iMark, row[0]);
- return iMark;
- }
- void CHARACTER::SetGoldreward(int amount)
- {
- if (amount > 0)
- {
- DBManager::instance().DirectQuery("UPDATE player.zodiac_point SET goldreward = goldreward + '%d' WHERE id = '%d';", amount, GetPlayerID());
- }
- else
- {
- DBManager::instance().DirectQuery("UPDATE player.zodiac_point SET goldreward = goldreward - '%d' WHERE id = '%d';", amount, GetPlayerID());
- }
- }
- int CHARACTER::GetGoldreward()
- {
- std::unique_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT goldreward FROM player.zodiac_point WHERE id = '%d';", GetPlayerID()));
- if (pMsg->Get()->uiNumRows == 0)
- {
- return 0;
- }
- MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
- int iMark = 0;
- str_to_number(iMark, row[0]);
- return iMark;
- }
- void CHARACTER::IsZodiacEffectMob()
- {
- if (!this)
- {
- return;
- }
- if (!IsMonster())
- {
- return;
- }
- if (IsDead())
- {
- return;
- }
- DWORD Monster = GetRaceNum();
- if (!Monster || Monster == 0)
- {
- return;
- }
- if (Monster == 2750 || Monster == 2860)
- {
- if (number(1, 2) == 1)
- {
- EffectPacket(SE_SKILL_DAMAGE_ZONE);
- }
- else
- {
- EffectPacket(SE_SKILL_SAFE_ZONE);
- }
- }
- }
- void CHARACTER::IsZodiacEffectPC(DWORD Monster)
- {
- if (!this)
- {
- return;
- }
- if (!IsPC())
- {
- return;
- }
- if (IsDead())
- {
- return;
- }
- if (!Monster || Monster == 0)
- {
- return;
- }
- if (!GetDesc() || !GetDesc()->GetCharacter())
- {
- return;
- }
- if (Monster == 20464)
- {
- EffectPacket(SE_DEAPO_BOOM);
- }
- else if (Monster == 2770 || Monster == 2771 || Monster == 2772)
- {
- EffectPacket(SE_METEOR);
- }
- else if (Monster == 2790 || Monster == 2791 || Monster == 2792)
- {
- EffectPacket(SE_BEAD_RAIN);
- }
- else if (Monster == 2830 || Monster == 2831 || Monster == 2832)
- {
- EffectPacket(SE_FALL_ROCK);
- }
- else if (Monster == 2800 || Monster == 2801 || Monster == 2802)
- {
- EffectPacket(SE_ARROW_RAIN);
- }
- else if (Monster == 2810 || Monster == 2811 || Monster == 2812)
- {
- EffectPacket(SE_HORSE_DROP);
- }
- else if (Monster == 2840 || Monster == 2841 || Monster == 2842)
- {
- EffectPacket(SE_EGG_DROP);
- }
- }
- void CHARACTER::ZodiacFloorMessage(BYTE Floor)
- {
- if (!IsPC())
- {
- return;
- }
- if (Floor == 1)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 2)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 3)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 4)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 5)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 6)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_THE_ZODIAC_BOSS__"), GetLang()));
- else if (Floor == 7)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DESTROY_A_METIN_STONE_TO_GET_BONUS_BOOSTER__"), GetLang()));
- else if (Floor == 8)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DESTROY_ALL_METIN_STONES__"), GetLang()));
- else if (Floor == 9)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 10)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 11)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_THE_ZODIAC_BOSS__"), GetLang()));
- else if (Floor == 12)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 13)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DESTROY_METIN_STONES__"), GetLang()));
- else if (Floor == 14)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__B_FLOOR_DESTROY_METIN_STONES__"), GetLang()));
- else if (Floor == 15)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_THE_MONSTERS__"), GetLang()));
- else if (Floor == 16)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 17)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_THE_ZODIAC_BOSS__"), GetLang()));
- else if (Floor == 18)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DESTROY_ALL_METIN_STONES__"), GetLang()));
- else if (Floor == 19)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 20)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 21)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DESTROY_A_METIN_STONE_TO_GET_BONUS_BOOSTER__"), GetLang()));
- else if (Floor == 22)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_AL_ZODIAC_CHIEFS__"), GetLang()));
- else if (Floor == 23)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 24)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 25)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 26)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 27)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DESTROY_ALL_METIN_STONES__"), GetLang()));
- else if (Floor == 28)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__B_FLOOR_DESTROY_METIN_STONES__"), GetLang()));
- else if (Floor == 29)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DESTROY_METIN_STONES__"), GetLang()));
- else if (Floor == 30)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DESTROY_METIN_STONES__"), GetLang()));
- else if (Floor == 31)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 32)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 33)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_ALL_MONSTER__"), GetLang()));
- else if (Floor == 34)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__DEFEAT_THE_MONSTERS__"), GetLang()));
- else if (Floor >= 35 && Floor <= 39)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__B_FLOOR_DESTROY_A_METIN_STONES__"), GetLang()));
- else if (Floor == 40)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__B_FLOOR_NOW_U_CAN_FILL_YUR_STOCKS_BY_SHOPPING__"), GetLang()));
- else if (Floor == 41)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__MISSION_FAILED__"), GetLang()));
- else if (Floor == 42)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__YOU_MISSED_THE_B_FLOOR__"), GetLang()));
- else if (Floor == 43)
- ChatPacket(CHAT_TYPE_ZODIAC_NOTICE, LC_TEXT_TRANS(("__TIME_IS_UP__"), GetLang()));
- }
- void CHARACTER::EffectZodiacPacket(long X, long Y, int enumEffectType, int enumEffectType2)
- {
- TPacketGCSpecialZodiacEffect p;
- p.header = HEADER_GC_SEPCIAL_ZODIAC_EFFECT;
- p.type = enumEffectType;
- p.type2 = enumEffectType2;
- p.vid = GetVID();
- p.x = X;
- p.y = Y;
- PacketAround(&p, sizeof(p));
- }
- DWORD CHARACTER::CountZodiacItems(DWORD Vnum)
- {
- std::unique_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT count FROM player.zodiac_npc WHERE item_vnum = '%u' and owner_id = '%d'", Vnum, GetPlayerID()));
- if (pMsg->Get()->uiNumRows == 0)
- {
- return 0;
- }
- MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
- DWORD dwCount = 0;
- str_to_number(dwCount, row[0]);
- return dwCount;
- }
- void CHARACTER::SetZodiacItems(DWORD Vnum, int Count)
- {
- std::unique_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT owner_id FROM player.zodiac_npc WHERE item_vnum = '%u' and owner_id = '%u'", Vnum, GetPlayerID()));
- if (pMsg->Get()->uiNumRows == 0)
- {
- char szQuery[512];
- snprintf(szQuery, sizeof(szQuery), "INSERT INTO player.zodiac_npc(owner_id, item_vnum, count) VALUES(%u, %u, %d)", GetPlayerID(), Vnum, Count);
- DBManager::Instance().DirectQuery(szQuery);
- return;
- }
- else
- {
- char szQuery2[512];
- snprintf(szQuery2, sizeof(szQuery2), "UPDATE player.zodiac_npc SET count = '%d' WHERE item_vnum = %u and owner_id = '%u'", Count, Vnum, GetPlayerID());
- DBManager::Instance().DirectQuery(szQuery2);
- }
- }
- DWORD CHARACTER::PurchaseCountZodiacItems(DWORD Vnum)
- {
- std::unique_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT count FROM player.zodiac_npc_sold WHERE item_vnum = '%u' and owner_id = '%d'", Vnum, GetPlayerID()));
- if (pMsg->Get()->uiNumRows == 0)
- {
- return 0;
- }
- MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
- DWORD dwCount = 0;
- str_to_number(dwCount, row[0]);
- return dwCount;
- }
- void CHARACTER::SetPurchaseZodiacItems(DWORD Vnum, int Count)
- {
- std::unique_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT owner_id FROM player.zodiac_npc_sold WHERE item_vnum = '%u' and owner_id = '%u'", Vnum, GetPlayerID()));
- if (pMsg->Get()->uiNumRows == 0)
- {
- char szQuery[512];
- snprintf(szQuery, sizeof(szQuery), "INSERT INTO player.zodiac_npc_sold(owner_id, item_vnum, count) VALUES(%u, %u, %d)", GetPlayerID(), Vnum, Count);
- DBManager::Instance().DirectQuery(szQuery);
- return;
- }
- else
- {
- char szQuery2[512];
- snprintf(szQuery2, sizeof(szQuery2), "UPDATE player.zodiac_npc_sold SET count = '%d' WHERE item_vnum = '%u' and owner_id = '%u'", Count, Vnum, GetPlayerID());
- DBManager::Instance().DirectQuery(szQuery2);
- }
- }
- #endif
- #ifdef ENABLE_SKILL_COLOR_SYSTEM
- void CHARACTER::SetSkillColor(DWORD * dwSkillColor)
- {
- memcpy(m_dwSkillColor, dwSkillColor, sizeof(m_dwSkillColor));
- UpdatePacket();
- }
- #endif
- void ConvertEmpireText(DWORD dwEmpireID, char* szText, size_t len, int iPct)
- {
- szText;
- }
- #ifdef ENABLE_AFK_MODE_SYSTEM
- EVENTFUNC(update_character_event)
- {
- char_event_info* info = dynamic_cast<char_event_info*>( event->info );
- if ( info == NULL )
- {
- return 0;
- }
- LPCHARACTER ch = info->ch;
- if (NULL == ch || ch->IsNPC())
- {
- return 0;
- }
- if (get_dword_time() - ch->GetLastMoveTime() > 60000*3)
- {
- if (!ch->IsAway())
- {
- ch->SetAway(true);
- }
- if (!ch->IsAffectFlag(AFF_AFK))
- {
- ch->AddAffect(AFFECT_AFK, POINT_NONE, 0, AFF_AFK, INFINITE_AFFECT_DURATION, 0, true, true);
- }
- }
- return PASSES_PER_SEC(15);
- }
- void CHARACTER::StartUpdateCharacterEvent()
- {
- if (m_pkUpdateCharacter)
- {
- return;
- }
- char_event_info* info = AllocEventInfo<char_event_info>();
- info->ch = this;
- m_pkUpdateCharacter = event_create(update_character_event, info, PASSES_PER_SEC(15));
- }
- #endif
- #ifdef ENABLE_BOSS_TRACKING
- EVENTFUNC(boss_tracking_data_event)
- {
- char_event_info* info = dynamic_cast<char_event_info*>(event->info);
- if (!info)
- {
- return 0;
- }
- LPCHARACTER ch = info->ch;
- if (!ch || !ch->GetDesc())
- {
- return 0;
- }
- if (ch->IsPC() == true)
- {
- if (ch->IsBossTrackingWindow == true)
- {
- for (int i = 0; i < 7; i++)
- {
- if (ch && ch->GetDesc())
- {
- CBossTracking::instance().SendClientPacket(ch, i, ch->BossTrackingMobVnum);
- }
- }
- }
- }
- return PASSES_PER_SEC(1);
- }
- void CHARACTER::StartBossTrackingDataEvent()
- {
- if (m_pkUpdateBossTracking)
- {
- return;
- }
- char_event_info* info = AllocEventInfo<char_event_info>();
- info->ch = this;
- m_pkUpdateBossTracking = event_create(boss_tracking_data_event, info, PASSES_PER_SEC(10));
- }
- void CHARACTER::StopBossTrackingDataEvent()
- {
- event_cancel(&m_pkUpdateBossTracking);
- m_pkUpdateBossTracking = NULL;
- BossTrackingMobVnum = 0;
- IsBossTrackingWindow = false;
- }
- #endif
- #ifdef ENABLE_AFTERDEATH_SHIELD
- void CHARACTER::AddAfterdeathShield()
- {
- if(!FindAffect(AFFECT_AFTERDEATH_SHIELD))
- {
- int duration = int(15);
- AddAffect(AFFECT_AFTERDEATH_SHIELD, 0, 0, AFF_AFTERDEATH_SHIELD, duration, 0, false);
- return;
- }
- }
- void CHARACTER::RemoveAfterdeathShield()
- {
- if(FindAffect(AFFECT_AFTERDEATH_SHIELD))
- {
- RemoveAffect(AFFECT_AFTERDEATH_SHIELD);
- return;
- }
- }
- bool CHARACTER::IsAfterdeathShieldProtected()
- {
- return FindAffect(AFFECT_AFTERDEATH_SHIELD)?true:false;
- }
- #endif
- #ifdef __ADMIN_MANAGER__
- DWORD CHARACTER::GetAccountBanCount() const
- {
- if (GetDesc())
- return GetDesc()->GetAccountTable().accban_count;
- return 0;
- }
- #endif
- /*** From Lysium ***/
- void CHARACTER::SetDamageLimitPercent(int limit)
- {
- m_damageHPLimit = (limit != 0) ? m_damageHPLimit = MINMAX(1, (GetMaxHP() * limit) / 100, GetMaxHP()) : 0;
- }
- /*** End ***/
- #ifdef ENABLE_FAKE_PC
- void CHARACTER::StopAutoRecovery(const EAffectTypes type)
- {
- if (AFFECT_AUTO_HP_RECOVERY != type && AFFECT_AUTO_SP_RECOVERY != type)
- {
- return;
- }
- CAffect* pAffect = FindAffect(type);
- if (pAffect == NULL)
- {
- return;
- }
- LPITEM pItem = FindItemByID(pAffect->dwFlag);
- if (NULL == pItem)
- {
- return;
- }
- RemoveAffect(pAffect);
- pItem->SetSocket(0, 0);
- }
- #endif
- #ifdef ENABLE_SHOW_MAP_BOSS_AND_STONE
- bool CHARACTER::IsBoss()
- {
- return m_pkMobData ? m_pkMobData->m_table.bRank > 3 && IsMonster() : false;
- }
- #endif
- #ifdef ENABLE_RUNE_SYSTEM
- bool CHARACTER::GetStrikeByVid(DWORD dwTargetVID, DWORD * iAmount)
- {
- auto it = m_iStrike.find(dwTargetVID);
- if (it == m_iStrike.end())
- {
- return false;
- }
- *iAmount = it->second;
- return true;
- }
- void CHARACTER::RegisterStrike(DWORD dwTargetVID)
- {
- DWORD iCount = 0;
- DWORD iTotalAmount = 0;
- if (!GetStrikeByVid(dwTargetVID, &iCount))
- {
- m_iStrike.insert(std::make_pair(dwTargetVID, 1));
- }
- iTotalAmount = iCount += 1;
- m_iStrike[dwTargetVID] = iTotalAmount;
- }
- void CHARACTER::ResetStrikes(DWORD dwTargetVID)
- {
- auto it = m_iStrike.find(dwTargetVID);
- if (it != m_iStrike.end())
- {
- m_iStrike.erase(it);
- }
- }
- std::string CHARACTER::GetRunes()
- {
- std::string return_value = "";
- for(int i = POINT_RUNE_PAGE1_KEYSTONE1; i <= POINT_RUNE_PAGE3_ROW3; i++)
- {
- return_value += std::to_string(GetPoint(i)) + ",";
- }
- return return_value;
- }
- void CHARACTER::EnableRuneRow(int bRow)
- {
- SetPoint(POINT_RUNE_PAGE1_KEYSTONE1 + bRow, 1);
- }
- void CHARACTER::AddRuneBonus(int bType, int bValue)
- {
- auto it = m_dwRuneBonuses.find(bType);
- if (it == m_dwRuneBonuses.end())
- {
- m_dwRuneBonuses.insert(std::make_pair(bType, bValue));
- }
- }
- void CHARACTER::RemoveRuneBonus(int bType)
- {
- auto it = m_dwRuneBonuses.find(bType);
- if (it != m_dwRuneBonuses.end())
- {
- m_dwRuneBonuses.erase(it);
- }
- }
- int CHARACTER::GetBonusValue(int bType)
- {
- auto it = m_dwRuneBonuses.find(bType);
- if (it != m_dwRuneBonuses.end())
- {
- return it->second;
- }
- return 0;
- }
- bool CHARACTER::HasRuneBonus(int bType)
- {
- auto it = m_dwRuneBonuses.find(bType);
- if (it != m_dwRuneBonuses.end())
- {
- return true;
- }
- return false;
- }
- #endif
- #ifdef ENABLE_COSTUME_MOUNT_SYSTEM
- void CHARACTER::CheckWears()
- {
- LPITEM item = GetWear(WEAR_COSTUME_MOUNT);
- if (item && item->IsRideItem())
- {
- CMountSystem* MountSystem = GetMountSystem();
- if (MountSystem)
- {
- uint32_t dwVnum = item->GetValue(4);
- MountSystem->Summon(dwVnum, GetName());
- MountSystem->Mount(GetMountingVnumM());
- }
- }
- #ifdef ENABLE_COSTUME_PET_SYSTEM
- item = GetWear(WEAR_PET);
- if (item)
- {
- if (item->GetType() == ITEM_PET && item->GetSubType() == PET_SLOT)
- {
- CPetSystem* petSystem = GetPetSystem();
- uint32_t dwVnum = item->GetValue(0);
- if (petSystem)
- {
- petSystem->Summon(dwVnum, item, 0, false);
- }
- }
- }
- #endif
- }
- #endif
- #ifdef ENABLE_SPECIAL_CHAT
- void CHARACTER::SendPickupItemPacket(int item_vnum, BYTE bArg)
- {
- if (!GetDesc())
- {
- return;
- }
- TPacketGCPickupItemSC PickupItemGC;
- PickupItemGC.bHeader = HEADER_GC_PICKUP_ITEM_SC;
- PickupItemGC.item_vnum = item_vnum;
- PickupItemGC.arg = bArg;
- GetDesc()->Packet(&PickupItemGC, sizeof(TPacketGCPickupItemSC));
- }
- #endif
- #ifdef ENABLE_MULTI_FARM_BLOCK
- void CHARACTER::SetProtectTime(const std::string& flagname, int value)
- {
- itertype(m_protection_Time) it = m_protection_Time.find(flagname);
- if (it != m_protection_Time.end())
- it->second = value;
- else
- m_protection_Time.insert(make_pair(flagname, value));
- }
- int CHARACTER::GetProtectTime(const std::string& flagname) const
- {
- itertype(m_protection_Time) it = m_protection_Time.find(flagname);
- if (it != m_protection_Time.end())
- return it->second;
- return 0;
- }
- #endif
- #ifdef ENABLE_VOTE4BUFF
- long long CHARACTER::GetVoteCoin()
- {
- std::unique_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT votebuff FROM account.account WHERE id = '%d';", GetDesc()->GetAccountTable().id));
- if (pMsg->Get()->uiNumRows == 0)
- return 0;
- MYSQL_ROW row = mysql_fetch_row(pMsg->Get()->pSQLResult);
- long long coin = 0;
- str_to_number(coin, row[0]);
- return coin;
- }
- void CHARACTER::SetVoteCoin(long long amount)
- {
- std::unique_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("UPDATE account.account SET votebuff = '%lld' WHERE id = '%d';", amount, GetDesc()->GetAccountTable().id));
- }
- #endif
- #ifdef ENABLE_EXTENDED_BATTLE_PASS
- void CHARACTER::SetLastReciveExtBattlePassInfoTime(DWORD time)
- {
- m_dwLastReciveExtBattlePassInfoTime = time;
- }
- void CHARACTER::SetLastReciveExtBattlePassOpenRanking(DWORD time)
- {
- m_dwLastExtBattlePassOpenRankingTime = time;
- }
- void CHARACTER::LoadExtBattlePass(DWORD dwCount, TPlayerExtBattlePassMission* data)
- {
- m_bIsLoadedExtBattlePass = false;
- for (int i = 0; i < dwCount; ++i, ++data)
- {
- TPlayerExtBattlePassMission* newMission = new TPlayerExtBattlePassMission;
- newMission->dwPlayerId = data->dwPlayerId;
- newMission->dwBattlePassType = data->dwBattlePassType;
- newMission->dwMissionIndex = data->dwMissionIndex;
- newMission->dwMissionType = data->dwMissionType;
- newMission->dwBattlePassId = data->dwBattlePassId;
- newMission->dwExtraInfo = data->dwExtraInfo;
- newMission->bCompleted = data->bCompleted;
- newMission->bIsUpdated = data->bIsUpdated;
- m_listExtBattlePass.push_back(newMission);
- }
- m_bIsLoadedExtBattlePass = true;
- }
- DWORD CHARACTER::GetExtBattlePassMissionProgress(DWORD dwBattlePassType, BYTE bMissionIndex, BYTE bMissionType)
- {
- DWORD BattlePassID;
- if (dwBattlePassType == 1)
- BattlePassID = CBattlePassManager::instance().GetNormalBattlePassID();
- else if (dwBattlePassType == 2)
- BattlePassID = CBattlePassManager::instance().GetPremiumBattlePassID();
- else if (dwBattlePassType == 3)
- BattlePassID = CBattlePassManager::instance().GetEventBattlePassID();
- else {
- sys_err("Unknown BattlePassType (%d)", dwBattlePassType);
- return 0;
- }
- ListExtBattlePassMap::iterator it = m_listExtBattlePass.begin();
- while (it != m_listExtBattlePass.end())
- {
- TPlayerExtBattlePassMission* pkMission = *it++;
- if (pkMission->dwBattlePassType == dwBattlePassType && pkMission->dwMissionIndex == bMissionIndex && pkMission->dwMissionType == bMissionType && pkMission->dwBattlePassId == BattlePassID)
- return pkMission->dwExtraInfo;
- }
- return 0;
- }
- bool CHARACTER::IsExtBattlePassCompletedMission(DWORD dwBattlePassType, BYTE bMissionIndex, BYTE bMissionType)
- {
- DWORD BattlePassID;
- if (dwBattlePassType == 1)
- BattlePassID = CBattlePassManager::instance().GetNormalBattlePassID();
- else if (dwBattlePassType == 2)
- BattlePassID = CBattlePassManager::instance().GetPremiumBattlePassID();
- else if (dwBattlePassType == 3)
- BattlePassID = CBattlePassManager::instance().GetEventBattlePassID();
- else {
- sys_err("Unknown BattlePassType (%d)", dwBattlePassType);
- return false;
- }
- ListExtBattlePassMap::iterator it = m_listExtBattlePass.begin();
- while (it != m_listExtBattlePass.end())
- {
- TPlayerExtBattlePassMission* pkMission = *it++;
- if (pkMission->dwBattlePassType == dwBattlePassType && pkMission->dwMissionIndex == bMissionIndex && pkMission->dwMissionType == bMissionType && pkMission->dwBattlePassId == BattlePassID)
- return (pkMission->bCompleted ? true : false);
- }
- return false;
- }
- bool CHARACTER::IsExtBattlePassRegistered(BYTE bBattlePassType, DWORD dwBattlePassID)
- {
- std::unique_ptr<SQLMsg> pMsg(DBManager::instance().DirectQuery("SELECT * FROM player.battlepass_playerindex WHERE player_id = %d and battlepass_type = %d and battlepass_id = %d", GetPlayerID(), bBattlePassType, dwBattlePassID));
- if (pMsg->Get()->uiNumRows != 0)
- return true;
- return false;
- }
- void CHARACTER::UpdateExtBattlePassMissionProgress(DWORD dwMissionType, DWORD dwUpdateValue, DWORD dwCondition, bool isOverride)
- {
- if (!GetDesc())
- return;
- if (!m_bIsLoadedExtBattlePass)
- return;
- DWORD dwSafeCondition = dwCondition;
- for (BYTE bBattlePassType = 1; bBattlePassType <= 3 ; ++bBattlePassType)
- {
- bool foundMission = false;
- DWORD dwSaveProgress = 0;
- dwCondition = dwSafeCondition;
- BYTE bBattlePassID;
- BYTE bMissionIndex = CBattlePassManager::instance().GetMissionIndex(bBattlePassType, dwMissionType, dwCondition);
- if (bBattlePassType == 1)
- bBattlePassID = CBattlePassManager::instance().GetNormalBattlePassID();
- if (bBattlePassType == 2){
- bBattlePassID = CBattlePassManager::instance().GetPremiumBattlePassID();
- if (bBattlePassID != GetExtBattlePassPremiumID())
- continue;
- }
- if (bBattlePassType == 3)
- bBattlePassID = CBattlePassManager::instance().GetEventBattlePassID();
- DWORD dwFirstInfo, dwSecondInfo;
- if (CBattlePassManager::instance().BattlePassMissionGetInfo(bBattlePassType, bMissionIndex, bBattlePassID, dwMissionType, &dwFirstInfo, &dwSecondInfo))
- {
- if (dwFirstInfo == 0)
- dwCondition = 0;
- if (dwMissionType == 2 and dwFirstInfo <= dwCondition or dwMissionType == 4 and dwFirstInfo <= dwCondition or dwMissionType == 20 and dwFirstInfo <= dwCondition)
- dwCondition = dwFirstInfo;
- if (dwFirstInfo == dwCondition && GetExtBattlePassMissionProgress(bBattlePassType, bMissionIndex, dwMissionType) < dwSecondInfo)
- {
- ListExtBattlePassMap::iterator it = m_listExtBattlePass.begin();
- while (it != m_listExtBattlePass.end())
- {
- TPlayerExtBattlePassMission* pkMission = *it++;
- if (pkMission->dwBattlePassType == bBattlePassType && pkMission->dwMissionIndex == bMissionIndex && pkMission->dwMissionType == dwMissionType && pkMission->dwBattlePassId == bBattlePassID)
- {
- pkMission->bIsUpdated = 1;
- if (isOverride)
- pkMission->dwExtraInfo = dwUpdateValue;
- else
- pkMission->dwExtraInfo += dwUpdateValue;
- if (pkMission->dwExtraInfo >= dwSecondInfo)
- {
- pkMission->dwExtraInfo = dwSecondInfo;
- pkMission->bCompleted = 1;
- std::string stMissionName = CBattlePassManager::instance().GetMissionNameByType(pkMission->dwMissionType);
- std::string stBattlePassName = CBattlePassManager::instance().GetNormalBattlePassNameByID(pkMission->dwBattlePassId);
- CBattlePassManager::instance().BattlePassRewardMission(this, bBattlePassType, dwMissionType, bBattlePassID);
- if (bBattlePassType == 1) {
- EffectPacket(SE_EFFECT_BP_NORMAL_MISSION_COMPLETED);
- ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT_TRANS(("BATTLEPASS_COMPLETE_NORMAL_MISSION"), GetLang()));
- }
- if (bBattlePassType == 2) {
- EffectPacket(SE_EFFECT_BP_PREMIUM_MISSION_COMPLETED);
- ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT_TRANS(("BATTLEPASS_COMPLETE_PREMIUM_MISSION"), GetLang()));
- }
- if (bBattlePassType == 3) {
- EffectPacket(SE_EFFECT_BP_EVENT_MISSION_COMPLETED);
- ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT_TRANS(("BATTLEPASS_COMPLETE_EVENT_MISSION"), GetLang()));
- }
- TPacketGCExtBattlePassMissionUpdate packet;
- packet.bHeader = HEADER_GC_EXT_BATTLE_PASS_MISSION_UPDATE;
- packet.bBattlePassType = bBattlePassType;
- packet.bMissionIndex = bMissionIndex;
- packet.dwNewProgress = pkMission->dwExtraInfo;
- GetDesc()->Packet(&packet, sizeof(TPacketGCExtBattlePassMissionUpdate));
- }
- dwSaveProgress = pkMission->dwExtraInfo;
- foundMission = true;
- if (pkMission->bCompleted != 1) {
- TPacketGCExtBattlePassMissionUpdate packet;
- packet.bHeader = HEADER_GC_EXT_BATTLE_PASS_MISSION_UPDATE;
- packet.bBattlePassType = bBattlePassType;
- packet.bMissionIndex = bMissionIndex;
- packet.dwNewProgress = dwSaveProgress;
- GetDesc()->Packet(&packet, sizeof(TPacketGCExtBattlePassMissionUpdate));
- }
- break;
- }
- }
- if (!foundMission)
- {
- if (!IsExtBattlePassRegistered(bBattlePassType, bBattlePassID))
- DBManager::instance().DirectQuery("INSERT INTO player.battlepass_playerindex SET player_id=%d, player_name='%s', battlepass_type=%d, battlepass_id=%d, start_time=NOW()", GetPlayerID(), GetName(), bBattlePassType, bBattlePassID);
- TPlayerExtBattlePassMission* newMission = new TPlayerExtBattlePassMission;
- newMission->dwPlayerId = GetPlayerID();
- newMission->dwBattlePassType = bBattlePassType;
- newMission->dwMissionType = dwMissionType;
- newMission->dwBattlePassId = bBattlePassID;
- if (dwUpdateValue >= dwSecondInfo)
- {
- newMission->dwMissionIndex = CBattlePassManager::instance().GetMissionIndex(bBattlePassType, dwMissionType, dwCondition);
- newMission->dwExtraInfo = dwSecondInfo;
- newMission->bCompleted = 1;
- CBattlePassManager::instance().BattlePassRewardMission(this, bBattlePassType, dwMissionType, bBattlePassID);
- if (bBattlePassType == 1) {
- EffectPacket(SE_EFFECT_BP_NORMAL_MISSION_COMPLETED);
- ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT_TRANS(("BATTLEPASS_COMPLETE_NORMAL_MISSION"), GetLang()));
- }
- if (bBattlePassType == 2) {
- EffectPacket(SE_EFFECT_BP_PREMIUM_MISSION_COMPLETED);
- ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT_TRANS(("BATTLEPASS_COMPLETE_PREMIUM_MISSION"), GetLang()));
- }
- if (bBattlePassType == 3) {
- EffectPacket(SE_EFFECT_BP_EVENT_MISSION_COMPLETED);
- ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT_TRANS(("BATTLEPASS_COMPLETE_EVENT_MISSION"), GetLang()));
- }
- dwSaveProgress = dwSecondInfo;
- }
- else
- {
- newMission->dwMissionIndex = CBattlePassManager::instance().GetMissionIndex(bBattlePassType, dwMissionType, dwCondition);
- newMission->dwExtraInfo = dwUpdateValue;
- newMission->bCompleted = 0;
- dwSaveProgress = dwUpdateValue;
- }
- newMission->bIsUpdated = 1;
- m_listExtBattlePass.push_back(newMission);
- TPacketGCExtBattlePassMissionUpdate packet;
- packet.bHeader = HEADER_GC_EXT_BATTLE_PASS_MISSION_UPDATE;
- packet.bBattlePassType = bBattlePassType;
- packet.bMissionIndex = bMissionIndex;
- packet.dwNewProgress = dwSaveProgress;
- GetDesc()->Packet(&packet, sizeof(TPacketGCExtBattlePassMissionUpdate));
- }
- }
- }
- }
- }
- void CHARACTER::SetExtBattlePassMissionProgress(BYTE bBattlePassType, DWORD dwMissionIndex, DWORD dwMissionType, DWORD dwUpdateValue)
- {
- if (!GetDesc())
- return;
- if (!m_bIsLoadedExtBattlePass)
- return;
- bool foundMission = false;
- DWORD dwSaveProgress = 0;
- BYTE bBattlePassID;
- if (bBattlePassType == 1)
- bBattlePassID = CBattlePassManager::instance().GetNormalBattlePassID();
- else if (bBattlePassType == 2)
- bBattlePassID = CBattlePassManager::instance().GetPremiumBattlePassID();
- else if (bBattlePassType == 3)
- bBattlePassID = CBattlePassManager::instance().GetEventBattlePassID();
- else {
- sys_err("Unknown BattlePassType (%d)", bBattlePassType);
- return;
- }
- DWORD dwFirstInfo, dwSecondInfo;
- if (CBattlePassManager::instance().BattlePassMissionGetInfo(bBattlePassType, dwMissionIndex, bBattlePassID, dwMissionType, &dwFirstInfo, &dwSecondInfo))
- {
- ListExtBattlePassMap::iterator it = m_listExtBattlePass.begin();
- while (it != m_listExtBattlePass.end())
- {
- TPlayerExtBattlePassMission* pkMission = *it++;
- if (pkMission->dwBattlePassType == bBattlePassType && pkMission->dwMissionIndex == dwMissionIndex && pkMission->dwMissionType == dwMissionType && pkMission->dwBattlePassId == bBattlePassID)
- {
- pkMission->bIsUpdated = 1;
- pkMission->bCompleted = 0;
- pkMission->dwExtraInfo = dwUpdateValue;
- if (pkMission->dwExtraInfo >= dwSecondInfo)
- {
- pkMission->dwExtraInfo = dwSecondInfo;
- pkMission->bCompleted = 1;
- std::string stMissionName = CBattlePassManager::instance().GetMissionNameByType(pkMission->dwMissionType);
- std::string stBattlePassName = CBattlePassManager::instance().GetNormalBattlePassNameByID(pkMission->dwBattlePassId);
- //ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT("New Value : %d"), pkMission->dwExtraInfo);
- CBattlePassManager::instance().BattlePassRewardMission(this, bBattlePassType, dwMissionType, bBattlePassID);
- if (bBattlePassType == 1) {
- EffectPacket(SE_EFFECT_BP_NORMAL_MISSION_COMPLETED);
- ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT_TRANS(("BATTLEPASS_COMPLETE_NORMAL_MISSION"), GetLang()));
- }
- if (bBattlePassType == 2) {
- EffectPacket(SE_EFFECT_BP_PREMIUM_MISSION_COMPLETED);
- ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT_TRANS(("BATTLEPASS_COMPLETE_PREMIUM_MISSION"), GetLang()));
- }
- if (bBattlePassType == 3) {
- EffectPacket(SE_EFFECT_BP_EVENT_MISSION_COMPLETED);
- ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT_TRANS(("BATTLEPASS_COMPLETE_EVENT_MISSION"), GetLang()));
- }
- TPacketGCExtBattlePassMissionUpdate packet;
- packet.bHeader = HEADER_GC_EXT_BATTLE_PASS_MISSION_UPDATE;
- packet.bBattlePassType = bBattlePassType;
- packet.bMissionIndex = dwMissionIndex;
- packet.dwNewProgress = pkMission->dwExtraInfo;
- GetDesc()->Packet(&packet, sizeof(TPacketGCExtBattlePassMissionUpdate));
- }
- dwSaveProgress = pkMission->dwExtraInfo;
- foundMission = true;
- if (pkMission->bCompleted != 1) {
- TPacketGCExtBattlePassMissionUpdate packet;
- packet.bHeader = HEADER_GC_EXT_BATTLE_PASS_MISSION_UPDATE;
- packet.bBattlePassType = bBattlePassType;
- packet.bMissionIndex = dwMissionIndex;
- packet.dwNewProgress = dwSaveProgress;
- GetDesc()->Packet(&packet, sizeof(TPacketGCExtBattlePassMissionUpdate));
- }
- break;
- }
- }
- if (!foundMission)
- {
- if (!IsExtBattlePassRegistered(bBattlePassType, bBattlePassID))
- DBManager::instance().DirectQuery("INSERT INTO player.battlepass_playerindex SET player_id=%d, player_name='%s', battlepass_type=%d, battlepass_id=%d, start_time=NOW()", GetPlayerID(), GetName(), bBattlePassType, bBattlePassID);
- TPlayerExtBattlePassMission* newMission = new TPlayerExtBattlePassMission;
- newMission->dwPlayerId = GetPlayerID();
- newMission->dwBattlePassType = bBattlePassType;
- newMission->dwMissionType = dwMissionType;
- newMission->dwBattlePassId = bBattlePassID;
- if (dwUpdateValue >= dwSecondInfo)
- {
- newMission->dwMissionIndex = dwMissionIndex;
- newMission->dwExtraInfo = dwSecondInfo;
- newMission->bCompleted = 1;
- CBattlePassManager::instance().BattlePassRewardMission(this, bBattlePassType, dwMissionType, bBattlePassID);
- if (bBattlePassType == 1) {
- EffectPacket(SE_EFFECT_BP_NORMAL_MISSION_COMPLETED);
- ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT_TRANS(("BATTLEPASS_COMPLETE_NORMAL_MISSION"), GetLang()));
- }
- if (bBattlePassType == 2) {
- EffectPacket(SE_EFFECT_BP_PREMIUM_MISSION_COMPLETED);
- ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT_TRANS(("BATTLEPASS_COMPLETE_PREMIUM_MISSION"), GetLang()));
- }
- if (bBattlePassType == 3) {
- EffectPacket(SE_EFFECT_BP_EVENT_MISSION_COMPLETED);
- ChatPacket(CHAT_TYPE_NOTICE, LC_TEXT_TRANS(("BATTLEPASS_COMPLETE_EVENT_MISSION"), GetLang()));
- }
- dwSaveProgress = dwSecondInfo;
- }
- else
- {
- newMission->dwMissionIndex = dwMissionIndex;
- newMission->dwExtraInfo = dwUpdateValue;
- newMission->bCompleted = 0;
- dwSaveProgress = dwUpdateValue;
- }
- newMission->bIsUpdated = 1;
- m_listExtBattlePass.push_back(newMission);
- TPacketGCExtBattlePassMissionUpdate packet;
- packet.bHeader = HEADER_GC_EXT_BATTLE_PASS_MISSION_UPDATE;
- packet.bBattlePassType = bBattlePassType;
- packet.bMissionIndex = dwMissionIndex;
- packet.dwNewProgress = dwSaveProgress;
- GetDesc()->Packet(&packet, sizeof(TPacketGCExtBattlePassMissionUpdate));
- }
- }
- }
- #endif
-
Hallo,
hat jemand evtl. schonmal so ein Problem gehabt oder weis sogar die Lösung dafür?
ab und an kommt random ein core crash... kann nicht genau sagen wann, da er beim testen anderer Leute passiert.
Anbei bt full der reihe nach nummeriert.
1Bitte melden Sie sich an, um diesen Anhang zu sehen.2Bitte melden Sie sich an, um diesen Anhang zu sehen.3Bitte melden Sie sich an, um diesen Anhang zu sehen.
Über Hilfe wäre ich sehr dankbar.
Es kann auch bezahlt werden.
-
Hallo,
Ich habe ein Problem mit den Bonis von meinen Kostümen. An sich haben costume_body und costume_hair funktioniert. Ich konnte ganz normal hinzufügen sowie auch switchen.
Ich habe nachgeschaut Weapon ist auch mit dabei in char_item.cpp bzgl switchen ...
In item_attr in der datenbank war costume_weapon nicht mit dabei. Habe ich natürlich hinzugefügt.Danach habe ich in item_attribute.cpp return ATTRIBUTE_SET_COSTUME_WEAPON; bei case COSTUME_WEAPON: eingefügt weil vorher ein return; dort stand. Alles andere habe ich mir auch bei den anderen zweien abgeschaut jedoch klappte es nicht.
Sieht so aus:
Code- if (GetType() == ITEM_COSTUME)
- {
- switch (GetSubType())
- {
- case COSTUME_BODY:
- return ATTRIBUTE_SET_COSTUME_BODY;
- case COSTUME_HAIR:
- return ATTRIBUTE_SET_COSTUME_HAIR;
- #ifdef ENABLE_COSTUME_WEAPON_SYSTEM
- case COSTUME_WEAPON:
- return ATTRIBUTE_SET_COSTUME_WEAPON; // vorher stand hier nur break;
- #endif
- }
- }
Danach habe ich mal versucht in der ClientManagerBoot.cpp (wo ich vorher auch schon costume_weapon angepasst habe, jedoch ich danach keines der 3 kostümteile mehr switchen oder mit bonis versehen konnte) das
auszukommentieren, damit quasi nur noch body und weapon bleibt (das weapon war vorher nicht vorhanden) und auf einmal konnte ich Waffenkostüm und Rüsstung bonis hinzufügen und auch switchen, jedoch konnte ich nur die bonis die ich für costume_body in der DB festgelegt habe drauf switchen, nicht die für costume_weapon. ?!?!
Wenn ich es jetzt aber so habeCode- bool CClientManager::InitializeItemAttrTable()
- {
- char query[4096];
- #ifdef ENABLE_PENDANT
- snprintf(query, sizeof(query), "SELECT apply, apply+0, prob, lv1, lv2, lv3, lv4, lv5, weapon, body, wrist, foots, neck, head, shield, ear, pendant, costume_hair, costume_body, min_lvl, max_lvl, costume_weapon FROM item_attr ORDER BY apply"); //costume_weapon HINZUGEFÜGT
- #else
- snprintf(query, sizeof(query), "SELECT apply, apply+0, prob, lv1, lv2, lv3, lv4, lv5, weapon, body, wrist, foots, neck, head, shield, ear, costume_hair, costume_body, min_lvl, max_lvl, costume_weapon FROM item_attr ORDER BY apply"); //costume_weapon HINZUGEFÜGT
- #endif
- std::unique_ptr<SQLMsg> pkMsg(CDBManager::instance().DirectQuery(query));
- SQLResult* pRes = pkMsg->Get();
- if (!pRes->uiNumRows)
- {
- sys_err("no result from item_attr");
- return false;
- }
- if (!m_vec_itemAttrTable.empty())
- {
- m_vec_itemAttrTable.clear();
- }
- m_vec_itemAttrTable.reserve((DWORD)pRes->uiNumRows);
- MYSQL_ROW data;
- while ((data = mysql_fetch_row(pRes->pSQLResult)))
- {
- TItemAttrTable t;
- memset(&t, 0, sizeof(TItemAttrTable));
- int col = 0;
- strlcpy(t.szApply, data[col++], sizeof(t.szApply));
- str_to_number(t.dwApplyIndex, data[col++]);
- str_to_number(t.dwProb, data[col++]);
- str_to_number(t.lValues[0], data[col++]);
- str_to_number(t.lValues[1], data[col++]);
- str_to_number(t.lValues[2], data[col++]);
- str_to_number(t.lValues[3], data[col++]);
- str_to_number(t.lValues[4], data[col++]);
- str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_WEAPON], data[col++]);
- str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_BODY], data[col++]);
- str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_WRIST], data[col++]);
- str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_FOOTS], data[col++]);
- str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_NECK], data[col++]);
- str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_HEAD], data[col++]);
- str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_SHIELD], data[col++]);
- str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_EAR], data[col++]);
- #ifdef ENABLE_PENDANT
- str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_PENDANT], data[col++]);
- #endif
- str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_COSTUME_HAIR], data[col++]);
- str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_COSTUME_BODY], data[col++]);
- #ifdef ENABLE_COSTUME_WEAPON_SYSTEM
- str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_COSTUME_WEAPON], data[col++]); // NEU HINZUGEFÜGT, DANACH LÄSST SICH KEIN KOSTÜM MEHR MIT BONIS VERSEHEN ODER SWITCHEN
- #endif
- // GunnerMBT - 02/04/2014
- str_to_number(t.min_lvl, data[col++]);
- str_to_number(t.max_lvl, data[col++]);
- // end
- m_vec_itemAttrTable.push_back(t);
- }
- return true;
- }
So denke ich mal sollte es dann für alle drei Kostümteile funktionieren, habe lediglich den kommentierten weapon part hinzugefügt und vorher ging es mit body & hair (bonis hinzufügen &switchen).
Jedoch kann ich so kein einzigen Boni mehr auf irgenein Kostüm hinzufügen oder switchen.
Ich hoffe es kann jemand helfen. -
Hast du das System erst neu verbaut oder was es schon so vorhanden. Falls du es eingebaut hast evtl. von neu einbauen, evlt. ist auch etwas am Code buggy bei der wahrscheinlich "releasten" Version von dir.
-
Installier doch einfach mysql56 auf dem zweiten root. Damit musst du dir auch keine Kopfschmerzen machen.
-
Lad doch mal deine uiBan.py hier hoch.
-
Administration ist Top, Viel Erfolg!
-
Hallo Community,
gibt es ein veröffentlichtes Titel system wo man per item einen eigenen Titel setzen kann?
Ggbfs. bietet sowas auch jemand zum Verkauf an.
Danke im Voraus. -
The Dual blades are wow! awesome work.
-
Vielleicht sowas?
Ich vermute mal, dass table->info ein string ist. Falls nicht, einfach mit dem passenden Datentypen austauschen. Eigentlich hat std::pair einen passenden Konstruktor zum erstellen von Key-Value Pairs, aber vielleicht ist das auch Versionsabhängig.
Edit:
Alternativ kannst du es auch so machen, wie Metin2 es sonst im gesamten Source macht (jedenfalls bei mir):
ich danke schon mal. Ich werde es nach der Arbeit ausprobieren. 😄
-
Hallo,
Ich habe ein Problem beim compilen der Game bei dem Sura Head Itemshop. Bekomme diesen Fehler:
Bitte melden Sie sich an, um diesen Anhang zu sehen.
C- #include "stdafx.h"
- #include "itemshop.h"
- #include "char.h"
- #include "db.h"
- #include "char_manager.h"
- #include "sectree_manager.h"
- #include "config.h"
- #include "item_manager.h"
- #include "item.h"
- #include "desc.h"
- #ifdef ENABLE_ITEMSHOP
- CItemshopManager::CItemshopManager()
- {
- }
- CItemshopManager::~CItemshopManager()
- {
- }
- void CItemshopManager::InitializeItems(TItemshopItemTable * table, WORD size)
- {
- m_ItemshopItems.clear();
- for (int i = 0; i < size; ++i, ++table)
- {
- const TItemTable* item_table = ITEM_MANAGER::instance().GetTable(table->dwVnum);
- if (item_table)
- {
- if (table->wCount > 1 && ((IS_SET(item_table->dwAntiFlags, ITEM_ANTIFLAG_STACK)) || !(IS_SET(item_table->dwFlags, ITEM_FLAG_STACKABLE))))
- {
- sys_err("<Itemshop / Are you stupid?> Vnum %lld Count %d but item is not stackable. Adjust this shit!", table->dwVnum, table->wCount);
- continue;
- }
- m_ItemshopItems[table->byCategory].push_back(*table);
- }
- }
- }
- void CItemshopManager::InitializeCategories(TItemshopCategoryTable* table, WORD size)
- {
- m_ItemshopCategories.clear();
- for (int i = 0; i < size; ++i, ++table)
- {
- m_ItemshopCategories.insert(std::pair(table->index, table->info));
- }
- }
- void CItemshopManager::RefreshSingleItem(TItemshopItemTable* item)
- {
- for (auto& category : m_ItemshopItems)
- {
- for (auto& cur_item : category.second)
- {
- if (!strcmp(cur_item.hash, item->hash))
- {
- thecore_memcpy(&cur_item, item, sizeof(TItemshopItemTable));
- CHARACTER_MANAGER::instance().SendItemshopSingleItemRefresh(item);
- return;
- }
- }
- }
- }
- void CItemshopManager::RemoveSingleItem(TItemshopItemTable* item)
- {
- for (auto& category : m_ItemshopItems)
- {
- for(int i = 0; i < category.second.size(); i++)
- {
- if (!strcmp(category.second[i].hash, item->hash))
- {
- category.second.erase(category.second.begin() + i);
- CHARACTER_MANAGER::instance().SendItemshopSingleRemoveItem(item);
- return;
- }
- }
- }
- }
- void CItemshopManager::AddSingleItem(TItemshopItemTable* item)
- {
- const TItemTable* item_table = ITEM_MANAGER::instance().GetTable(item->dwVnum);
- if (item_table)
- {
- if (item->wCount > 1 && ((IS_SET(item_table->dwAntiFlags, ITEM_ANTIFLAG_STACK)) || !(IS_SET(item_table->dwFlags, ITEM_FLAG_STACKABLE))))
- {
- sys_err("<Itemshop / Are you stupid?> Vnum %ld Count %d but item is not stackable. Adjust this shit!", item->dwVnum, item->wCount);
- return;
- }
- m_ItemshopItems[item->byCategory].push_back(*item);
- CHARACTER_MANAGER::instance().SendItemshopSingleAddItem(item);
- }
- }
- bool CItemshopManager::IsValidHash(const char* hash)
- {
- for (const auto& category : m_ItemshopItems)
- {
- for (const auto& item : category.second) {
- if (!strcmp(hash, item.hash))
- return true;
- }
- }
- return false;
- }
- bool CItemshopManager::IsValidPurchase(TItemshopItemTable itemInfo, WORD wCount, unsigned long long &ullPrice)
- {
- const TItemTable* item_table = ITEM_MANAGER::instance().GetTable(itemInfo.dwVnum);
- if (item_table)
- {
- // NOTE: Log user reason custom packet
- if (wCount > 1 && ((IS_SET(item_table->dwAntiFlags, ITEM_ANTIFLAG_STACK)) || !(IS_SET(item_table->dwFlags, ITEM_FLAG_STACKABLE))))
- return false;
- }
- if (wCount <= 0
- || check_mul_error(itemInfo.wCount, wCount)
- || itemInfo.wCount * wCount > ITEM_MAX_COUNT)
- {
- return false;
- }
- BYTE discountPercent = MINMAX(0, itemInfo.byDiscountPercent, 100);
- if (discountPercent > 0) {
- ullPrice = ullPrice - (ullPrice * discountPercent / 100);
- }
- if (check_mul_error<unsigned long long>(ullPrice, wCount)) {
- return false;
- }
- ullPrice *= wCount;
- return true;
- }
- bool CItemshopManager::HasEnoughCoins(DWORD accID, unsigned long long ullItemPrice)
- {
- std::unique_ptr<SQLMsg> pkMsg(DBManager::instance().DirectQuery("SELECT coins from account.account WHERE id = %ld", accID));
- SQLResult* pRes = pkMsg->Get();
- if (pRes->uiNumRows == 0)
- {
- return false;
- }
- MYSQL_ROW data = mysql_fetch_row(pRes->pSQLResult);
- unsigned long long ullTotalCoins;
- str_to_number(ullTotalCoins, data[0]);
- return ullTotalCoins >= ullItemPrice;
- }
- bool CItemshopManager::CanBuyItem(LPCHARACTER ch, const char* hash, WORD wCount)
- {
- if (!ch->CanUseItemshop())
- {
- ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You have to wait 10 seconds after an invalid itemshop action."));
- return false;
- }
- if (!IsValidHash(hash))
- {
- ch->SetItemshopCooldown(thecore_pulse() + PASSES_PER_SEC(10));
- return false;
- }
- TItemshopItemTable itemInfo{ 0 };
- for (const auto& category : m_ItemshopItems)
- {
- for (const auto& item : category.second)
- {
- if (!strcmp(hash, item.hash))
- {
- itemInfo = item;
- break;
- }
- }
- }
- if (itemInfo.llLimitCount == 0)
- return false;
- unsigned long long ullPrice = itemInfo.ullPrice;
- if (!IsValidPurchase(itemInfo, wCount, ullPrice))
- {
- sys_err("<Itemshop> OVERFLOW check failed. PID: %d - BuyCount %d - Hash %s - Vnum %lld - Count %d", ch->GetPlayerID(), wCount, itemInfo.hash, itemInfo.dwVnum, itemInfo.wCount);
- return false;
- }
- const TAccountTable& accTable = ch->GetDesc()->GetAccountTable();
- if (!HasEnoughCoins(accTable.id, ullPrice))
- {
- ch->SetItemshopCooldown(thecore_pulse() + PASSES_PER_SEC(10));
- ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You dont have enough coins."));
- return false;
- }
- LPITEM item = ITEM_MANAGER::instance().CreateItem(itemInfo.dwVnum, itemInfo.wCount * wCount);
- if (!item)
- {
- ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Invalid item -> Write your Serveradmin to get some free coins :)"));
- return false;
- }
- int iEmptyCell;
- if (item->IsDragonSoul())
- {
- if ((iEmptyCell = ch->GetEmptyDragonSoulInventory(item)) == -1)
- {
- ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You carry too many Items."));
- M2_DESTROY_ITEM(item);
- return false;
- }
- }
- else
- {
- // NOTE: Adjust for special inventory by sanii
- if ((iEmptyCell = ch->GetEmptyInventory(item->GetSize())) == -1)
- {
- ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You carry too many Items."));
- M2_DESTROY_ITEM(item);
- return false;
- }
- }
- M2_DESTROY_ITEM(item);
- return true;
- }
- // NOTE: CALL THIS ONLY FROM DB_MANAGER
- bool CItemshopManager::BuyItem(LPCHARACTER ch, const char* hash, WORD wCount)
- {
- if (!IsValidHash(hash))
- {
- ch->SendItemshopItemsPacket(GetItemshopItems(),GetItemshopCategories());
- return false;
- }
- TItemshopItemTable itemInfo{0};
- for (const auto& category : m_ItemshopItems)
- {
- for (const auto & item : category.second)
- {
- if (!strcmp(hash, item.hash))
- {
- itemInfo = item;
- break;
- }
- }
- }
- unsigned long long ullPrice = itemInfo.ullPrice;
- if (!IsValidPurchase(itemInfo, wCount, ullPrice))
- {
- sys_err("<Itemshop> OVERFLOW check failed. PID: %d - BuyCount %d - Hash %s - Vnum %lld - Count %d", ch->GetPlayerID(), wCount, itemInfo.hash, itemInfo.dwVnum, itemInfo.wCount);
- return false;
- }
- const TAccountTable& accTable = ch->GetDesc()->GetAccountTable();
- if (!HasEnoughCoins(accTable.id, ullPrice))
- {
- ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You dont have enough coins."));
- return false;
- }
- LPITEM item = ITEM_MANAGER::instance().CreateItem(itemInfo.dwVnum, itemInfo.wCount * wCount);
- if (!item)
- {
- ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("Invalid item -> Write your Serveradmin to get some free coins :)"));
- return false;
- }
- // NOTE: adjust as needed
- bool forcedSockets = false;
- if (itemInfo.alSockets[0])
- {
- for (int i = 0; i < ITEM_LIMIT_MAX_NUM; i++)
- {
- if (LIMIT_REAL_TIME == item->GetLimitType(i))
- {
- // NOTE: We set socket0 as time value, but only if socket is set so we still can use default times in createitem
- item->SetSocket(0, time(0) + itemInfo.alSockets[0]);
- // NOTE: We dont have to start realtime event because createitem already does
- forcedSockets = true;
- }
- else if (LIMIT_TIMER_BASED_ON_WEAR == item->GetLimitType(i))
- {
- item->SetSocket(0, itemInfo.alSockets[0]);
- forcedSockets = true;
- }
- }
- }
- // NOTE: I dont have systems where i need to set multiple sockets in createitem but you can still do:
- // for(const auto& socket : itemInfo.alSockets)
- if(!forcedSockets)
- item->SetSockets(itemInfo.alSockets);
- // NOTE: You can adjust this if you want to use bAlterToMagicItemPct
- item->SetAttributes(itemInfo.aAttr);
- int iEmptyCell;
- if (item->IsDragonSoul())
- {
- if ((iEmptyCell = ch->GetEmptyDragonSoulInventory(item)) == -1)
- {
- ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You carry too many Items."));
- M2_DESTROY_ITEM(item);
- return false;
- }
- }
- else
- {
- // NOTE: Adjust for special inventory by sanii
- if ((iEmptyCell = ch->GetEmptyInventory(item->GetSize())) == -1)
- {
- ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You carry too many Items."));
- M2_DESTROY_ITEM(item);
- return false;
- }
- }
- DBManager::instance().DirectQuery("UPDATE account.account SET coins = coins - %lld WHERE id = %ld", ullPrice, accTable.id);
- if (item->IsDragonSoul())
- item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyCell));
- else
- item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyCell));
- ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("The purchase of the item was successful."));
- ch->SendItemshopCoinPacket();
- return true;
- }
- const std::unordered_map <BYTE, std::vector<TItemshopItemTable>> CItemshopManager::GetItemshopItems()
- {
- return m_ItemshopItems;
- }
- const std::unordered_map < BYTE, TItemshopCategoryInfo> CItemshopManager::GetItemshopCategories()
- {
- return m_ItemshopCategories;
- }
- #endif
Ich wäre sehr dankbar um Ratschläge.
Danke im Voraus.
-
#erledigt.
Fehler lag in der item_manager.cpp. -
bt full mal machen
Das ist schon bt full (zu sehen bei: continue without paging--bt full)....