Batch #16644 by ragnarok-clanker: no function's compiled code changes; checked with 593 compiled unit(s), including every includer of Source/Client/Application/Registry.h, Source/Client/Application/RegistryKey.h, Source/Client/Application/Timer.h, Source/Client/Mode/ModeFade.h, Source/Client/Mode/ModeFadeOut.h, Source/Client/Mode/ModeScreenshot.h, Source/Client/Replay/Replay.h, Source/Client/Replay/ReplayRecordOption.h, Source/Client/Session/Session.h, Source/Contents/Actors/ActorPickNode.h, Source/Contents/Effects/Core/RagEffectState.h, Source/Contents/Effects/Particles/Particle.h, Source/Contents/Movies/BinkMovie.h, Source/Contents/Sprites/SpriteLayerDrawing.h, Source/File/NFileLog.h, Source/Network/NIPAddr.h, Source/Network/Packets/ActorNamePacket.h, Source/Network/Packets/ClientKeepalive.h, Source/Network/Packets/ClientOptionPacket.h, Source/Network/Packets/ExecutableDigestPacket.h, Source/Network/Packets/GameTickPacket.h, Source/Render/DX7/QueuedDrawingDX7.h, Source/Render/DX7/RendererDX7.h, Source/Render/DX9/RenderSystemDX9.h, Source/Render/Device/DeviceSelection.h, Source/Render/Device/Direct3DErrors.h, Source/Render/Device/DisplayMode.h, Source/Render/Device/RenderAdapter.h, Source/Render/Device/RenderBackends.h, Source/Render/Drawing/ActionSpriteDrawing.h, Source/Render/Drawing/BitmapDrawing.h, Source/Render/Drawing/BlendColor.h, Source/Render/Drawing/SpriteGeometry.h, Source/Render/Drawing/TextureStageModes.h, Source/Render/Primitives/AuxiliarySubmission.h, Source/Render/Primitives/SpriteQuad.h, Source/Render/Primitives/TextureQuad.h, Source/Render/Projection/ScreenGeometry.h, Source/Render/Projection/ScreenRectangle.h, Source/Resource/Audio/BinkRuntime.h, Source/Resource/Bitmap/EmblemResource.h, Source/Resource/Bitmap/GifLzw.h, Source/Resource/Bitmap/GifResource.h, Source/Resource/Bitmap/PaletteResource.h, Source/Resource/Bitmap/SkinPalette.h, Source/Resource/Bitmap/TextureNames.h, Source/Resource/Effects/EZeffectResource.h, Source/Resource/Json/JsonCppLoader.h, Source/Resource/Models/RmaResource.h, Source/Resource/Sprites/ImfResource.h, Source/Resource/Xml/XmlNode.h, Source/Security/FileSignatureVerifier.h, Source/Security/ProcessSecurity.h, Source/UI/Achievement/UIAchWnd.h, Source/UI/AdventureGuide/UIAdventureGuide.h, Source/UI/Buttons/UIBalloonOpenBtn.h, Source/UI/Buttons/UIMiniBtnWnd.h, Source/UI/Buttons/UISlotBitmap.h, Source/UI/Buttons/UIStaticBitmap.h, Source/UI/Buttons/UIStaticItem.h, Source/UI/Buttons/UIWindowCallBtnWnd.h, Source/UI/CashEmotion/UICashEmotionSprBtn.h, Source/UI/CashShop/UIMileageWnd.h, Source/UI/CashShop/UIPayConfirmWnd.h, Source/UI/Chat/UIChatRoomWnd.h, Source/UI/Dialogs/UIAccountLimitedToolWnd.h, Source/UI/Dialogs/UICntWnd.h, Source/UI/Dialogs/UILoadingWnd.h, Source/UI/Dialogs/UIMessageBox.h, Source/UI/Dialogs/UIMessageBoxAutoreturn.h, Source/UI/Dialogs/UINormalMB.h, Source/UI/Dialogs/UINoteWnd.h, Source/UI/Dialogs/UINoticeWnd.h, Source/UI/Dialogs/UIRPImageWnd.h, Source/UI/Dialogs/UIRPImageWnd2.h, Source/UI/Dialogs/UITalkboxTrapInputWnd.h, Source/UI/Dialogs/UITransMenuWnd.h, Source/UI/Dialogs/UIVideoWnd.h, Source/UI/Dialogs/UIWordDisplayWnd.h, Source/UI/Edit/UIItemTagCtrl.h, Source/UI/Enchant/EnchantUI.h, Source/UI/Events/UICheckAttendanceWnd.h, Source/UI/Events/UIOpenRoulletteWnd.h, Source/UI/Events/UIRoulletteWnd.h, Source/UI/Exchange/UIExchangeUI.h, Source/UI/GameSettings/GameSettingsUI.h, Source/UI/GameSettings/UIBattleMsgOptionWnd.h, Source/UI/GameSettings/UIEscOptionWnd.h, Source/UI/GameSettings/UIHotKeyWnd.h, Source/UI/GameSettings/UIHotkeyGuideWnd.h, Source/UI/GameSettings/UIViewCameraInfoWnd.h, Source/UI/Gauges/UIBarGraph.h, Source/UI/Guild/UIEmblemWnd.h, Source/UI/Guild/UIGuildWnd.h, Source/UI/Items/UIChangeMaterialWnd.h, Source/UI/Items/UICollectionSystemWnd.h, Source/UI/Items/UIEquipmentPropertiesWnd.h, Source/UI/Items/UIGradeEnchantWnd.h, Source/UI/Items/UIIngredientInfoWnd.h, Source/UI/Items/UIItemBaseWnd.h, Source/UI/Items/UIItemCollectionWnd.h, Source/UI/Items/UIItemMoveInfo.h, Source/UI/Items/UIItemPurchaseWnd.h, Source/UI/Items/UIItemReformWnd.h, Source/UI/Items/UIItemSellWnd.h, Source/UI/Items/UIItemSellWnd2.h, Source/UI/Items/UIItemShopWnd.h, Source/UI/Items/UIItemShopWnd2.h, Source/UI/Items/UIItemStoreComboBox.h, Source/UI/Items/UIItemStoreFindWnd.h, Source/UI/Items/UIItemStoreSubWnd.h, Source/UI/Items/UIItemStoreWnd.h, Source/UI/Items/UIItemWnd.h, Source/UI/Items/UILapineScrollBar.h, Source/UI/Items/UILapineUpgradeBoxWnd.h, Source/UI/Items/UIMerchantItemLogWnd.h, Source/UI/Items/UIParaItemShopWnd.h, Source/UI/Items/UIPreviewEquipWnd.h, Source/UI/Items/UIRefiningWnd.h, Source/UI/Items/UISecondCostumeWnd.h, Source/UI/Items/UISelectCartWnd.h, Source/UI/Lists/UIComboBoxEx.h, Source/UI/Lists/UIScrollBarVariants.h, Source/UI/Lists/UIScrollWnd.h, Source/UI/Lists/UITagListBox.h, Source/UI/Login/FuncDrawWNDChar.h, Source/UI/Login/UIChangeNameWnd.h, Source/UI/Login/UIDescriptRace.h, Source/UI/Login/UIEmailAddressWnd.h, Source/UI/Login/UILoginOTPWnd.h, Source/UI/Login/UILoginWnd.h, Source/UI/Login/UIMakeCharWnd.h, Source/UI/Login/UINewMakeCharWnd.h, Source/UI/Login/UINewSelectCharWnd.h, Source/UI/Login/UIPasswordWnd.h, Source/UI/Login/UISecondPasswordEditWnd.h, Source/UI/Login/UISelCharForUServerWnd.h, Source/UI/Login/UISelectServerWnd.h, Source/UI/Login/UIWaitDBSaveWnd.h, Source/UI/Macro/UICaptchaPreviewWnd.h, Source/UI/Macro/UICaptchaRegisterWnd.h, Source/UI/Macro/UIMacroBlackListCheckWnd.h, Source/UI/Macro/UIMacroDetectorWnd.h, Source/UI/Macro/UIMacroReport.h, Source/UI/Macro/UIMacroUserInfoWnd.h, Source/UI/Monster/UIMonsterDisplayWnd.h, Source/UI/Monster/UIMonsterInfoWnd.h, Source/UI/Navigation/NavigationLink.h, Source/UI/Navigation/UIChooseWarpWnd.h, Source/UI/Navigation/UIListBoxNavi.h, Source/UI/Navigation/UIListBoxNaviSearch.h, Source/UI/Navigation/UIMemorialDunWnd.h, Source/UI/Navigation/UIMiniMapWnd.h, Source/UI/Navigation/UIMinimapZoomWnd.h, Source/UI/Navigation/UINavigationHelpWnd.h, Source/UI/Navigation/UINavigationWnd.h, Source/UI/Navigation/UIRoMapWnd.h, Source/UI/Navigation/UIScrollBarNavi.h, Source/UI/Navigation/UIShowWarpWnd.h, Source/UI/Party/MiniPartyGrid.h, Source/UI/Party/MiniPartyPlacement.h, Source/UI/Party/MiniPartyWndAreaMgr.h, Source/UI/Party/UIJobSlotButton.h, Source/UI/Party/UIPartyBookingHelpWnd.h, Source/UI/Party/UISeekPartyListWnd.h, Source/UI/Party/UISeekPartyMBWnd.h, Source/UI/Party/UISeekPartyWnd.h, Source/UI/ProbabilityTable/UIProbabilityTable.h, Source/UI/Quest/UINotifyQuestWnd.h, Source/UI/Quest/UIOngoingQuestInfo.h, Source/UI/Quest/UIRecommendedQuestInfo.h, Source/UI/Quest/UIRenewQuestUI.h, Source/UI/Quest/UIRenewQuestWnd.h, Source/UI/Replay/UIReplayButton.h, Source/UI/Replay/UIReplayControlWnd.h, Source/UI/Replay/UIReplayListBox.h, Source/UI/Replay/UIReplayRECControlWnd.h, Source/UI/Replay/UISelectReplayDataWnd.h, Source/UI/Repute/UIReputeWnd.h, Source/UI/Rodex/UIOpenMailBoxWnd.h, Source/UI/Rodex/UIRodexContentsWnd.h, Source/UI/Rodex/UIRodexInboxWnd.h, Source/UI/RuneSystem/UIRuneSystemWindows.h, Source/UI/RuneSystem/UIRuneSystemWnd.h, Source/UI/SelectPackageItemBox/SelectPackageItemBox.h, Source/UI/SelectPackageItemBox/UIPackageBoxNameList.h, Source/UI/Shop/PriceCommission.h, Source/UI/Shop/UIBank_NewWnd.h, Source/UI/Shop/UIBartermarketWnd.h, Source/UI/Shop/UIMerchantItemMyShopWnd.h, Source/UI/Shop/UIMerchantItemPurchaseWnd.h, Source/UI/Shop/UIMerchantItemShopWnd.h, Source/UI/Shop/UIMerchantItemWnd.h, Source/UI/Shop/UIMerchantMirrorItemWnd.h, Source/UI/Shop/UISerachStoreInfoWnd.h, Source/UI/Shop/UInCash_CallWnd.h, Source/UI/Skill/UIDebuffRemoveWnd.h, Source/UI/Skill/UIGraffiStrboxWnd.h, Source/UI/Skill/UINewSkillListWnd.h, Source/UI/SkillDelayInfo/SkillDelayInfo.h, Source/UI/Status/UIBasicInfoWnd.h, Source/UI/Status/UIHomunInfoWnd.h, Source/UI/Status/UIJobListWnd.h, Source/UI/Status/UIMerInfoWnd.h, Source/UI/Status/UIPetEvolutionWnd.h, Source/UI/Status/UIPetInfoWnd.h, Source/UI/Status/UIPetTamingDeceiveWnd.h, Source/UI/Status/UIRebirthWnd.h, Source/UI/StylingShop/UIStylingShopWnd.h, Source/UI/Text/TextTags.h, Source/UI/Text/UIBroadcastBalloon.h, Source/UI/Text/UIRoundBoxTooltipWnd.h, Source/UI/Window/FrameSkin.h, Source/UI/Window/UIBasicCtrl.h, Source/UI/Window/UIControl.h, Source/UI/Window/UIWindowMgr.inl, Source/Utility/Cipher/EncryptedName.h, Source/Utility/Hash/CRC32.h, Source/Utility/Hash/GGHash.h, Source/Utility/Hash/GGHashMgr.h, Source/Utility/Hash/Md5State.h, Source/Utility/Hash/SHA3.h, Source/Utility/Hash/XxHash3.h, Source/Utility/Text/GuidParse.h, Source/Utility/Text/Tokenizer.h, Source/Utility/Zlib.h, Source/ActorPickNode.h, Source/Client/ModeFade.h, Source/Client/ModeFadeOut.h, Source/Client/ModeScreenshot.h, Source/Client/Registry.h, Source/Client/Replay.h, Source/Client/ReplayRecordOption.h, Source/Client/Session.h, Source/Client/Timer.h, Source/Network/ActorNamePacket.h, Source/Network/ClientKeepalive.h, Source/Network/ClientOptionPacket.h, Source/Network/ExecutableDigestPacket.h, Source/Network/GameTickPacket.h, Source/Render/ActionSpriteDrawing.h, Source/Render/AuxiliarySubmission.h, Source/Render/BitmapDrawing.h, Source/Render/BlendColor.h, Source/Render/DeviceSelection.h, Source/Render/Direct3DErrors.h, Source/Render/DisplayMode.h, Source/Render/RenderAdapter.h, Source/Render/RenderBackends.h, Source/Render/RendererDX7.h, Source/Render/ScreenGeometry.h, Source/Render/ScreenRectangle.h, Source/Render/SpriteGeometry.h, Source/Render/SpriteQuad.h, Source/Render/TextureQuad.h, Source/Render/TextureStageModes.h, Source/Resource/BinkRuntime.h, Source/Resource/EZeffectResource.h, Source/Resource/EmblemResource.h, Source/Resource/GifLzw.h, Source/Resource/GifResource.h, Source/Resource/ImfResource.h, Source/Resource/PaletteResource.h, Source/Resource/RmaResource.h, Source/Resource/SkinPalette.h, Source/Resource/TextureNames.h, Source/Resource/XmlNode.h, Source/UI/Buttons/UICashEmotionSprBtn.h, Source/UI/Buttons/UIDescriptRace.h, Source/UI/Buttons/UIItemMoveInfo.h, Source/UI/Buttons/UIJobSlotButton.h, Source/UI/Buttons/UIReplayButton.h, Source/UI/Dialogs/UIChooseWarpWnd.h, Source/UI/Dialogs/UIEmailAddressWnd.h, Source/UI/Dialogs/UIGraffiStrboxWnd.h, Source/UI/Dialogs/UIMemorialDunWnd.h, Source/UI/Dialogs/UIMiniMapWnd.h, Source/UI/Dialogs/UIMinimapZoomWnd.h, Source/UI/Dialogs/UINotifyQuestWnd.h, Source/UI/Dialogs/UIPasswordWnd.h, Source/UI/Dialogs/UIPetTamingDeceiveWnd.h, Source/UI/Dialogs/UISecondPasswordEditWnd.h, Source/UI/Dialogs/UISelectCartWnd.h, Source/UI/Dialogs/UIWaitDBSaveWnd.h, Source/UI/FrameSkin.h, Source/UI/Item/UIEquipmentPropertiesWnd.h, Source/UI/Item/UIItemBaseWnd.h, Source/UI/Item/UIItemPurchaseWnd.h, Source/UI/Item/UIItemSellWnd.h, Source/UI/Item/UIItemSellWnd2.h, Source/UI/Item/UIItemShopWnd.h, Source/UI/Item/UIItemShopWnd2.h, Source/UI/Item/UIItemStoreFindWnd.h, Source/UI/Item/UIItemStoreSubWnd.h, Source/UI/Item/UIItemStoreWnd.h, Source/UI/Item/UIItemWnd.h, Source/UI/Item/UIMerchantItemLogWnd.h, Source/UI/Item/UIParaItemShopWnd.h, Source/UI/Lists/UIItemStoreComboBox.h, Source/UI/Lists/UIListBoxNavi.h, Source/UI/Lists/UIListBoxNaviSearch.h, Source/UI/Lists/UIPackageBoxNameList.h, Source/UI/Lists/UIReplayListBox.h, Source/UI/Lists/UIScrollBarNavi.h, Source/UI/MiniPartyGrid.h, Source/UI/MiniPartyPlacement.h, Source/UI/PriceCommission.h, Source/UI/Text/NavigationLink.h, Source/UI/Text/UIAchWnd.h, Source/UI/TextTags.h, Source/UI/UIBarGraph.h, Source/UI/UIBartermarketWnd.h, Source/UI/UIBasicCtrl.h, Source/UI/UIBroadcastBalloon.h, Source/UI/UICaptchaPreviewWnd.h, Source/UI/UICaptchaRegisterWnd.h, Source/UI/UIChangeMaterialWnd.h, Source/UI/UICheckAttendanceWnd.h, Source/UI/UIGradeEnchantWnd.h, Source/UI/UIHotkeyGuideWnd.h, Source/UI/UIIngredientInfoWnd.h, Source/UI/UIItemReformWnd.h, Source/UI/UILapineScrollBar.h, Source/UI/UILapineUpgradeBoxWnd.h, Source/UI/UIMacroBlackListCheckWnd.h, Source/UI/UIMacroDetectorWnd.h, Source/UI/UIMacroReport.h, Source/UI/UIMacroUserInfoWnd.h, Source/UI/UIPreviewEquipWnd.h, Source/UI/UIRefiningWnd.h, Source/UI/UIReputeWnd.h, Source/UI/UIRoundBoxTooltipWnd.h, Source/UI/UIScrollWnd.h, Source/UI/UISlotBitmap.h, Source/UI/UIStaticBitmap.h, Source/UI/UIStaticItem.h, Source/UI/Window/FuncDrawWNDChar.h, Source/UI/Window/MiniPartyWndAreaMgr.h, Source/UI/Window/UIAccountLimitedToolWnd.h, Source/UI/Window/UIBalloonOpenBtn.h, Source/UI/Window/UIBank_NewWnd.h, Source/UI/Window/UIBasicInfoWnd.h, Source/UI/Window/UIBattleMsgOptionWnd.h, Source/UI/Window/UIChangeNameWnd.h, Source/UI/Window/UIChatRoomWnd.h, Source/UI/Window/UICntWnd.h, Source/UI/Window/UICollectionSystemWnd.h, Source/UI/Window/UIDebuffRemoveWnd.h, Source/UI/Window/UIEmblemWnd.h, Source/UI/Window/UIEscOptionWnd.h, Source/UI/Window/UIHomunInfoWnd.h, Source/UI/Window/UIHotKeyWnd.h, Source/UI/Window/UIJobListWnd.h, Source/UI/Window/UILoginOTPWnd.h, Source/UI/Window/UILoginWnd.h, Source/UI/Window/UIMakeCharWnd.h, Source/UI/Window/UIMerInfoWnd.h, Source/UI/Window/UIMessageBox.h, Source/UI/Window/UIMessageBoxAutoreturn.h, Source/UI/Window/UIMileageWnd.h, Source/UI/Window/UIMiniBtnWnd.h, Source/UI/Window/UIMonsterDisplayWnd.h, Source/UI/Window/UIMonsterInfoWnd.h, Source/UI/Window/UINavigationHelpWnd.h, Source/UI/Window/UINavigationWnd.h, Source/UI/Window/UINewMakeCharWnd.h, Source/UI/Window/UINewSelectCharWnd.h, Source/UI/Window/UINewSkillListWnd.h, Source/UI/Window/UINormalMB.h, Source/UI/Window/UINoteWnd.h, Source/UI/Window/UINoticeWnd.h, Source/UI/Window/UIOpenMailBoxWnd.h, Source/UI/Window/UIOpenRoulletteWnd.h, Source/UI/Window/UIPartyBookingHelpWnd.h, Source/UI/Window/UIPayConfirmWnd.h, Source/UI/Window/UIPetEvolutionWnd.h, Source/UI/Window/UIPetInfoWnd.h, Source/UI/Window/UIRPImageWnd.h, Source/UI/Window/UIRPImageWnd2.h, Source/UI/Window/UIRebirthWnd.h, Source/UI/Window/UIReplayControlWnd.h, Source/UI/Window/UIReplayRECControlWnd.h, Source/UI/Window/UIRoMapWnd.h, Source/UI/Window/UIRodexContentsWnd.h, Source/UI/Window/UIRoulletteWnd.h, Source/UI/Window/UISecondCostumeWnd.h, Source/UI/Window/UISeekPartyListWnd.h, Source/UI/Window/UISeekPartyMBWnd.h, Source/UI/Window/UISeekPartyWnd.h, Source/UI/Window/UISelCharForUServerWnd.h, Source/UI/Window/UISelectReplayDataWnd.h, Source/UI/Window/UISelectServerWnd.h, Source/UI/Window/UISerachStoreInfoWnd.h, Source/UI/Window/UIShowWarpWnd.h, Source/UI/Window/UITalkboxTrapInputWnd.h, Source/UI/Window/UITransMenuWnd.h, Source/UI/Window/UIVideoWnd.h, Source/UI/Window/UIViewCameraInfoWnd.h, Source/UI/Window/UIWindowCallBtnWnd.h, Source/UI/Window/UIWordDisplayWnd.h, Source/Utility/CRC32.h, Source/Utility/Compression/Zlib.h, Source/Utility/EncryptedName.h, Source/Utility/FileSignatureVerifier.h, Source/Utility/GGHash.h, Source/Utility/GGHashMgr.h, Source/Utility/GuidParse.h, Source/Utility/JsonCppLoader.h, Source/Utility/Md5State.h, Source/Utility/NFileLog.h, Source/Utility/NIPAddr.h, Source/Utility/ProcessSecurity.h, Source/Utility/RegistryKey.h, Source/Utility/SHA3.h, Source/Utility/Tokenizer.h, Source/Utility/XxHash3.h. Adds to the build: Source/Client/Application/ClientOptions.cpp, Source/Client/Application/Registry.cpp, Source/Client/Application/RegistryKey.cpp, Source/Client/Application/Timer.cpp, Source/Client/Mode/EntityInit.cpp, Source/Client/Mode/ModeBaseEvents.cpp, Source/Client/Mode/ModeCursorDrawing.cpp, Source/Client/Mode/ModeFade.cpp, Source/Client/Mode/ModeFadeOut.cpp, Source/Client/Mode/ModeScreenshot.cpp, Source/Client/Mode/ModeTransitions.cpp, Source/Client/Replay/Replay.cpp, Source/Client/Replay/ReplayControl.cpp, Source/Client/Replay/ReplayPacketRecorder.cpp, Source/Client/Session/Session.cpp, Source/Client/Session/SessionAchievements.cpp, Source/Client/Session/SessionParty.cpp, Source/Client/Session/SessionPredicates.cpp, Source/Client/Session/SessionState.cpp, Source/Contents/Actors/ActorPickNode.cpp, Source/File/NFileLog.cpp, Source/Network/NIPAddr.cpp, Source/Network/Packets/ActorNamePacket.cpp, Source/Network/Packets/ClientKeepalive.cpp, Source/Network/Packets/ClientOptionPacket.cpp, Source/Network/Packets/ExecutableDigestPacket.cpp, Source/Network/Packets/GameTickPacket.cpp, Source/Render/DX7/AlphaQueuesDX7.cpp, Source/Render/DX7/AuxiliaryQueuesDX7.cpp, Source/Render/DX7/OpaqueQueuesDX7.cpp, Source/Render/DX7/RendererDX7.cpp, Source/Render/DX9/DeviceCapabilitiesDX9.cpp, Source/Render/Device/DeviceSelection.cpp, Source/Render/Device/Direct3DErrors.cpp, Source/Render/Device/DisplayMode.cpp, Source/Render/Device/RenderAdapter.cpp, Source/Render/Device/RenderBackends.cpp, Source/Render/Drawing/ActionSpriteDrawing.cpp, Source/Render/Drawing/BitmapDrawing.cpp, Source/Render/Drawing/BlendColor.cpp, Source/Render/Drawing/SpriteGeometry.cpp, Source/Render/Primitives/AlphaRectangle.cpp, Source/Render/Primitives/AuxiliarySubmission.cpp, Source/Render/Primitives/SpriteQuad.cpp, Source/Render/Primitives/TextureQuad.cpp, Source/Render/Primitives/UIRPDataDrawing.cpp, Source/Render/Projection/ScreenGeometry.cpp, Source/Render/Projection/ScreenRectangle.cpp, Source/Render/Projection/ViewportProjection.cpp, Source/Resource/Bitmap/EmblemResource.cpp, Source/Resource/Bitmap/GifLzw.cpp, Source/Resource/Bitmap/GifResource.cpp, Source/Resource/Bitmap/PaletteResource.cpp, Source/Resource/Bitmap/SkinPalette.cpp, Source/Resource/Bitmap/TextureNames.cpp, Source/Resource/Effects/EZeffectResource.cpp, Source/Resource/Json/JsonCppLoader.cpp, Source/Resource/Models/RmaResource.cpp, Source/Resource/Sprites/ImfLayerIndex.cpp, Source/Resource/Sprites/ImfResource.cpp, Source/Resource/Xml/XmlNode.cpp, Source/Resource/Xml/XmlParsing.cpp, Source/Security/FileSignatureVerifier.cpp, Source/Security/ProcessSecurity.cpp, Source/Security/UnknownA68.cpp, Source/UI/Achievement/UIAchWnd.cpp, Source/UI/Buttons/UIBalloonOpenBtn.cpp, Source/UI/Buttons/UIMiniBtnWnd.cpp, Source/UI/Buttons/UISlotBitmap.cpp, Source/UI/Buttons/UIStaticBitmap.cpp, Source/UI/Buttons/UIStaticItem.cpp, Source/UI/CashShop/UIMileageWnd.cpp, Source/UI/Chat/UIZeroChatWnd.cpp, Source/UI/Dialogs/UIAccountLimitedToolWnd.cpp, Source/UI/Dialogs/UILocaleTextWnd.cpp, Source/UI/Dialogs/UIMessageBox.cpp, Source/UI/Dialogs/UINormalMB.cpp, Source/UI/Dialogs/UINoteWnd.cpp, Source/UI/Dialogs/UINoticeWnd.cpp, Source/UI/Dialogs/UIRPImageWnd.cpp, Source/UI/Dialogs/UIRPImageWnd2.cpp, Source/UI/Dialogs/UITransMenuWnd.cpp, Source/UI/Dialogs/UIVideoWnd.cpp, Source/UI/Dialogs/UIWordDisplayWnd.cpp, Source/UI/Events/UICheckAttendanceWnd.cpp, Source/UI/Events/UIOpenRoulletteWnd.cpp, Source/UI/Events/UIRoulletteWnd.cpp, Source/UI/GameSettings/UIBattleMsgOptionWnd.cpp, Source/UI/GameSettings/UIEscOptionWnd.cpp, Source/UI/GameSettings/UIHotKeyWnd.cpp, Source/UI/GameSettings/UIHotkeyGuideWnd.cpp, Source/UI/GameSettings/UIViewCameraInfoWnd.cpp, Source/UI/Gauges/UIBarGraph.cpp, Source/UI/Guild/UIEmblemWnd.cpp, Source/UI/Items/UIChangeMaterialWnd.cpp, Source/UI/Items/UICollectionSystemWnd.cpp, Source/UI/Items/UIEquipmentPropertiesWnd.cpp, Source/UI/Items/UIGradeEnchantWnd.cpp, Source/UI/Items/UIItemMoveInfo.cpp, Source/UI/Items/UIItemReformWnd.cpp, Source/UI/Items/UIItemStoreComboBox.cpp, Source/UI/Items/UIItemStoreWnd.cpp, Source/UI/Items/UILapineBoxWnd.cpp, Source/UI/Items/UILapineScrollBar.cpp, Source/UI/Items/UILapineUpgradeBoxWnd.cpp, Source/UI/Items/UIMerchantItemLogWnd.cpp, Source/UI/Items/UIParaItemShopWnd.cpp, Source/UI/Items/UIPreviewEquipWnd.cpp, Source/UI/Items/UIRefiningWnd.cpp, Source/UI/Items/UISecondCostumeWnd.cpp, Source/UI/Lists/UIScrollWnd.cpp, Source/UI/Login/FuncDrawWNDChar.cpp, Source/UI/Login/UIChangeNameWnd.cpp, Source/UI/Login/UIDescriptRace.cpp, Source/UI/Login/UIEmailAddressWnd.cpp, Source/UI/Login/UILoginWnd.cpp, Source/UI/Login/UINewMakeCharWnd.cpp, Source/UI/Login/UINewSelectCharWnd.cpp, Source/UI/Login/UIPasswordWnd.cpp, Source/UI/Login/UISelCharForUServerWnd.cpp, Source/UI/Login/UIWaitDBSaveWnd.cpp, Source/UI/Macro/UICaptchaPreviewWnd.cpp, Source/UI/Macro/UICaptchaRegisterWnd.cpp, Source/UI/Macro/UIMacroBlackListCheckWnd.cpp, Source/UI/Macro/UIMacroDetectorWnd.cpp, Source/UI/Macro/UIMacroReport.cpp, Source/UI/Macro/UIMacroUserInfoWnd.cpp, Source/UI/Navigation/NavigationLink.cpp, Source/UI/Navigation/UIListBoxNavi.cpp, Source/UI/Navigation/UIMinimapZoomWnd.cpp, Source/UI/Navigation/UINavigationHelpWnd.cpp, Source/UI/Navigation/UINavigationWnd.cpp, Source/UI/Navigation/UIRoMapWnd.cpp, Source/UI/Navigation/UIScrollBarNavi.cpp, Source/UI/Navigation/UIShowWarpWnd.cpp, Source/UI/Party/MiniPartyGrid.cpp, Source/UI/Party/MiniPartyManager.cpp, Source/UI/Party/MiniPartyPlacement.cpp, Source/UI/Party/MiniPartyUsableArea.cpp, Source/UI/Party/UIJobSlotButton.cpp, Source/UI/Party/UIPartyBookingHelpWnd.cpp, Source/UI/Party/UISeekPartyListWnd.cpp, Source/UI/Party/UISeekPartyMBWnd.cpp, Source/UI/Party/UISeekPartyWnd.cpp, Source/UI/Repute/UIReputeWnd.cpp, Source/UI/Rodex/UIOpenMailBoxWnd.cpp, Source/UI/Rodex/UIRodexContentsWnd.cpp, Source/UI/SelectPackageItemBox/UIPackageBoxNameList.cpp, Source/UI/Shop/PriceCommission.cpp, Source/UI/Shop/UIBartermarketWnd.cpp, Source/UI/Shop/UISerachStoreInfoWnd.cpp, Source/UI/Skill/UIDebuffRemoveWnd.cpp, Source/UI/Skill/UIGraffiStrboxWnd.cpp, Source/UI/Skill/UINewSkillListWnd.cpp, Source/UI/Skill/UINewSkillListWndHitTest.cpp, Source/UI/Status/UIBasicInfoWnd.cpp, Source/UI/Status/UIJobListWnd.cpp, Source/UI/Status/UIPetEvolutionWnd.cpp, Source/UI/Status/UIRebirthWnd.cpp, Source/UI/Text/TextTagExtraction.cpp, Source/UI/Text/TextTagRegistry.cpp, Source/UI/Text/UIBroadcastBalloon.cpp, Source/UI/Text/UIRoundBoxTooltipWnd.cpp, Source/UI/Window/FrameSkin.cpp, Source/UI/Window/UIBasicCtrl.cpp, Source/UI/Window/WindowBackground.cpp, Source/UI/Window/WindowLowerBorder.cpp, Source/UI/Window/WindowOverlay.cpp, Source/UI/Window/WindowSprite.cpp, Source/UI/Window/WindowTitlebar.cpp, Source/Utility/BoolStubs.cpp, Source/Utility/Hash/CRC32.cpp, Source/Utility/Hash/GGHash.cpp, Source/Utility/Hash/GGHashMgr.cpp, Source/Utility/Hash/Md5State.cpp, Source/Utility/Hash/SHA3.cpp, Source/Utility/Hash/XxHash3.cpp, Source/Utility/Lexicon/LexiconTrie.cpp, Source/Utility/Text/GuidParse.cpp, Source/Utility/Text/Tokenizer.cpp Deletes: Source/ActorPickNode.cpp, Source/ActorPickNode.h, Source/Archive/UnknownA68.cpp, Source/Client/ClientOptions.cpp, Source/Client/ModeBaseEvents.cpp, Source/Client/ModeCursorDrawing.cpp, Source/Client/ModeFade.cpp, Source/Client/ModeFade.h, Source/Client/ModeFadeOut.cpp, Source/Client/ModeFadeOut.h, Source/Client/ModeScreenshot.cpp, Source/Client/ModeScreenshot.h, Source/Client/ModeTransitions.cpp, Source/Client/Registry.cpp, Source/Client/Registry.h, Source/Client/Replay.cpp, Source/Client/Replay.h, Source/Client/ReplayControl.cpp, Source/Client/ReplayPacketRecorder.cpp, Source/Client/ReplayRecordOption.h, Source/Client/Session.cpp, Source/Client/Session.h, Source/Client/SessionAchievements.cpp, Source/Client/SessionParty.cpp, Source/Client/SessionPredicates.cpp, Source/Client/SessionState.cpp, Source/Client/Timer.cpp, Source/Client/Timer.h, Source/EntityInit.cpp, Source/Interface/BoolStubs.cpp, Source/LexiconTrie.cpp, Source/Network/ActorNamePacket.cpp, Source/Network/ActorNamePacket.h, Source/Network/ClientKeepalive.cpp, Source/Network/ClientKeepalive.h, Source/Network/ClientOptionPacket.cpp, Source/Network/ClientOptionPacket.h, Source/Network/ExecutableDigestPacket.cpp, Source/Network/ExecutableDigestPacket.h, Source/Network/GameTickPacket.cpp, Source/Network/GameTickPacket.h, Source/Render/ActionSpriteDrawing.cpp, Source/Render/ActionSpriteDrawing.h, Source/Render/AlphaQueuesDX7.cpp, Source/Render/AlphaRectangle.cpp, Source/Render/AuxiliaryQueuesDX7.cpp, Source/Render/AuxiliarySubmission.cpp, Source/Render/AuxiliarySubmission.h, Source/Render/BitmapDrawing.cpp, Source/Render/BitmapDrawing.h, Source/Render/BlendColor.cpp, Source/Render/BlendColor.h, Source/Render/DeviceCapabilitiesDX9.cpp, Source/Render/DeviceSelection.cpp, Source/Render/DeviceSelection.h, Source/Render/Direct3DErrors.cpp, Source/Render/Direct3DErrors.h, Source/Render/DisplayMode.cpp, Source/Render/DisplayMode.h, Source/Render/OpaqueQueuesDX7.cpp, Source/Render/RenderAdapter.cpp, Source/Render/RenderAdapter.h, Source/Render/RenderBackends.cpp, Source/Render/RenderBackends.h, Source/Render/RendererDX7.cpp, Source/Render/RendererDX7.h, Source/Render/ScreenGeometry.cpp, Source/Render/ScreenGeometry.h, Source/Render/ScreenRectangle.cpp, Source/Render/ScreenRectangle.h, Source/Render/SpriteGeometry.cpp, Source/Render/SpriteGeometry.h, Source/Render/SpriteQuad.cpp, Source/Render/SpriteQuad.h, Source/Render/TextureQuad.cpp, Source/Render/TextureQuad.h, Source/Render/TextureStageModes.h, Source/Render/UIRPDataDrawing.cpp, Source/Render/ViewportProjection.cpp, Source/Resource/BinkRuntime.h, Source/Resource/EZeffectResource.cpp, Source/Resource/EZeffectResource.h, Source/Resource/EmblemResource.cpp, Source/Resource/EmblemResource.h, Source/Resource/GifLzw.cpp, Source/Resource/GifLzw.h, Source/Resource/GifResource.cpp, Source/Resource/GifResource.h, Source/Resource/ImfLayerIndex.cpp, Source/Resource/ImfResource.cpp, Source/Resource/ImfResource.h, Source/Resource/PaletteResource.cpp, Source/Resource/PaletteResource.h, Source/Resource/RmaResource.cpp, Source/Resource/RmaResource.h, Source/Resource/SkinPalette.cpp, Source/Resource/SkinPalette.h, Source/Resource/TextureNames.cpp, Source/Resource/TextureNames.h, Source/Resource/XmlNode.cpp, Source/Resource/XmlNode.h, Source/Resource/XmlParsing.cpp, Source/UI/Buttons/UICashEmotionSprBtn.h, Source/UI/Buttons/UIDescriptRace.cpp, Source/UI/Buttons/UIDescriptRace.h, Source/UI/Buttons/UIItemMoveInfo.cpp, Source/UI/Buttons/UIItemMoveInfo.h, Source/UI/Buttons/UIJobSlotButton.cpp, Source/UI/Buttons/UIJobSlotButton.h, Source/UI/Buttons/UIReplayButton.h, Source/UI/Dialogs/UIChooseWarpWnd.h, Source/UI/Dialogs/UIEmailAddressWnd.cpp, Source/UI/Dialogs/UIEmailAddressWnd.h, Source/UI/Dialogs/UIGraffiStrboxWnd.cpp, Source/UI/Dialogs/UIGraffiStrboxWnd.h, Source/UI/Dialogs/UIMemorialDunWnd.h, Source/UI/Dialogs/UIMiniMapWnd.h, Source/UI/Dialogs/UIMinimapZoomWnd.cpp, Source/UI/Dialogs/UIMinimapZoomWnd.h, Source/UI/Dialogs/UINotifyQuestWnd.h, Source/UI/Dialogs/UIPasswordWnd.cpp, Source/UI/Dialogs/UIPasswordWnd.h, Source/UI/Dialogs/UIPetTamingDeceiveWnd.h, Source/UI/Dialogs/UISecondPasswordEditWnd.h, Source/UI/Dialogs/UISelectCartWnd.h, Source/UI/Dialogs/UIWaitDBSaveWnd.cpp, Source/UI/Dialogs/UIWaitDBSaveWnd.h, Source/UI/FrameSkin.cpp, Source/UI/FrameSkin.h, Source/UI/Item/UIEquipmentPropertiesWnd.cpp, Source/UI/Item/UIEquipmentPropertiesWnd.h, Source/UI/Item/UIItemBaseWnd.h, Source/UI/Item/UIItemPurchaseWnd.h, Source/UI/Item/UIItemSellWnd.h, Source/UI/Item/UIItemSellWnd2.h, Source/UI/Item/UIItemShopWnd.h, Source/UI/Item/UIItemShopWnd2.h, Source/UI/Item/UIItemStoreFindWnd.h, Source/UI/Item/UIItemStoreSubWnd.h, Source/UI/Item/UIItemStoreWnd.cpp, Source/UI/Item/UIItemStoreWnd.h, Source/UI/Item/UIItemWnd.h, Source/UI/Item/UIMerchantItemLogWnd.cpp, Source/UI/Item/UIMerchantItemLogWnd.h, Source/UI/Item/UIParaItemShopWnd.cpp, Source/UI/Item/UIParaItemShopWnd.h, Source/UI/Lists/UIItemStoreComboBox.cpp, Source/UI/Lists/UIItemStoreComboBox.h, Source/UI/Lists/UIListBoxNavi.cpp, Source/UI/Lists/UIListBoxNavi.h, Source/UI/Lists/UIListBoxNaviSearch.h, Source/UI/Lists/UIPackageBoxNameList.cpp, Source/UI/Lists/UIPackageBoxNameList.h, Source/UI/Lists/UIReplayListBox.h, Source/UI/Lists/UIScrollBarNavi.cpp, Source/UI/Lists/UIScrollBarNavi.h, Source/UI/MiniPartyGrid.cpp, Source/UI/MiniPartyGrid.h, Source/UI/MiniPartyManager.cpp, Source/UI/MiniPartyPlacement.cpp, Source/UI/MiniPartyPlacement.h, Source/UI/MiniPartyUsableArea.cpp, Source/UI/PriceCommission.cpp, Source/UI/PriceCommission.h, Source/UI/Text/NavigationLink.cpp, Source/UI/Text/NavigationLink.h, Source/UI/Text/UIAchWnd.cpp, Source/UI/Text/UIAchWnd.h, Source/UI/TextTagExtraction.cpp, Source/UI/TextTagRegistry.cpp, Source/UI/TextTags.h, Source/UI/UIBarGraph.cpp, Source/UI/UIBarGraph.h, Source/UI/UIBartermarketWnd.cpp, Source/UI/UIBartermarketWnd.h, Source/UI/UIBasicCtrl.cpp, Source/UI/UIBasicCtrl.h, Source/UI/UIBroadcastBalloon.cpp, Source/UI/UIBroadcastBalloon.h, Source/UI/UICaptchaPreviewWnd.cpp, Source/UI/UICaptchaPreviewWnd.h, Source/UI/UICaptchaRegisterWnd.cpp, Source/UI/UICaptchaRegisterWnd.h, Source/UI/UIChangeMaterialWnd.cpp, Source/UI/UIChangeMaterialWnd.h, Source/UI/UICheckAttendanceWnd.cpp, Source/UI/UICheckAttendanceWnd.h, Source/UI/UIGradeEnchantWnd.cpp, Source/UI/UIGradeEnchantWnd.h, Source/UI/UIHotkeyGuideWnd.cpp, Source/UI/UIHotkeyGuideWnd.h, Source/UI/UIIngredientInfoWnd.h, Source/UI/UIItemReformWnd.cpp, Source/UI/UIItemReformWnd.h, Source/UI/UILapineBoxWnd.cpp, Source/UI/UILapineScrollBar.cpp, Source/UI/UILapineScrollBar.h, Source/UI/UILapineUpgradeBoxWnd.cpp, Source/UI/UILapineUpgradeBoxWnd.h, Source/UI/UIMacroBlackListCheckWnd.cpp, Source/UI/UIMacroBlackListCheckWnd.h, Source/UI/UIMacroDetectorWnd.cpp, Source/UI/UIMacroDetectorWnd.h, Source/UI/UIMacroReport.cpp, Source/UI/UIMacroReport.h, Source/UI/UIMacroUserInfoWnd.cpp, Source/UI/UIMacroUserInfoWnd.h, Source/UI/UIPreviewEquipWnd.cpp, Source/UI/UIPreviewEquipWnd.h, Source/UI/UIRefiningWnd.cpp, Source/UI/UIRefiningWnd.h, Source/UI/UIReputeWnd.cpp, Source/UI/UIReputeWnd.h, Source/UI/UIRoundBoxTooltipWnd.cpp, Source/UI/UIRoundBoxTooltipWnd.h, Source/UI/UIScrollWnd.cpp, Source/UI/UIScrollWnd.h, Source/UI/UISlotBitmap.cpp, Source/UI/UISlotBitmap.h, Source/UI/UIStaticBitmap.cpp, Source/UI/UIStaticBitmap.h, Source/UI/UIStaticItem.cpp, Source/UI/UIStaticItem.h, Source/UI/Window/FuncDrawWNDChar.cpp, Source/UI/Window/FuncDrawWNDChar.h, Source/UI/Window/MiniPartyWndAreaMgr.h, Source/UI/Window/UIAccountLimitedToolWnd.cpp, Source/UI/Window/UIAccountLimitedToolWnd.h, Source/UI/Window/UIBalloonOpenBtn.cpp, Source/UI/Window/UIBalloonOpenBtn.h, Source/UI/Window/UIBank_NewWnd.h, Source/UI/Window/UIBasicInfoWnd.cpp, Source/UI/Window/UIBasicInfoWnd.h, Source/UI/Window/UIBattleMsgOptionWnd.cpp, Source/UI/Window/UIBattleMsgOptionWnd.h, Source/UI/Window/UIChangeNameWnd.cpp, Source/UI/Window/UIChangeNameWnd.h, Source/UI/Window/UIChatRoomWnd.h, Source/UI/Window/UICntWnd.h, Source/UI/Window/UICollectionSystemWnd.cpp, Source/UI/Window/UICollectionSystemWnd.h, Source/UI/Window/UIDebuffRemoveWnd.cpp, Source/UI/Window/UIDebuffRemoveWnd.h, Source/UI/Window/UIEmblemWnd.cpp, Source/UI/Window/UIEmblemWnd.h, Source/UI/Window/UIEscOptionWnd.cpp, Source/UI/Window/UIEscOptionWnd.h, Source/UI/Window/UIHomunInfoWnd.h, Source/UI/Window/UIHotKeyWnd.cpp, Source/UI/Window/UIHotKeyWnd.h, Source/UI/Window/UIJobListWnd.cpp, Source/UI/Window/UIJobListWnd.h, Source/UI/Window/UILocaleTextWnd.cpp, Source/UI/Window/UILoginOTPWnd.h, Source/UI/Window/UILoginWnd.cpp, Source/UI/Window/UILoginWnd.h, Source/UI/Window/UIMakeCharWnd.h, Source/UI/Window/UIMerInfoWnd.h, Source/UI/Window/UIMessageBox.cpp, Source/UI/Window/UIMessageBox.h, Source/UI/Window/UIMessageBoxAutoreturn.h, Source/UI/Window/UIMileageWnd.cpp, Source/UI/Window/UIMileageWnd.h, Source/UI/Window/UIMiniBtnWnd.cpp, Source/UI/Window/UIMiniBtnWnd.h, Source/UI/Window/UIMonsterDisplayWnd.h, Source/UI/Window/UIMonsterInfoWnd.h, Source/UI/Window/UINavigationHelpWnd.cpp, Source/UI/Window/UINavigationHelpWnd.h, Source/UI/Window/UINavigationWnd.cpp, Source/UI/Window/UINavigationWnd.h, Source/UI/Window/UINewMakeCharWnd.cpp, Source/UI/Window/UINewMakeCharWnd.h, Source/UI/Window/UINewSelectCharWnd.cpp, Source/UI/Window/UINewSelectCharWnd.h, Source/UI/Window/UINewSkillListWnd.cpp, Source/UI/Window/UINewSkillListWnd.h, Source/UI/Window/UINewSkillListWndHitTest.cpp, Source/UI/Window/UINormalMB.cpp, Source/UI/Window/UINormalMB.h, Source/UI/Window/UINoteWnd.cpp, Source/UI/Window/UINoteWnd.h, Source/UI/Window/UINoticeWnd.cpp, Source/UI/Window/UINoticeWnd.h, Source/UI/Window/UIOpenMailBoxWnd.cpp, Source/UI/Window/UIOpenMailBoxWnd.h, Source/UI/Window/UIOpenRoulletteWnd.cpp, Source/UI/Window/UIOpenRoulletteWnd.h, Source/UI/Window/UIPartyBookingHelpWnd.cpp, Source/UI/Window/UIPartyBookingHelpWnd.h, Source/UI/Window/UIPayConfirmWnd.h, Source/UI/Window/UIPetEvolutionWnd.cpp, Source/UI/Window/UIPetEvolutionWnd.h, Source/UI/Window/UIPetInfoWnd.h, Source/UI/Window/UIRPImageWnd.cpp, Source/UI/Window/UIRPImageWnd.h, Source/UI/Window/UIRPImageWnd2.cpp, Source/UI/Window/UIRPImageWnd2.h, Source/UI/Window/UIRebirthWnd.cpp, Source/UI/Window/UIRebirthWnd.h, Source/UI/Window/UIReplayControlWnd.h, Source/UI/Window/UIReplayRECControlWnd.h, Source/UI/Window/UIRoMapWnd.cpp, Source/UI/Window/UIRoMapWnd.h, Source/UI/Window/UIRodexContentsWnd.cpp, Source/UI/Window/UIRodexContentsWnd.h, Source/UI/Window/UIRoulletteWnd.cpp, Source/UI/Window/UIRoulletteWnd.h, Source/UI/Window/UISecondCostumeWnd.cpp, Source/UI/Window/UISecondCostumeWnd.h, Source/UI/Window/UISeekPartyListWnd.cpp, Source/UI/Window/UISeekPartyListWnd.h, Source/UI/Window/UISeekPartyMBWnd.cpp, Source/UI/Window/UISeekPartyMBWnd.h, Source/UI/Window/UISeekPartyWnd.cpp, Source/UI/Window/UISeekPartyWnd.h, Source/UI/Window/UISelCharForUServerWnd.cpp, Source/UI/Window/UISelCharForUServerWnd.h, Source/UI/Window/UISelectReplayDataWnd.h, Source/UI/Window/UISelectServerWnd.h, Source/UI/Window/UISerachStoreInfoWnd.cpp, Source/UI/Window/UISerachStoreInfoWnd.h, Source/UI/Window/UIShowWarpWnd.cpp, Source/UI/Window/UIShowWarpWnd.h, Source/UI/Window/UITalkboxTrapInputWnd.h, Source/UI/Window/UITransMenuWnd.cpp, Source/UI/Window/UITransMenuWnd.h, Source/UI/Window/UIVideoWnd.cpp, Source/UI/Window/UIVideoWnd.h, Source/UI/Window/UIViewCameraInfoWnd.cpp, Source/UI/Window/UIViewCameraInfoWnd.h, Source/UI/Window/UIWindowCallBtnWnd.h, Source/UI/Window/UIWordDisplayWnd.cpp, Source/UI/Window/UIWordDisplayWnd.h, Source/UI/Window/UIZeroChatWnd.cpp, Source/UI/WindowBackground.cpp, Source/UI/WindowLowerBorder.cpp, Source/UI/WindowOverlay.cpp, Source/UI/WindowSprite.cpp, Source/UI/WindowTitlebar.cpp, Source/Utility/CRC32.cpp, Source/Utility/CRC32.h, Source/Utility/Compression/Zlib.h, Source/Utility/EncryptedName.h, Source/Utility/FileSignatureVerifier.cpp, Source/Utility/FileSignatureVerifier.h, Source/Utility/GGHash.cpp, Source/Utility/GGHash.h, Source/Utility/GGHashMgr.cpp, Source/Utility/GGHashMgr.h, Source/Utility/GuidParse.cpp, Source/Utility/GuidParse.h, Source/Utility/JsonCppLoader.cpp, Source/Utility/JsonCppLoader.h, Source/Utility/Md5State.cpp, Source/Utility/Md5State.h, Source/Utility/NFileLog.cpp, Source/Utility/NFileLog.h, Source/Utility/NIPAddr.cpp, Source/Utility/NIPAddr.h, Source/Utility/ProcessSecurity.cpp, Source/Utility/ProcessSecurity.h, Source/Utility/RegistryKey.cpp, Source/Utility/RegistryKey.h, Source/Utility/SHA3.cpp, Source/Utility/SHA3.h, Source/Utility/Tokenizer.cpp, Source/Utility/Tokenizer.h, Source/Utility/XxHash3.cpp, Source/Utility/XxHash3.h
1157 lines
34 KiB
C++
1157 lines
34 KiB
C++
#include "Client/Mode/ModeMessage.h"
|
|
#include "UI/Window/UIEnums.h"
|
|
#include "Contents/Actors/MercenaryAI.h"
|
|
#include "Contents/Actors/ActorEnums.h"
|
|
|
|
#include "Client/Mode/CGameMode.h"
|
|
#include "Client/Mode/ModeMgr.h"
|
|
#include "Client/Session/Session.h"
|
|
#include "Contents/Actors/ActorStateFlags.h"
|
|
#include "Contents/Actors/GameActor.h"
|
|
#include "Contents/Actors/Pc.h"
|
|
#include "Contents/Skills/ClientSkills.h"
|
|
#include "Contents/Skills/SkillInfo.h"
|
|
#include "Contents/World/World.h"
|
|
#include "File/File.h"
|
|
#include "Network/Connection/Connection.h"
|
|
#include "Network/Packets/PacketId.h"
|
|
#include "Network/Packets/PacketLengths.h"
|
|
#include "UI/Window/UIWindowMgr.h"
|
|
|
|
extern "C" {
|
|
#include <lauxlib.h>
|
|
#include <lua.h>
|
|
#include <lualib.h>
|
|
}
|
|
|
|
#include <cmath>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <cstring>
|
|
#include <list>
|
|
#include <string>
|
|
#include <windows.h>
|
|
#include <timeapi.h>
|
|
|
|
namespace {
|
|
|
|
struct SkillOwnerPacket {
|
|
/* 0000 */ std::int16_t opcode;
|
|
/* 0002 */ std::uint32_t aid;
|
|
};
|
|
|
|
#pragma pack(push, 1)
|
|
struct ActionRequestPacket {
|
|
/* 0000 */ std::int16_t opcode;
|
|
/* 0002 */ std::uint32_t aid;
|
|
/* 0006 */ std::uint32_t target;
|
|
/* 000A */ unsigned char action;
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
static_assert(sizeof(ActionRequestPacket) == 11);
|
|
|
|
// INLINED
|
|
bool IsHomunAid(std::uint32_t aid) {
|
|
return aid != 0xFFFFFFFF && aid == *reinterpret_cast<const std::uint32_t*>(&g_session.spAndHomunculusStats[8]);
|
|
}
|
|
|
|
// INLINED
|
|
bool IsMercenaryAid(std::uint32_t aid) {
|
|
return aid != 0xFFFFFFFF && aid == *reinterpret_cast<const std::uint32_t*>(&g_session.companionTargetState[8]);
|
|
}
|
|
|
|
// INLINED
|
|
bool IsLocalPlayerAid(std::uint32_t aid) {
|
|
CPlayer* player = static_cast<CGameMode*>(g_modeMgr.GetGameMode())->scene->player;
|
|
if (!player) {
|
|
return false;
|
|
}
|
|
return player->GetGdid() == static_cast<int>(aid);
|
|
}
|
|
|
|
// INLINED
|
|
bool IsFirstSkillRange(unsigned id) {
|
|
return id - 8000u <= 60;
|
|
}
|
|
|
|
// INLINED
|
|
bool IsOtherSkillRange(unsigned id) {
|
|
return id - 8200u <= 41 || id - 8400u <= 57;
|
|
}
|
|
|
|
}
|
|
|
|
// OFFSET: 0x00D9E3F0
|
|
// FUNCTION: fn_22327
|
|
CMercenaryAI::CMercenaryAI(int kind) : state(nullptr), actionStarted(0), actionDuration(0), kind(kind), lastTick(0) {
|
|
}
|
|
|
|
// OFFSET: 0x00D9E430
|
|
// FUNCTION: fn_22328
|
|
CMercenaryAI::~CMercenaryAI() {
|
|
if (this->state) {
|
|
lua_close(this->state);
|
|
this->state = nullptr;
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x00D9E500
|
|
// FUNCTION: fn_22330
|
|
int ClampTargetAttackRange(std::uint32_t aid, int distance) {
|
|
CGameActor* actor = static_cast<CGameActor*>(static_cast<CGameMode*>(g_modeMgr.GetGameMode())->scene->GetGameActorByAID(aid));
|
|
if (actor) {
|
|
CGameActor* target = static_cast<CGameActor*>(
|
|
static_cast<CGameMode*>(g_modeMgr.GetGameMode())->scene->GetGameActorByAID(*reinterpret_cast<const std::uint32_t*>(&actor->homunMsg[5]))
|
|
);
|
|
if (target) {
|
|
return distance < target->GetNpcLocationRadius() ? target->GetNpcLocationRadius() : distance;
|
|
}
|
|
}
|
|
return distance;
|
|
}
|
|
|
|
// OFFSET: 0x00D9E570
|
|
// FUNCTION: fn_22331
|
|
void CMercenaryAI::Shutdown() {
|
|
if (this->state) {
|
|
lua_close(this->state);
|
|
this->state = nullptr;
|
|
}
|
|
}
|
|
|
|
// OFFSET: 0x00D9E590
|
|
// FUNCTION: fn_22332
|
|
int CMercenaryAI::Load(const char* path) {
|
|
if (!path) {
|
|
return 1;
|
|
}
|
|
|
|
if (this->state) {
|
|
lua_close(this->state);
|
|
this->state = nullptr;
|
|
}
|
|
|
|
this->state = luaL_newstate();
|
|
if (!this->state) {
|
|
return 2;
|
|
}
|
|
|
|
luaL_openlibs(this->state);
|
|
this->RegisterFunctions();
|
|
|
|
if (luaL_loadfile(this->state, path) == 0) {
|
|
if (lua_pcall(this->state, 0, 0, 0) == 0) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
char message[1024];
|
|
sprintf(message, "%s\n", lua_tostring(this->state, -1));
|
|
MessageBoxA(nullptr, message, "AI.lua error", 0);
|
|
return 3;
|
|
}
|
|
|
|
// OFFSET: 0x00D9E690
|
|
// FUNCTION: fn_22333
|
|
int CMercenaryAI::Process(std::uint32_t aid) {
|
|
char message[1024];
|
|
|
|
CGameActor* actor = static_cast<CGameActor*>(static_cast<CGameMode*>(g_modeMgr.GetGameMode())->scene->GetGameActorByAID(aid));
|
|
if (actor->render.state == 2 || actor->render.state == 7) {
|
|
if (!actor->render.isMotionFinished) {
|
|
return 0;
|
|
}
|
|
actor->SetState(0, 1);
|
|
}
|
|
|
|
if (this->actionStarted == 0) {
|
|
int actionState = 0;
|
|
if (this->kind == 0) {
|
|
actionState = g_session.m_homunActionState;
|
|
} else if (this->kind == 1) {
|
|
actionState = g_session.m_mercenaryActionState;
|
|
}
|
|
|
|
if (actionState != 0 && this->kind == 0) {
|
|
this->actionStarted = GetTickCount();
|
|
if (actionState == 29) {
|
|
if (g_session.m_homunJob >= 6048 && g_session.m_homunJob <= 6052) {
|
|
actor->SetAction(0x30, 4, 0);
|
|
} else {
|
|
actor->SetAction(0x38, 4, 0);
|
|
}
|
|
this->actionDuration = 3000;
|
|
}
|
|
return 0;
|
|
}
|
|
} else if (GetTickCount() - this->actionStarted > this->actionDuration) {
|
|
actor->SetState(0, 1);
|
|
if (this->kind == 0) {
|
|
g_session.m_homunActionState = 0;
|
|
} else if (this->kind == 1) {
|
|
g_session.m_mercenaryActionState = 0;
|
|
}
|
|
this->actionStarted = 0;
|
|
this->actionDuration = 0;
|
|
}
|
|
|
|
std::uint32_t now = GetTickCount();
|
|
if (now - this->lastTick < 140) {
|
|
return 0;
|
|
}
|
|
|
|
this->lastTick = now;
|
|
if (!this->state) {
|
|
return 0;
|
|
}
|
|
|
|
lua_getglobal(this->state, "AI");
|
|
lua_pushnumber(this->state, aid);
|
|
if (lua_pcall(this->state, 1, 0, 0) == 0) {
|
|
return 0;
|
|
}
|
|
|
|
sprintf(message, "%s\n", lua_tostring(this->state, -1));
|
|
MessageBoxA(nullptr, message, "AI.lua error", 0);
|
|
this->Shutdown();
|
|
return 1;
|
|
}
|
|
|
|
int AiGetActors(lua_State* state);
|
|
int AiTrace(lua_State* state);
|
|
int AiGetTick(lua_State* state);
|
|
int AiSkillGround(lua_State* state);
|
|
int AiIsMonster(lua_State* state);
|
|
int AiTraceAI(lua_State* state);
|
|
int AiMoveToOwner(lua_State* state);
|
|
int AiMove(lua_State* state);
|
|
int AiGetMsg(lua_State* state);
|
|
int AiGetResMsg(lua_State* state);
|
|
int AiSkillObject(lua_State* state);
|
|
int AiHomunGetV(lua_State* state);
|
|
int AiMercenaryGetV(lua_State* state);
|
|
int AiHomunAttack(lua_State* state);
|
|
int AiMercenaryAttack(lua_State* state);
|
|
int AiTraceValue(lua_State* state);
|
|
|
|
// OFFSET: 0x00D9E890
|
|
// FUNCTION: fn_22334
|
|
void CMercenaryAI::RegisterFunctions() {
|
|
lua_register(this->state, "GetActors", AiGetActors);
|
|
lua_register(this->state, "Trace", AiTrace);
|
|
lua_register(this->state, "GetTick", AiGetTick);
|
|
lua_register(this->state, "SkillGround", AiSkillGround);
|
|
lua_register(this->state, "IsMonster", AiIsMonster);
|
|
lua_register(this->state, "TraceAI", AiTraceAI);
|
|
lua_register(this->state, "MoveToOwner", AiMoveToOwner);
|
|
lua_register(this->state, "Move", AiMove);
|
|
lua_register(this->state, "GetMsg", AiGetMsg);
|
|
lua_register(this->state, "GetResMsg", AiGetResMsg);
|
|
lua_register(this->state, "SkillObject", AiSkillObject);
|
|
|
|
if (this->kind == 0) {
|
|
lua_register(this->state, "GetV", AiHomunGetV);
|
|
lua_register(this->state, "Attack", AiHomunAttack);
|
|
} else if (this->kind == 1) {
|
|
lua_register(this->state, "GetV", AiMercenaryGetV);
|
|
lua_register(this->state, "Attack", AiMercenaryAttack);
|
|
}
|
|
|
|
lua_register(this->state, "TraceValue", AiTraceValue);
|
|
}
|
|
|
|
// OFFSET: 0x00D9EAF0
|
|
// FUNCTION: fn_22335
|
|
int AiHomunAttack(lua_State* state) {
|
|
if (g_session.GetOption(17) > 0) {
|
|
return 0;
|
|
}
|
|
|
|
std::uint32_t aid = static_cast<std::uint32_t>(lua_tonumber(state, 1));
|
|
std::uint32_t target = static_cast<std::uint32_t>(lua_tonumber(state, 2));
|
|
if (!g_session.IsHomunAid(aid)) {
|
|
return 0;
|
|
}
|
|
if (*reinterpret_cast<const std::uint32_t*>(&g_session.companionTargetState[8]) != 0 && g_session.IsMercenaryAid(target)) {
|
|
return 0;
|
|
}
|
|
|
|
CGameMode* mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode());
|
|
CGameActor* actor = static_cast<CGameActor*>(mode->scene->GetGameActorByAID(aid));
|
|
CGameActor* targetActor = static_cast<CGameActor*>(mode->scene->GetGameActorByAID(target));
|
|
if (!actor || !targetActor) {
|
|
return 0;
|
|
}
|
|
if (StateFlag06(targetActor->GetStateFlags()) || StateFlag01(targetActor->GetStateFlags()) || StateFlag02(targetActor->GetStateFlags())) {
|
|
return 0;
|
|
}
|
|
|
|
// GLOBAL: gl_24908
|
|
static std::uint32_t lastAttackTime;
|
|
if (*reinterpret_cast<const std::uint32_t*>(&g_session.spAndHomunculusStats[0x48]) + lastAttackTime < timeGetTime()) {
|
|
ActionRequestPacket packet;
|
|
packet.opcode = ID_CZ_REQUEST_ACTNPC;
|
|
packet.aid = aid;
|
|
packet.target = target;
|
|
packet.action = 0;
|
|
GetRagConnection().Send(reinterpret_cast<PacketLengths&>(GetRagConnection()).FixedLength(packet.opcode), &packet);
|
|
lastAttackTime = timeGetTime();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// OFFSET: 0x00D9ECA0
|
|
// FUNCTION: fn_22336
|
|
int AiMercenaryAttack(lua_State* state) {
|
|
std::uint32_t aid = static_cast<std::uint32_t>(lua_tonumber(state, 1));
|
|
std::uint32_t target = static_cast<std::uint32_t>(lua_tonumber(state, 2));
|
|
if (!g_session.IsMercenaryAid(aid)) {
|
|
return 0;
|
|
}
|
|
if (*reinterpret_cast<const std::uint32_t*>(&g_session.spAndHomunculusStats[8]) != 0 && g_session.IsHomunAid(target)) {
|
|
return 0;
|
|
}
|
|
|
|
CGameMode* mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode());
|
|
CGameActor* actor = static_cast<CGameActor*>(mode->scene->GetGameActorByAID(aid));
|
|
CGameActor* targetActor = static_cast<CGameActor*>(mode->scene->GetGameActorByAID(target));
|
|
if (!actor || !targetActor) {
|
|
return 0;
|
|
}
|
|
if (StateFlag06(targetActor->GetStateFlags()) || StateFlag01(targetActor->GetStateFlags()) || StateFlag02(targetActor->GetStateFlags())) {
|
|
return 0;
|
|
}
|
|
|
|
// GLOBAL: gl_24909
|
|
static std::uint32_t lastAttackTime;
|
|
if (static_cast<std::uint32_t>(g_session.m_mercenaryStats[7]) + lastAttackTime < timeGetTime()) {
|
|
ActionRequestPacket packet;
|
|
packet.opcode = ID_CZ_REQUEST_ACTNPC;
|
|
packet.aid = aid;
|
|
packet.target = target;
|
|
packet.action = 0;
|
|
GetRagConnection().Send(reinterpret_cast<PacketLengths&>(GetRagConnection()).FixedLength(packet.opcode), &packet);
|
|
lastAttackTime = timeGetTime();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// OFFSET: 0x00D9EE10
|
|
// FUNCTION: fn_22337
|
|
int AiGetActors(lua_State* state) {
|
|
CWorld* world = static_cast<CGameMode*>(g_modeMgr.GetGameMode())->scene;
|
|
lua_newtable(state);
|
|
|
|
int index = 1;
|
|
for (std::list<CRenderObject*>::iterator it = world->actors.begin(); it != world->actors.end(); ++it) {
|
|
int key = index++;
|
|
int accountId = static_cast<int>((*it)->render.accountId);
|
|
lua_pushnumber(state, key);
|
|
lua_pushnumber(state, accountId);
|
|
lua_settable(state, -3);
|
|
}
|
|
|
|
int playerAid = static_cast<int>(g_session.m_aid);
|
|
lua_pushnumber(state, index);
|
|
lua_pushnumber(state, playerAid);
|
|
lua_settable(state, -3);
|
|
return 1;
|
|
}
|
|
|
|
// OFFSET: 0x00D9F270
|
|
// FUNCTION: fn_22340
|
|
int AiGetTick(lua_State* state) {
|
|
lua_pushnumber(state, GetTickCount());
|
|
return 1;
|
|
}
|
|
|
|
// OFFSET: 0x00D9F2B0
|
|
// FUNCTION: fn_22341
|
|
int AiHomunGetV(lua_State* state) {
|
|
CGameMode* mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode());
|
|
int property = static_cast<int>(lua_tonumber(state, 1));
|
|
std::uint32_t aid = static_cast<std::uint32_t>(lua_tonumber(state, 2));
|
|
|
|
CGameActor* actor = nullptr;
|
|
if (aid == g_session.m_aid) {
|
|
actor = mode->scene->player;
|
|
} else {
|
|
actor = static_cast<CGameActor*>(mode->scene->GetGameActorByAID(aid));
|
|
}
|
|
|
|
double result = 0.0;
|
|
switch (property) {
|
|
case V_OWNER:
|
|
result = static_cast<double>(g_session.m_aid);
|
|
break;
|
|
|
|
case V_POSITION:
|
|
case 13:
|
|
if (actor) {
|
|
if (aid != g_session.m_aid) {
|
|
if (StateFlag06(actor->GetStateFlags()) || StateFlag01(actor->GetStateFlags()) || StateFlag02(actor->GetStateFlags())) {
|
|
lua_pushnumber(state, -1.0);
|
|
lua_pushnumber(state, -1.0);
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
int cellX, cellY;
|
|
mode->WorldCell(actor->render.position.x, actor->render.position.z, cellX, cellY);
|
|
|
|
int skillId = 0;
|
|
int skillLevel = 0;
|
|
if (property == 13) {
|
|
skillId = static_cast<int>(lua_tonumber(state, 3));
|
|
skillLevel = static_cast<int>(lua_tonumber(state, 4));
|
|
}
|
|
|
|
std::uint32_t homunAid = *reinterpret_cast<const std::uint32_t*>(&g_session.spAndHomunculusStats[8]);
|
|
if (actor->render.accountId != g_session.m_aid && !g_session.IsCompanionAid(actor->render.accountId)) {
|
|
CGameActor* targetActor = static_cast<CGameActor*>(static_cast<CGameMode*>(g_modeMgr.GetGameMode())->scene->GetGameActorByAID(homunAid));
|
|
if (targetActor) {
|
|
int targetX, targetY;
|
|
static_cast<CGameMode*>(g_modeMgr.GetGameMode())->WorldCell(targetActor->render.position.x, targetActor->render.position.z, targetX, targetY);
|
|
|
|
int range = 0;
|
|
if (skillId != 0) {
|
|
range = static_cast<CGameMode*>(g_modeMgr.GetGameMode())->GetSkillAttackRange(skillId, skillLevel);
|
|
}
|
|
|
|
int clamped = ClampTargetAttackRange(homunAid, range);
|
|
if (clamped > 0) {
|
|
const float dx = static_cast<float>(targetX - cellX);
|
|
const float dy = static_cast<float>(cellY - targetY);
|
|
const float angle = std::acos((1.0f / SquareRoot(dy * dy + dx * dx)) * dx);
|
|
cellX = static_cast<int>(static_cast<float>(cellX) + std::cos(angle) * static_cast<float>(clamped));
|
|
cellY = static_cast<int>(static_cast<float>(cellY) + -std::sin(angle) * static_cast<float>(clamped));
|
|
|
|
if (!static_cast<CGameMode*>(g_modeMgr.GetGameMode())->IsValidCell(cellX, cellY)) {
|
|
if (!static_cast<CGameMode*>(g_modeMgr.GetGameMode())->GetClosestValidCell(&cellX, &cellY)) {
|
|
cellX = targetX;
|
|
cellY = targetY;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
lua_pushnumber(state, cellX);
|
|
lua_pushnumber(state, cellY);
|
|
return 2;
|
|
}
|
|
|
|
lua_pushnumber(state, -1.0);
|
|
lua_pushnumber(state, -1.0);
|
|
return 2;
|
|
|
|
case 2:
|
|
return 1;
|
|
|
|
case V_MOTION:
|
|
if (!actor) {
|
|
result = -1.0;
|
|
} else {
|
|
result = static_cast<double>(actor->render.state);
|
|
}
|
|
break;
|
|
|
|
case V_ATTACKRANGE: {
|
|
int range = *reinterpret_cast<const int*>(&g_session.companionTargetState[4]);
|
|
if (!actor || range == 0) {
|
|
result = -1.0;
|
|
} else {
|
|
result = static_cast<double>(range);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case V_TARGET:
|
|
if (!actor) {
|
|
result = -1.0;
|
|
} else {
|
|
result = static_cast<double>(actor->hitTargetAid);
|
|
}
|
|
break;
|
|
|
|
case V_SKILLATTACKRANGE:
|
|
case 14: {
|
|
std::uint32_t skillId = static_cast<std::uint32_t>(lua_tonumber(state, 3));
|
|
CSkillInfo skill = g_session.LookupHomunSkill(skillId);
|
|
if (!skill.available) {
|
|
result = 1.0;
|
|
} else {
|
|
int range = skill.range;
|
|
if (property == 14) {
|
|
int level = static_cast<int>(lua_tonumber(state, 4));
|
|
range = static_cast<CGameMode*>(g_modeMgr.GetGameMode())->GetSkillAttackRange(skillId, level);
|
|
}
|
|
std::uint32_t homunAid = *reinterpret_cast<const std::uint32_t*>(&g_session.spAndHomunculusStats[8]);
|
|
result = static_cast<double>(ClampTargetAttackRange(homunAid, range));
|
|
}
|
|
lua_pushnumber(state, result);
|
|
return 1;
|
|
}
|
|
|
|
case V_HOMUNTYPE:
|
|
if (!actor) {
|
|
result = -1.0;
|
|
} else {
|
|
result = static_cast<double>(actor->GetEffectiveJob(-1) % 6000);
|
|
}
|
|
break;
|
|
|
|
case V_HP:
|
|
if (aid == g_session.m_aid) {
|
|
result = static_cast<double>(g_session.hp);
|
|
} else if (!g_session.IsHomunAid(aid)) {
|
|
result = -1.0;
|
|
} else {
|
|
result = static_cast<double>(g_session.m_homunHp);
|
|
}
|
|
break;
|
|
|
|
case V_SP:
|
|
if (aid == g_session.m_aid) {
|
|
result = static_cast<double>(*reinterpret_cast<const int*>(&g_session.spAndHomunculusStats[0]));
|
|
} else if (!g_session.IsHomunAid(aid)) {
|
|
result = -1.0;
|
|
} else {
|
|
result = static_cast<double>(g_session.m_homunSp);
|
|
}
|
|
break;
|
|
|
|
case V_MAXHP:
|
|
if (aid == g_session.m_aid) {
|
|
result = static_cast<double>(g_session.maxHp);
|
|
} else if (!g_session.IsHomunAid(aid)) {
|
|
result = -1.0;
|
|
} else {
|
|
result = static_cast<double>(*reinterpret_cast<const int*>(&g_session.homunMaxHp[0]));
|
|
}
|
|
break;
|
|
|
|
case V_MAXSP:
|
|
if (aid == g_session.m_aid) {
|
|
result = static_cast<double>(*reinterpret_cast<const int*>(&g_session.spAndHomunculusStats[4]));
|
|
} else if (!g_session.IsHomunAid(aid)) {
|
|
result = -1.0;
|
|
} else {
|
|
result = static_cast<double>(g_session.homunMaxSp);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return 0;
|
|
}
|
|
|
|
lua_pushnumber(state, result);
|
|
return 1;
|
|
}
|
|
|
|
// OFFSET: 0x00D9F8E0
|
|
// FUNCTION: fn_22342
|
|
int AiMercenaryGetV(lua_State* state) {
|
|
CGameMode* mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode());
|
|
int property = static_cast<int>(lua_tonumber(state, 1));
|
|
std::uint32_t aid = static_cast<std::uint32_t>(lua_tonumber(state, 2));
|
|
|
|
CGameActor* actor = nullptr;
|
|
if (aid == g_session.m_aid) {
|
|
actor = mode->scene->player;
|
|
} else {
|
|
actor = static_cast<CGameActor*>(mode->scene->GetGameActorByAID(aid));
|
|
}
|
|
|
|
double result = 0.0;
|
|
switch (property) {
|
|
case V_OWNER:
|
|
result = static_cast<double>(g_session.m_aid);
|
|
break;
|
|
|
|
case V_POSITION:
|
|
case 13:
|
|
if (actor) {
|
|
if (aid != g_session.m_aid) {
|
|
if (StateFlag06(actor->GetStateFlags()) || StateFlag01(actor->GetStateFlags()) || StateFlag02(actor->GetStateFlags())) {
|
|
lua_pushnumber(state, -1.0);
|
|
lua_pushnumber(state, -1.0);
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
int cellX, cellY;
|
|
mode->WorldCell(actor->render.position.x, actor->render.position.z, cellX, cellY);
|
|
|
|
int skillId = 0;
|
|
int skillLevel = 0;
|
|
if (property == 13) {
|
|
skillId = static_cast<int>(lua_tonumber(state, 3));
|
|
skillLevel = static_cast<int>(lua_tonumber(state, 4));
|
|
}
|
|
|
|
std::uint32_t mercAid = *reinterpret_cast<const std::uint32_t*>(&g_session.companionTargetState[8]);
|
|
if (actor->render.accountId != g_session.m_aid && !g_session.IsCompanionAid(actor->render.accountId)) {
|
|
CGameActor* targetActor = static_cast<CGameActor*>(static_cast<CGameMode*>(g_modeMgr.GetGameMode())->scene->GetGameActorByAID(mercAid));
|
|
if (targetActor) {
|
|
int targetX, targetY;
|
|
static_cast<CGameMode*>(g_modeMgr.GetGameMode())->WorldCell(targetActor->render.position.x, targetActor->render.position.z, targetX, targetY);
|
|
|
|
int range = 0;
|
|
if (skillId != 0) {
|
|
range = static_cast<CGameMode*>(g_modeMgr.GetGameMode())->GetSkillAttackRange(skillId, skillLevel);
|
|
}
|
|
|
|
int clamped = ClampTargetAttackRange(*reinterpret_cast<const std::uint32_t*>(&g_session.spAndHomunculusStats[8]), range);
|
|
if (clamped > 0) {
|
|
const float dx = static_cast<float>(targetX - cellX);
|
|
const float dy = static_cast<float>(cellY - targetY);
|
|
const float dist = SquareRoot(dy * dy + dx * dx);
|
|
const float angle = std::acos((1.0f / dist) * dx);
|
|
cellX = static_cast<int>(static_cast<float>(cellX) + std::cos(angle) * static_cast<float>(clamped));
|
|
cellY = static_cast<int>(static_cast<float>(cellY) + -std::sin(angle) * static_cast<float>(clamped));
|
|
|
|
if (!static_cast<CGameMode*>(g_modeMgr.GetGameMode())->IsValidCell(cellX, cellY)) {
|
|
if (!static_cast<CGameMode*>(g_modeMgr.GetGameMode())->GetClosestValidCell(&cellX, &cellY)) {
|
|
cellX = targetX;
|
|
cellY = targetY;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
lua_pushnumber(state, cellX);
|
|
lua_pushnumber(state, cellY);
|
|
return 2;
|
|
}
|
|
|
|
lua_pushnumber(state, -1.0);
|
|
lua_pushnumber(state, -1.0);
|
|
return 2;
|
|
|
|
case 2:
|
|
return 1;
|
|
|
|
case V_MOTION:
|
|
if (!actor) {
|
|
result = -1.0;
|
|
} else {
|
|
result = static_cast<double>(actor->render.state);
|
|
}
|
|
break;
|
|
|
|
case V_ATTACKRANGE: {
|
|
int range = *reinterpret_cast<const int*>(&g_session.mercenaryAttackRange[0]);
|
|
if (!actor || range == 0) {
|
|
result = -1.0;
|
|
} else {
|
|
result = static_cast<double>(range);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case V_TARGET:
|
|
if (!actor || actor->render.state == 3) {
|
|
result = -1.0;
|
|
} else {
|
|
result = static_cast<double>(actor->hitTargetAid);
|
|
}
|
|
break;
|
|
|
|
case V_SKILLATTACKRANGE:
|
|
case 14: {
|
|
std::uint32_t skillId = static_cast<std::uint32_t>(lua_tonumber(state, 3));
|
|
CSkillInfo skill = g_session.LookupMercSkill(skillId);
|
|
if (!skill.available) {
|
|
result = 1.0;
|
|
} else {
|
|
int range = skill.range;
|
|
if (property == 14) {
|
|
int level = static_cast<int>(lua_tonumber(state, 4));
|
|
range = static_cast<CGameMode*>(g_modeMgr.GetGameMode())->GetSkillAttackRange(skillId, level);
|
|
}
|
|
std::uint32_t mercAid = *reinterpret_cast<const std::uint32_t*>(&g_session.companionTargetState[8]);
|
|
result = static_cast<double>(ClampTargetAttackRange(mercAid, range));
|
|
}
|
|
lua_pushnumber(state, result);
|
|
return 1;
|
|
}
|
|
|
|
case V_HP:
|
|
if (aid == g_session.m_aid) {
|
|
result = static_cast<double>(g_session.hp);
|
|
} else if (!g_session.IsMercenaryAid(aid)) {
|
|
result = -1.0;
|
|
} else {
|
|
result = static_cast<double>(g_session.m_mercenaryHp);
|
|
}
|
|
break;
|
|
|
|
case V_SP:
|
|
if (aid == g_session.m_aid) {
|
|
result = static_cast<double>(*reinterpret_cast<const int*>(&g_session.spAndHomunculusStats[0]));
|
|
} else if (!g_session.IsMercenaryAid(aid)) {
|
|
result = -1.0;
|
|
} else {
|
|
result = static_cast<double>(g_session.m_mercenarySp);
|
|
}
|
|
break;
|
|
|
|
case V_MAXHP:
|
|
if (aid == g_session.m_aid) {
|
|
result = static_cast<double>(g_session.maxHp);
|
|
} else if (!g_session.IsMercenaryAid(aid)) {
|
|
result = -1.0;
|
|
} else {
|
|
result = static_cast<double>(g_session.m_mercenaryMaxHp);
|
|
}
|
|
break;
|
|
|
|
case V_MAXSP:
|
|
if (aid == g_session.m_aid) {
|
|
result = static_cast<double>(*reinterpret_cast<const int*>(&g_session.spAndHomunculusStats[4]));
|
|
} else if (!g_session.IsMercenaryAid(aid)) {
|
|
result = -1.0;
|
|
} else {
|
|
result = static_cast<double>(g_session.m_mercenaryMaxSp);
|
|
}
|
|
break;
|
|
|
|
case V_MERTYPE:
|
|
if (!actor) {
|
|
result = -1.0;
|
|
} else {
|
|
if (g_session.IsHirelingJob(actor->GetEffectiveJob(-1))) {
|
|
result = actor->GetEffectiveJob(-1) % 6017 + 1.0;
|
|
} else {
|
|
result = 1.0;
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return 0;
|
|
}
|
|
|
|
lua_pushnumber(state, result);
|
|
return 1;
|
|
}
|
|
|
|
// OFFSET: 0x00DA0630
|
|
// FUNCTION: fn_22348
|
|
int AiTrace(lua_State* state) {
|
|
std::string text = luaL_checkstring(state, 1);
|
|
return 0;
|
|
}
|
|
|
|
// OFFSET: 0x00DA0720
|
|
// FUNCTION: fn_22349
|
|
int AiTraceAI(lua_State* state) {
|
|
if (!g_session.m_traceAi) {
|
|
return 0;
|
|
}
|
|
|
|
const char* text = luaL_checkstring(state, 1);
|
|
if (!text) {
|
|
return 0;
|
|
}
|
|
|
|
// GLOBAL: gl_24844
|
|
static std::string lastTraceMessage;
|
|
if (lastTraceMessage == text) {
|
|
return 0;
|
|
}
|
|
|
|
lastTraceMessage = text;
|
|
std::string line = text;
|
|
line.append("\n", 1);
|
|
OutputDebugStringA(line.c_str());
|
|
|
|
SYSTEMTIME localTime;
|
|
GetLocalTime(&localTime);
|
|
std::uint32_t date = ((localTime.wYear << 8 | static_cast<short>(localTime.wMonth)) << 8) | static_cast<short>(localTime.wDay);
|
|
std::uint32_t time = ((localTime.wHour << 8 | static_cast<short>(localTime.wMinute)) << 8) | static_cast<short>(localTime.wSecond);
|
|
|
|
CFile file;
|
|
char path[256];
|
|
GetCurrentDirectoryA(sizeof(path), path);
|
|
char* data = std::strstr(path, "\\data");
|
|
int size = 0;
|
|
if (data) {
|
|
std::memcpy(path, path, data - path);
|
|
}
|
|
std::strcat(path, "\\TraceAI.txt");
|
|
|
|
char* buffer = const_cast<char*>(text);
|
|
if (file.Open(path, 0, true, false)) {
|
|
size = file.GetSize();
|
|
buffer = new char[size];
|
|
file.Read(buffer, size);
|
|
file.Close();
|
|
}
|
|
|
|
file.Open(path, 0x1001, true, false);
|
|
if (size) {
|
|
file.Write(buffer, size);
|
|
}
|
|
|
|
char stamp[256];
|
|
sprintf(stamp, "%d/%d/%d - %d:%d:%d", date >> 16, (date >> 8) & 0xFF, date & 0xFF, (time >> 16) & 0xFF, (time >> 8) & 0xFF, time & 0xFF);
|
|
file.Write(stamp, std::strlen(stamp));
|
|
file.Write(text, std::strlen(text));
|
|
file.Write("\r\n", 2);
|
|
file.Close();
|
|
if (size) {
|
|
delete[] buffer;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// OFFSET: 0x00DA0C70
|
|
// FUNCTION: fn_22350
|
|
int AiTraceValue(lua_State* state) {
|
|
std::string text = luaL_checkstring(state, 1);
|
|
g_windowMgr.SendNotice(UIM_PUSHINTOCHATHISTORY, reinterpret_cast<std::intptr_t>(text.c_str()), 0xFFFF, 4, 0, 0);
|
|
return 1;
|
|
}
|
|
|
|
// OFFSET: 0x00DA0D90
|
|
// FUNCTION: fn_22351
|
|
void AiSetTableNumber(lua_State* state, int key, int value) {
|
|
lua_pushnumber(state, key);
|
|
lua_pushnumber(state, value);
|
|
lua_settable(state, -3);
|
|
}
|
|
|
|
namespace {
|
|
|
|
struct AiMessage {
|
|
/* 0000 */ int type;
|
|
/* 0004 */ int x;
|
|
/* 0008 */ int y;
|
|
/* 000C */ int level;
|
|
/* 0010 */ int skill;
|
|
/* 0014 */ int target;
|
|
|
|
AiMessage() : type(0), x(0), y(0), level(0), skill(0), target(0) {}
|
|
};
|
|
|
|
static_assert(sizeof(AiMessage) == 24);
|
|
|
|
#pragma pack(push, 1)
|
|
struct MoveToOwnerPacket {
|
|
/* 0000 */ std::int16_t opcode;
|
|
/* 0002 */ std::uint32_t aid;
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
static_assert(sizeof(MoveToOwnerPacket) == 6);
|
|
|
|
#pragma pack(push, 1)
|
|
struct MoveNpcPacket {
|
|
/* 0000 */ std::int16_t opcode;
|
|
/* 0002 */ std::uint32_t aid;
|
|
/* 0006 */ unsigned char dest[3];
|
|
};
|
|
#pragma pack(pop)
|
|
|
|
static_assert(sizeof(MoveNpcPacket) == 9);
|
|
|
|
}
|
|
|
|
// OFFSET: 0x00D9EEF0
|
|
// FUNCTION: fn_22338
|
|
int AiGetMsg(lua_State* state) {
|
|
std::uint32_t aid = static_cast<std::uint32_t>(lua_tonumber(state, 1));
|
|
int index;
|
|
if (g_session.IsHomunAid(aid)) {
|
|
index = 0;
|
|
} else if (g_session.IsMercenaryAid(aid)) {
|
|
index = 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
|
|
CGameActor* actor = static_cast<CGameActor*>(static_cast<CGameMode*>(g_modeMgr.GetGameMode())->scene->GetGameActorByAID(aid));
|
|
if (!actor) {
|
|
return 0;
|
|
}
|
|
|
|
AiMessage message = *reinterpret_cast<const AiMessage*>(actor->GetMsg2AI(index));
|
|
lua_newtable(state);
|
|
lua_pushnumber(state, 1);
|
|
lua_pushnumber(state, message.type);
|
|
lua_settable(state, -3);
|
|
switch (message.type) {
|
|
case MOVE_CMD:
|
|
case ATTACK_AREA_CMD:
|
|
case PATROL_CMD:
|
|
AiSetTableNumber(state, 2, message.x);
|
|
AiSetTableNumber(state, 3, message.y);
|
|
break;
|
|
case ATTACK_OBJECT_CMD:
|
|
AiSetTableNumber(state, 2, message.target);
|
|
break;
|
|
case SKILL_OBJECT_CMD:
|
|
AiSetTableNumber(state, 2, message.level);
|
|
AiSetTableNumber(state, 3, message.skill);
|
|
AiSetTableNumber(state, 4, message.target);
|
|
break;
|
|
case SKILL_AREA_CMD:
|
|
AiSetTableNumber(state, 2, message.level);
|
|
AiSetTableNumber(state, 3, message.skill);
|
|
AiSetTableNumber(state, 4, message.x);
|
|
AiSetTableNumber(state, 5, message.y);
|
|
break;
|
|
}
|
|
|
|
message.type = 0;
|
|
actor->SetMsg2AI(reinterpret_cast<const float*>(&message), index);
|
|
return 1;
|
|
}
|
|
|
|
// OFFSET: 0x00D9F0B0
|
|
// FUNCTION: fn_22339
|
|
int AiGetResMsg(lua_State* state) {
|
|
std::uint32_t aid = static_cast<std::uint32_t>(lua_tonumber(state, 1));
|
|
int index;
|
|
if (g_session.IsHomunAid(aid)) {
|
|
index = 0;
|
|
} else if (g_session.IsMercenaryAid(aid)) {
|
|
index = 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
|
|
CGameActor* actor = static_cast<CGameActor*>(static_cast<CGameMode*>(g_modeMgr.GetGameMode())->scene->GetGameActorByAID(aid));
|
|
if (!actor) {
|
|
return 0;
|
|
}
|
|
|
|
AiMessage message = *reinterpret_cast<const AiMessage*>(actor->GetResMsg2AI(index));
|
|
lua_newtable(state);
|
|
lua_pushnumber(state, 1);
|
|
lua_pushnumber(state, message.type);
|
|
lua_settable(state, -3);
|
|
switch (message.type) {
|
|
case MOVE_CMD:
|
|
case ATTACK_AREA_CMD:
|
|
case PATROL_CMD:
|
|
AiSetTableNumber(state, 2, message.x);
|
|
AiSetTableNumber(state, 3, message.y);
|
|
break;
|
|
case ATTACK_OBJECT_CMD:
|
|
AiSetTableNumber(state, 2, message.target);
|
|
break;
|
|
case SKILL_OBJECT_CMD:
|
|
AiSetTableNumber(state, 2, message.level);
|
|
AiSetTableNumber(state, 3, message.skill);
|
|
AiSetTableNumber(state, 4, message.target);
|
|
break;
|
|
case SKILL_AREA_CMD:
|
|
AiSetTableNumber(state, 2, message.level);
|
|
AiSetTableNumber(state, 3, message.skill);
|
|
AiSetTableNumber(state, 4, message.x);
|
|
AiSetTableNumber(state, 5, message.y);
|
|
break;
|
|
}
|
|
|
|
message.type = 0;
|
|
actor->SetResMsg2AI(reinterpret_cast<const float*>(&message), index);
|
|
return 1;
|
|
}
|
|
|
|
// OFFSET: 0x00D9FF50
|
|
// FUNCTION: fn_22343
|
|
int AiIsMonster(lua_State* state) {
|
|
std::uint32_t aid = static_cast<std::uint32_t>(lua_tonumber(state, 1));
|
|
CGameMode* mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode());
|
|
CGameActor* actor = static_cast<CGameActor*>(mode->scene->GetGameActorByAID(aid));
|
|
double result = 0.0;
|
|
if (actor) {
|
|
int job = actor->GetEffectiveJob(-1);
|
|
if (((job > 1000 && job < 3999) || static_cast<unsigned>(job - 20021) <= 11978) && actor->objectType != 7) {
|
|
switch (actor->objectType) {
|
|
case 9:
|
|
case 10:
|
|
case 13:
|
|
case 14:
|
|
result = 0.0;
|
|
break;
|
|
default:
|
|
if (StateFlag06(actor->GetStateFlags()) || StateFlag01(actor->GetStateFlags()) || StateFlag02(actor->GetStateFlags())) {
|
|
result = 0.0;
|
|
} else {
|
|
result = 1.0;
|
|
}
|
|
break;
|
|
}
|
|
} else if (g_session.IsPlayerJobId(job)) {
|
|
CWorld* world = mode->scene;
|
|
bool ally;
|
|
if (world->isPKZone || world->isEventPVPMode) {
|
|
ally = g_session.IsPartyMember(actor->render.accountId, true);
|
|
} else if (world->isSiegeMode) {
|
|
ally = g_session.IsLocalPlayerAid(actor->GetGdid()) != 0;
|
|
} else {
|
|
ally = true;
|
|
}
|
|
if (!ally) {
|
|
if (StateFlag06(actor->GetStateFlags()) || StateFlag01(actor->GetStateFlags()) || StateFlag02(actor->GetStateFlags())) {
|
|
result = 0.0;
|
|
} else {
|
|
result = 1.0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
lua_pushnumber(state, result);
|
|
return 1;
|
|
}
|
|
|
|
// OFFSET: 0x00DA00D0
|
|
// FUNCTION: fn_22344
|
|
int AiMove(lua_State* state) {
|
|
std::uint32_t aid = static_cast<std::uint32_t>(lua_tonumber(state, 1));
|
|
int x = static_cast<int>(lua_tonumber(state, 2));
|
|
int y = static_cast<int>(lua_tonumber(state, 3));
|
|
|
|
if (!g_session.IsHomunAid(aid) && !g_session.IsMercenaryAid(aid)) {
|
|
return 0;
|
|
}
|
|
|
|
CGameMode* mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode());
|
|
CGameActor* actor = static_cast<CGameActor*>(mode->scene->GetGameActorByAID(aid));
|
|
if (!actor) {
|
|
return 0;
|
|
}
|
|
|
|
if (!mode->IsValidCell(x, y)) {
|
|
if (!mode->GetClosestValidCell(&x, &y)) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int actorX = 0, actorY = 0;
|
|
mode->WorldCell(actor->render.position.x, actor->render.position.z, actorX, actorY);
|
|
|
|
if (std::abs(x - actorX) + std::abs(y - actorY) < 25) {
|
|
#pragma pack(push, 1)
|
|
struct MoveNpcPacket {
|
|
/* 0000 */ std::int16_t opcode;
|
|
/* 0002 */ std::uint32_t aid;
|
|
/* 0006 */ unsigned char dest[3];
|
|
};
|
|
#pragma pack(pop)
|
|
static_assert(sizeof(MoveNpcPacket) == 9);
|
|
|
|
MoveNpcPacket packet;
|
|
packet.opcode = ID_CZ_REQUEST_MOVENPC;
|
|
packet.aid = aid;
|
|
packet.dest[0] = static_cast<unsigned char>(x >> 2);
|
|
packet.dest[1] = static_cast<unsigned char>(((y >> 4) & 0x3F) | (x << 6));
|
|
packet.dest[2] = static_cast<unsigned char>(y << 4);
|
|
|
|
GetRagConnection().Send(reinterpret_cast<PacketLengths&>(GetRagConnection()).FixedLength(packet.opcode), &packet);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// OFFSET: 0x00DA0260
|
|
// FUNCTION: fn_22345
|
|
int AiMoveToOwner(lua_State* state) {
|
|
std::uint32_t aid = static_cast<std::uint32_t>(lua_tonumber(state, 1));
|
|
if (!g_session.IsHomunAid(aid) && !g_session.IsMercenaryAid(aid)) {
|
|
return 0;
|
|
}
|
|
|
|
if (static_cast<CGameMode*>(g_modeMgr.GetGameMode())->scene->GetGameActorByAID(aid)) {
|
|
MoveToOwnerPacket packet;
|
|
packet.opcode = ID_CZ_REQUEST_MOVETOOWNER;
|
|
packet.aid = aid;
|
|
GetRagConnection().Send(reinterpret_cast<PacketLengths&>(GetRagConnection()).FixedLength(packet.opcode), &packet);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// OFFSET: 0x00DA0300
|
|
// FUNCTION: fn_22346
|
|
int AiSkillGround(lua_State* state) {
|
|
std::uint32_t aid = static_cast<std::uint32_t>(lua_tonumber(state, 1));
|
|
int skillArgs[4];
|
|
skillArgs[0] = static_cast<int>(lua_tonumber(state, 3));
|
|
skillArgs[1] = static_cast<int>(lua_tonumber(state, 4));
|
|
skillArgs[2] = static_cast<int>(lua_tonumber(state, 5));
|
|
skillArgs[3] = static_cast<int>(lua_tonumber(state, 2));
|
|
|
|
if (!g_session.IsHomunAid(aid) && !g_session.IsMercenaryAid(aid)) {
|
|
return 0;
|
|
}
|
|
if (!g_session.IsHomunculusSkill(static_cast<unsigned>(skillArgs[0])) && !g_session.IsMercenarySkill(static_cast<unsigned>(skillArgs[0]))) {
|
|
return 0;
|
|
}
|
|
|
|
CGameMode* mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode());
|
|
CGameActor* actor = static_cast<CGameActor*>(mode->scene->GetGameActorByAID(aid));
|
|
if (actor->render.state == 1 || actor->render.state == 0 || actor->render.state == 4) {
|
|
mode->SendMsg(MM_USE_SKILL_TOGROUND, reinterpret_cast<int>(skillArgs), 0, 0, 0);
|
|
}
|
|
mode->SendMsg(MM_SETLOCKONMOUSE, 0, 0, 0, 0);
|
|
return 0;
|
|
}
|
|
|
|
// OFFSET: 0x00DA0420
|
|
// FUNCTION: fn_22347
|
|
int AiSkillObject(lua_State* state) {
|
|
std::uint32_t aid = static_cast<std::uint32_t>(lua_tonumber(state, 1));
|
|
unsigned int level = static_cast<unsigned int>(lua_tonumber(state, 2));
|
|
std::uint32_t skillId = static_cast<std::uint32_t>(lua_tonumber(state, 3));
|
|
std::uint32_t target = static_cast<std::uint32_t>(lua_tonumber(state, 4));
|
|
|
|
CSkillInfo skill = g_session.LookupSkill(skillId);
|
|
if (!skill.available) {
|
|
return 0;
|
|
}
|
|
|
|
if (!g_session.IsHomunAid(aid) && !g_session.IsMercenaryAid(aid)) {
|
|
return 0;
|
|
}
|
|
|
|
if (!g_session.IsHomunculusSkill(skillId) && !g_session.IsMercenarySkill(skillId)) {
|
|
return 0;
|
|
}
|
|
|
|
CGameMode* mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode());
|
|
CGameActor* targetActor = nullptr;
|
|
if (target == g_session.m_aid) {
|
|
targetActor = mode->scene->player;
|
|
} else {
|
|
targetActor = static_cast<CGameActor*>(mode->scene->GetGameActorByAID(target));
|
|
if (targetActor) {
|
|
if (StateFlag06(targetActor->GetStateFlags()) || StateFlag01(targetActor->GetStateFlags()) || StateFlag02(targetActor->GetStateFlags())) {
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
CGameActor* actor = static_cast<CGameActor*>(mode->scene->GetGameActorByAID(aid));
|
|
if (targetActor && (actor->render.state == 1 || actor->render.state == 0 || actor->render.state == 4)) {
|
|
mode->SendMsg(MM_USE_SKILL, skillId, target, level, 0);
|
|
}
|
|
mode->SendMsg(MM_SETLOCKONMOUSE, 0, 0, 0, 0);
|
|
|
|
if (IsSupportSkill(skillId)) {
|
|
lua_pushnumber(state, 1.0);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|