Anonymous 发表于 2021-11-20 16:52:48

单元的cnpack很卡,求大佬指点迷津

排除了代码过多的原因,其他同样的行数的单元就很好,就这个很卡,恳请大佬帮忙指点指点,谢谢

====================================================================================================
unit ObjPlayer;

interface
uses
Windows, Classes, SysUtils, UInt64Lib, StrUtils, Grobal2, EDcode, Envir, ObjBase, ObjPetBooth,GameDB_SQL, WinlicenseSDK,MapPoint,
VersionManage, ObjPlayer_0_Base, PacketManageUnit, DateUtils;

type
//玩家对象
TPlayObject = class(TBasePlayObject)
    m_DearHuman: TPlayObject;
    m_MasterHuman: TPlayObject;
    m_GetWhisperHuman: TPlayObject;
   //ai参数

   m_boAI : Boolean;
   m_RunPos: TRunPos;
   m_boAIStart: Boolean;
   m_ManagedEnvir: TEnvirnoment; //挂机地图
    m_nPostion: Integer;
   m_PointManager: TPointManager;
    m_Path: TPath;

      start_x,start_y:Integer;
      m_nMoveFailCount:Integer;
      m_nround:Integer ;

      //new转移
       m_GuildTowerInfo: TGuildTowerInfo;
   m_dwStopMagic: array of Integer;                                                      //禁止人物释放技能
    m_btBuffArr: array of Byte;                                                   //Buff效果持续时间标记
    m_dwBuffArrTick: array of LongWord;
    m_ErgumCount: TErgumCount;
    m_DealCreat: TBaseObject;                                                                     //交易的主动方
    m_boSuitSub: array of Boolean;                                                          //套装属性
      m_ExemptHurt: TExemptHurt;
   m_ReduceSkillLevel: array of byte;                                                       //41个魂佑技能等级
    m_ReduceSkillPoint: array of byte;                                                       //41个魂佑技能点数灵兽装备增加的


private
    procedure ClientAddFriend(FriendName: string);
    procedure ClientDelFriend(FriendName: string);
    procedure ClientRespAddFriend(nRespCode: word; FriendName: string);
    procedure AddToFriendList(FriendName: string);
    procedure DelFromFriendList(FriendName: string);
    function ClientDropGold(nGold: Integer): Boolean;
    procedure ClientQueryBagItems();
    procedure ClientSendBagOrder();
    function ClientRide: Boolean;
    procedure ClearFree();
    function GetAmbitStatus(): Integer; override;
    function GetMagicExStatus(): byte; override;
    function GetFeature(BaseObject: TBaseObject): Integer; override;
    function GetFeatureEx(): byte; override;
    procedure StruckDamage(nDamage: Integer); override;
public
    procedure KillMonsterFunc();
    procedure KillPlayerFunc();
    procedure CheckProwlMagic();                                                                  //检查是否有潜行
    procedure SendPetInfo(State: byte);
    procedure ClientRideOff;
    procedure SendMeOnlineState(State: byte; b: ShortInt = -1);
    procedure MakeWeaponUnlock();
    function PetStoreAddExp(nPetItemIdx, nExp, nDay: Integer; boEat: Boolean): Boolean; override;
    procedure SendTigerItem();
    procedure CheckStoreBagDupeItem;
private
    m_sQueryName: string;
    function CheckEatItems(StdItem: pTStdItem): Boolean;
    procedure ClientQueryUserSet(ProcessMsg: pTProcessMessage);
    function IsDownPetItem(nMakeIndex: Integer): Boolean;
    function ClientDropItem(sItemName: string; nItemIdx: Integer): Boolean;
    procedure ClientQueryUserState(BaseObject: TBaseObject; nX, nY: Integer);
    function PetPickUpItem(nX, nY: Integer): Boolean;
    procedure ClientOpenDoor(nX, nY: Integer);
    function ClientTakeOnItems(btWhere: byte; nItemIdx: Integer; sItemName: string; boFlag: Boolean): Boolean;
    procedure ClientTakeOffItems(btWhere: byte; nItemIdx: Integer; sItemName: string);
    procedure ClientUseItems(nItemIdx: Integer; sItemName: string; nPackIdx: Integer);
    function UseStdmodeFunItem(StdItem: pTStdItem; boNew: Boolean = False): Boolean;
    procedure RefMyStatus;
    function ClientGetButchItem(BaseObject: TBaseObject; nX, nY: Integer; btDir: byte; var dwDelayTime: LongWord): Boolean;
    procedure ClientChangeMagicKey(nSkillIdx, nKey: Integer);
    procedure ClientMerchantDlgSelect(nParam1: Integer; sMsg: string; nType: Integer = 0);
    procedure ClientNamedStore(nParam1: Integer; nMakeIndex: Integer);
    procedure ClientSplitItem(nMakeIndex: Integer; nCount: Integer; boScript: Boolean);
    procedure RecordHomeXY(nParam1: Integer; nMapIdx: Integer); overload;
    procedure RecordHomeXY(nParam1: Integer; sMsg: string); overload;
    procedure ClientPerfectStoreMoveHome(nParam1: Integer; nMapIdx: Integer);
    procedure ClientQuerySlaverState;
    procedure ClientInput(nParam1: Integer; Data: string);
    procedure ClientMerchantQuerySellPrice(nParam1, nMakeIndex: Integer; sMsg: string);
    procedure ClientUserSellItem(nParam1, nMakeIndex: Integer; sMsg: string);
    procedure ClientUserBuyItem(nIdent, nParam1, nInt, nZz: Integer; sMsg: string; nType: Integer = 0);
    procedure ClientQueryRepairCost(nParam1, nInt: Integer; nRepairType: Integer; sMsg: string);
    procedure ClientRepairItem(nParam1, nInt: Integer; nRepairType: Integer; sMsg: string);
    function FindViewHum(PlayObject: TObject): TPlayObject;
    procedure ClientGropuClose();
    procedure ClientCreateGroup(sHumName: string);
    procedure ClientAddGroupMember(sHumName: string);
    procedure ClientDelGroupMember(sHumName: string);
    procedure ClientDealTry(sHumName: string);
    procedure ClientAddDealItem(nItemIdx: Integer; sItemName: string);
    procedure ClientDelDealItem(nItemIdx: Integer; sItemName: string);
    procedure ClientCancelDeal();
    procedure ClientChangeDealGold(nGold, nGameGold: Integer);
    procedure ClientDealEnd();
    procedure ClientStorageItem(NPC: TObject; nItemIdx: Integer; boFast:
      Boolean; sMsg: string);
    procedure ClientTakeBackStorageItem(NPC: TObject; nItemIdx: Integer; boFast:
      Boolean; sMsg: string);
    procedure ClientGetMinMap();
    procedure ClientMakeDrugItem(NPC: TObject; nItemName: string);
    procedure ClientOpenGuildDlg();
    procedure ClientGuildHome();
    procedure ClientGuildAddMember(sHumName: string);
    procedure ClientGuildDelMember(sHumName: string);
    procedure ClientGuildUpdateNotice(sNotict: string);
    procedure ClientGuildUpdateRankInfo(sRankInfo: string);
    procedure ClientGuildAlly();
    procedure ClientGuildBreakAlly(sGuildName: string);
    procedure ClientAdjustBonus(nPoint: Integer; sMsg: string);
    function ClientChangeDir(wIdent: word; nX, nY, nDir: Integer; var
      dwDelayTime: LongWord): Boolean;
    function ClientWalkXY(wIdent: word; nX, nY: Integer; boLateDelivery:
      Boolean; var dwDelayTime: LongWord): Boolean;
    //    function ClientHorseRunXY(wIdent: word; nX, nY: Integer; boLateDelivery:
    //      Boolean; var dwDelayTime: LongWord): Boolean;
    function ClientRunXY(wIdent: word; nX, nY: Integer; nFlag: Integer; var dwDelayTime: LongWord): Boolean;
    function ClientHitXY(wIdent: word; nX, nY, nDir, nMagicID: Integer;
      boLateDelivery: Boolean; var dwDelayTime: LongWord): Boolean;
    function ClientSitDownHit(nX, nY, nDir: Integer; var dwDelayTime: LongWord): Boolean;
    function ClientSpellXY(wIdent: word; nKey: Integer; nTargetX, nTargetY:
      Integer; TargeTBaseObject: TBaseObject; boLateDelivery: Boolean; var dwDelayTime: LongWord): Boolean;
    procedure ClientSetBagOrder(nItemCount: Integer; sData: string);
    procedure ClientCatchEvil(EvilObject: TBaseObject; nMakeIndex: Integer);
    procedure ClientAddEvilToItem(nWhere: word; nMakeIndex, BottleIndex: Integer);
    procedure ClientAddAntiEvilPower(nWhere: word; nMakeIndex, nAntiEvilItem: Integer);
    function GetEvilRecByMakeIndex(nItemMakeIndex: Integer): pTEvil;
    procedure DelEvilRec(nItemMakeIndex: Integer; DisMem: Boolean = True);
    procedure ClientRequest(wIdent: word; nOp, nOpCode: Integer);
    procedure ClientEvoluTion(wParam: word; nMainMakeIndex, nAuxMakeIndex, nMakeIndex: Integer);
    procedure ClientPetMakeBaby(nMaleMakeIndex, nFemaleMakeIndex: Integer);
    procedure ClientUPGradeTreasureBox(nCount: Integer; sBuf: string);
    procedure ClientEnlargeTreasureBox();
    procedure ClientInjectPowerToTreasureBox(nPoint: Integer);
    procedure ClientActivationTreasureBox();
    procedure ClientTakeItemToTreasureBox(nItemID: Integer);
    procedure ClientTakeItemOutTreasureBox(nItemID: Integer);
    function MagDoBatfly(UserMagic: pTUserMagic; nTargetX, nTargetY: Integer): Boolean;             //化身蝙蝠、移形换影、遁地
    procedure SendPetBagItems;
    procedure HorseHide;
    procedure PetHide(nMakeIndex: Integer);
    procedure SendDelDealItem(UserItem: pTUserItem);
    procedure SendAddDealItem(UserItem: pTUserItem);
    procedure OpenDealDlg(BaseObject: TBaseObject);
    function EatItems(StdItem: pTStdItem): Boolean;
    function EatUseItems(nShape: Integer): Boolean;
    function DayBright(): byte;
    procedure BaseObjectMove(sMAP, sX, sY: string);
    function RepairWeapon(): Boolean;
    function SuperRepairWeapon(): Boolean;
    function SuperRepairUseItems(): Boolean;
    function WinLottery(): Boolean;
    procedure ChangeServerMakeSlave(SalveInfo: pTSlaveInfo);
    function WeaptonMakeLuck(): Boolean;
    function PileStones(nX, nY: Integer): Boolean;
    procedure MakeMine();
    function GetRangeHumanCount(): Integer;
    procedure GetStartPoint();
    procedure MobPlace(sX, sY, sMonName, sCount: string);
    function PetDoShopCanSellCount: Integer;                                                      //计算豹子能摆摊几个物品
    procedure LogonTimcCost;
    procedure QuerySubAbility;
    procedure SendNotice();
    procedure SendLogon();
    function CheckUserItemTimeOut(UserItem: pTUserItem; StdItem: pTStdItem): Boolean;
    function IsGotoLabel(sMapName: string; nX, nY, nRange, nQuestFalgStatus: Integer;
      boQuestFalgStatus: Boolean; sItemName1, sItemName2: string; boNeedGroup: Boolean; nRandomCount: Integer): Boolean;
    procedure StartMapEventOfDropItem(sItemName: string);
    procedure StartMapEventOfPickUpItem(sItemName: string);
    procedure StartMapEventOfMine();
    procedure StartMapEventOfWalk();
    procedure StartMapEventOfRun();
    procedure StartMapEventOfButch();
    {客户端操作}
    function CheckCanOperate(Action: TClientAction; nKey: Integer = 0): Boolean;
    procedure ClientQueryUserName(Target: TBaseObject; X, Y: Integer);
    procedure ClientRequestPetDoShop();                                                             //请求摆摊
    procedure ClientDoShop(shopItemCount: word; sMsg: string);
    procedure ClientPetDoShop(nPet: Integer; shopItemCount: word; sMsg: string);
    procedure ClientGetbackPetShopItem();
    procedure ClientGetbackPetMoney();
    procedure ClientUpdatePetShop(nPet: Integer; nOpCode: Integer; sMsg: string);
    procedure ClientPetStopDoShop();                                                                //宠物收摊
    procedure ClientPersonalSet(Parm1, Parm2, Parm3: Word; sMsg: string);
    procedure ClientStorageItemToPetBag(nItemIdx: Integer);
    procedure ClientOpenHuanjing(nItemIdx: Integer; nOpCode: Integer; nCount: Integer);
    procedure ClientEvilOp(nOpCode: Integer; nEvilMonID: Integer; nMakeIndex: Integer);
    procedure ClientErnie(nOpCode: word);
    procedure ClientTakebackPetItem(nItemIdx: Integer);
    function ClientOpPneumaBagItem(sData: string): Boolean;
    function ClientOpPneumaGold(sData: string): Boolean;
    procedure ClientFelementOrderFlag(nMakeIndex, nMon: Integer);
    procedure ClientReCallGuarder(nMakeIndex, nX, nY: Integer);
    procedure ClientCreateSoul(nParm1, nParm2, nParm3: Integer);
    procedure ClientPhoenixSearch(nPetItem, nParm2: Integer);
    procedure ClientAllotGuildGold(sName: string; nGold: Integer);
    procedure ClientCtrlMental(wOpCode: word);
    procedure ClientTakeOnTigerItem(nWhere, nMakeIndex: Integer);
    procedure ClientTakeOffTigerItem(nWhere, nMakeIndex: Integer);
    procedure ClientTakeOnInosculatePneumaItem(nWhere, nMakeIndex: Integer);
    procedure ClientTakeOffInosculatePneumaItem(nWhere, nMakeIndex: Integer);
    procedure ClientTakeOnPetSoulItem(nWhere, nMakeIndex: Integer; wIndex: word);
    procedure ClientTakeOffPetSoulItem(nWhere, nMakeIndex: Integer; wIndex: word);
    procedure ClientDECOMPOSE(nParam, nMakeIndex: Integer);
    procedure ClientGEMREMOVE(nWhere, nMakeIndex: Integer);
    procedure ClientYiWangDan(nMakeIndex: Integer; sSkillName: string);
    procedure SendUseitems();
    procedure SendUseMagic();
    procedure SendSaveItemList(nBaseObject: Integer; boFast: Boolean);
    procedure SendDelItemList(ItemList: TStringList);
    procedure SendAdjustBonus();
    procedure SendChangeGuildName();
    procedure ShowMapInfo(sMAP, sX, sY: string);
    procedure ReadAllBook;
    function CheckItemsNeed(StdItem: pTStdItem): Boolean;
    function CheckItemBindUse(UserItem: pTUserItem): Boolean;
    function CheckActionStatus(wIdent: word; var dwDelayTime: LongWord): Boolean;
    procedure RecalcAdjusBonus;
    procedure RecalcAdditionalAbil;
    procedure RecalcAddInosculatePneumaAbil;
    procedure RecalcAddProvisionalAbil;
    procedure RecalcAddPetAbil;
    procedure RecalcPetSoulAbilitys;

    procedure CheckMarry();
    procedure CheckMaster();
    procedure ProcessClientPassword(ProcessMsg: pTProcessMessage);
    function CheckDenyLogon: Boolean;
    procedure ProcessSpiritSuite;
    function HorseRunTo(btDir: byte; boFlag: Boolean): Boolean;
    procedure SendTaskList;
    procedure ClientQueryBaoshi;
    procedure ClientSendBlessMsg(NPC: Integer; MsgFlag: Integer; sMsg: string);
    procedure ClientGemSmelt(nState: Integer; RedBaoshi, BlueBaoshi, GreenBaoshi: Integer; sItems: string);
    procedure ClientGemItems(NPC: Integer; nType: Integer; nItemCount: Integer; nState: Integer; sData: string);
    procedure ClientRefineItems(nType: Integer; nItemIdx, nItemIdx2: Integer; sData: string);
    procedure ClientOriginalStoneSmelt(nItemIdx, nType, nState: Integer; sData: string);
    procedure ClientEntopticSmelt(nState: Integer; sData: string);
    procedure ClientfuseequipItem(nState: Integer; nItemIdx, nItemIdx2: Integer; sData: string);
    procedure ChangePneumaState;
    procedure MakeFlagOwner(nflagType: Integer; ItemIdx: Integer; nX, nY: Integer; sData: string);
    procedure AddFlagComment(nflagType: Integer; NPCID: Integer; nMsgLen: Integer; sMsg: string);
    procedure ClickQueryMsg(NPCID: Integer; btnid: Integer);
    procedure GetTreasureBoxItem(wParam: word; nParam1, nParam2, nParam3: Integer; sMsg: string);
    procedure SendNearbyGuildMemberList();
    procedure ClientAskForGuildOfficial(nRankNo: Integer; sData: string);
    procedure ClientGuildOfficial(nCode, nRankNo: Integer; sChiefName: string);
    procedure SendTreasurePavilion();
    procedure SendNonSuchPavilion(nSerial: Integer);
    procedure ClientCallTiger();
    procedure ClientSetTigerTarget(nMonID, nOp, nX, nY: Integer);
    procedure ClientQueryMapLotusInfo();
    function ClientTakeOnEntopticItems(btWhere: byte; nItemIdx: Integer): Boolean;                  //装备元神内视装备
    function ClientTakeOffEntopticItems(btWhere: byte; nItemIdx: Integer): Boolean;               //取下元神内视装备
    function ClientIllumeHeartPoint(btWhere, btPlace: byte): Boolean;                               //点亮心命点
    procedure SendHeartFatePoint();
    procedure SendEntopticItems();
    procedure ClientQueryGuildClanList();
    procedure ClientClanOperate(nOpCode: Integer; sMsg: string);
    procedure ClientClanReQuery(nOpCode: Integer; sMsg: string);
    procedure MagFieryDragonRun();
    procedure ClientCatapultAttackTarget(nOpCode, nX, nY: Integer);
    procedure ClientQueryPetSoulInfo;                                                               //发送魂佑灵兽信息
    procedure ClientQueryPetSoulItem(nMakeIndex: Integer; wIndex: word);                            //查询魂佑灵兽装备
    procedure ClientMagOfPetBeast(nMakeIndex: Integer);
    procedure ClientCheckVerifyCode(sVerifyCode: string; boOutTime: Boolean = False);
    procedure ClientQueryAbility();
protected
    procedure RecalcAbilitysEx(); override;
public
    m_boInNonSuchPavilion: Boolean;
    procedure CheckPackPetShop();
    procedure ClientClickNPC(NPC: Integer);
    procedure SendMapDescription();
    procedure SendBagItemsPetInfo();
    procedure SendPetAttribute(PlayObject: TPlayObject; btWhere: byte; UserItem: pTUserItem);       //发送灵兽石附加属性
    procedure SendAddPetSoulInfo(nMakeIndex: Integer);
    procedure SendGuildTowerInfo();
    procedure SendGuildTowerRes();
    procedure RecalcTowerAbility();
    procedure SendTigerInfo();
    procedure RecalcTigerLevelAbilitys;
    procedure RecalcTigerAbility();
    procedure TigerDefendMaster(var nDamage: Integer);
    procedure TigerTransferDamage(var nDamage: Integer);
    procedure SlaveTransferDamage(var nDamage: Integer);
    procedure BaoBaoTransferDamage(var nDamage: Integer);                                           //宝宝斗转
    procedure PneumaLogin;
    procedure PetShow(nMakeIndex: Integer);
    function CancelGroup(): Boolean;
    procedure ClientQueryTreasureBoxItems(const boSend: Boolean = True);
    procedure ClientReCallTiger();
    procedure ClientSwitchPneuma();
    procedure ClientInosculatePneuma();
    procedure ClientQueryMentalAbilitys(PlayObject: TPlayObject);
    procedure ClientBuyShopItem(Play: TBaseObject; sItemName: string; nInt: Integer);
    procedure RecalcMentalLevelAbilitys;
    procedure SendWenPeiJH();                                                                     //发送纹佩精华
    procedure ClientAchievementSystem(boWenPei: Boolean = False);                                 //成就系统

    procedure RecalcPerHealthSpell(); override;
    procedure ClientMakeWenPei(btZW, btJW, btDW, btBW: byte);                                       //制做纹佩
    procedure ClientGetWenPeiDemand(nMakeIndex, nCode: Integer);
    procedure ClientTakeWenPei(nMakeIndex, nCode: Integer);                                       //强化 或 拆解 纹佩
    procedure ClientCollectSuits(nCJIdx, nCount: Integer; sData: string);                           //成就之收集套装
    procedure ClientPetEquipUp(nPetItemIdx, nStoreItemIdx: Integer; sData: string);               //升级灵兽装备
    function TrainingPetSkill(const StdItem: pTStdItem): Boolean;                                 //学习灵兽抵抗技能
    procedure RecalcAddSuiteAbil(Idx: Integer; boPercent: Boolean);
public
    constructor Create(); override;
    destructor Destroy; override;
    procedure ClearUp(btFree: Boolean = False); override;
    procedure SendSocket(DefMsg: pTDefaultMessage; sMsg: string); override;
    procedure SendDefMessage(wIdent: word; nRecog: Integer; nParam, nTag, nSeries: word; sMsg: string; boEn: Boolean = False); override;
    procedure SendFiendList(const b: ShortInt = -1);
    procedure SearchViewRange(); override;
    procedure OnEnvirnomentChanged(OldEnvir: TEnvirnoment; boChanged: Boolean = True); override;
    procedure PKDie(PlayObject: TPlayObject);
    procedure CreatePneumaEnd(btFlag: Integer; sNewName: string; nSex, btHumKind: byte);
    procedure GameTimeChanged();
    procedure RunNotice();
    //AI动作
    function gotopoint(smapName: string;nx,ny:integer): Boolean;
    function WalkToNext(nX, nY: Integer): Boolean;
    function RunToNext(nX, nY: Integer): Boolean;
      procedure Stop;
function GetBagItemCount(sItemName: string): Integer;
function Think(): Boolean;
procedure GotoTargetXYRange();
function GotoNextOne(nX, nY: Integer; boRun: Boolean): Boolean;
    function GetMagicSpell(UserMagic: pTUserMagic): Integer;
procedure Attack(TargeTBaseObject: TBaseObject; nDir: Integer); overload;
function actAttackTarget(): Boolean;
procedure GotoTargetXY;
procedure SetTargetXY(nX, nY: Integer); virtual;                                                //FFF0
function CheckTargetXYCount(nX, nY, nRange: Integer): Integer;
function CheckTargetXYCountOfDirection(nX, nY, nDir, nRange: Integer): Integer;
function AutoAvoid(): Boolean;
function canatackTarget(BaseObject:TBaseObject): Boolean;
procedure UpdatenoatcktActors(BaseObject: TBaseObject);
   procedure Wondering();
    procedure SearchTarget;
    function GetMyStatus(): Integer;
    procedure MoveToHome();
    procedure MoveToHomeRandom();
    procedure SendAddMagic(UserMagic: pTUserMagic);
    procedure SendDelMagic(UserMagic: pTUserMagic);
    procedure SendAddItem(UserItem: pTUserItem); override;
    procedure SendAddPetItem(UserItem: pTUserItem);
    procedure SendDelItems(UserItem: pTUserItem); override;
    procedure Whisper(whostr, saystr: string; nType: Integer = 1);
    function ClientPickUpItem(nX, nY, nType: Integer): Boolean;
    function IsBlockWhisper(sName: string): Boolean;
    function QuestCheckItem(sItemName: string; var nCount: Integer; var nParam:
      Integer; var nDura: Integer): pTUserItem;
    function QuestCheckItemEx(sItemName: string; nDura: Integer; boParam: Boolean): Integer;
    function QuestCheckItemX(sItemName: string; var nCount: Integer; var nParam:
      Integer; var nDura: Integer): pTUserItem;
    function GetCheckItemValue(nMakeIndex: Integer; sName: string): string;
    function GetItemValueSum(sItemName: string; sValName: string): Integer;
    function GetItemCountWithValue(sItemName: string; sValName: string; nValue: Integer): Integer;
    function QuestTakeCheckItem(CheckItem: pTUserItem): Boolean;
    procedure GainExp(dwExp: LongWord; dwMilitaryExp: LongWord; dwRepressDemonExp: LongWord);
    function GetExploit(PlayObject: TBaseObject): Boolean;
    function GetBeadExp(): Boolean;
    function GetWingExp(): Boolean;
    procedure GetExp(nExp: UInt64; nMilitaryExp: UInt64; nRepressDemon: UInt64; bScritpExp: Boolean = False; boShareMilitaryExp: Boolean = False; boShareRepressDemon: Boolean = False);
    procedure GetExpProc(nGetExp: UInt64; nGetMilitaryExp: UInt64; nGetRepressDemonExP: UInt64; bScritpExp: Boolean = False);
    procedure WinExp(nExp: UInt64; nMilitaryExp: UInt64; nRepressDemonExp: UInt64);
    procedure ClientGuildMemberList();
    procedure Run(); override;
    function Operate(ProcessMsg: pTProcessMessage): Boolean; override;
    procedure SendStruckMsg(wIdent: word; BaseObject, Attacker: TBaseObject; nDamage: Integer; wEffect: word);
    procedure RecalcAbilitys(boAction: Boolean = False); override;

    procedure DealCancel();
    procedure DealCancelA();
    function GetShowName(): string; override;
    procedure GetBackDealItems();
    procedure Disappear(); override;
    procedure GoldChange(sChrName: string; nGold: Integer);
    procedure ProcessUserLineMsg(sData: string; MsgType: word);
    procedure ProcessSayMsg(sData: string; nMsgType: Integer); override;
    procedure ClearStatusTime();
    procedure UserLogon(); virtual;
    procedure RefRankInfo(nRankNo: Integer; sRankName: string);
    procedure RefUserState;
    procedure SendGroupMembers();
    procedure JoinGroup(PlayObject: TPlayObject);
    function GeTBaseObjectInfo(): string;
    function GetHitMsgCount(): Integer;
    function GetSpellMsgCount(): Integer;
    function GetWalkMsgCount(): Integer;
    function GetRunMsgCount(): Integer;
    function GetTurnMsgCount(): Integer;
    function GetSiteDownMsgCount(): Integer;
    function GetDigUpMsgCount(): Integer;
    procedure SetScriptLabel(sLabel: string);
    procedure GetScriptLabel(sMsg: string; boLeft: Boolean);
    procedure SendScriptItemPic(sMsg: string; nParam: Integer);
    function LableIsCanJmp(sLabel: string; boLeft: Boolean): Boolean;
    function GetMyInfo(): string;
    procedure MakeGhost; override;
    procedure ScatterBagItems(ItemOfCreat: TBaseObject); override;
    procedure DropUseItems(BaseObject: TBaseObject; AttackBaseObject: TBaseObject = nil); override;
    function RecallHuman(sHumName: string; wRecallType: word): Boolean;
    procedure CancelDoShop;
    procedure UPGRADEMON(nType: Integer);
    procedure ReQuestGuildWar(sGuildName: string; WarTime: Integer = 0);
    procedure SendUpdateItem(UserItem: pTUserItem; boDelay: Boolean = True); override;
    procedure AddEvilToItemB(nWhere: word; nMakeIndex, BottleIndex: Integer);
    procedure ReleaseEvil(nMakeIndex: Integer);
    procedure GetBagUseItems(var btDc: byte; var btSc: byte; var btMc: byte; var btDura: byte);
    procedure CmdEndGuild();
    procedure CmdMemberFunction(sCmd, sParam: string);
    procedure CmdMemberFunctionEx(sCmd, sParam: string);
    procedure CmdSearchDear(sCmd, sParam: string);
    procedure CmdSearchMaster(sCmd, sParam: string);
    procedure CmdDearRecall(sCmd, sParam: string);
    procedure CmdMasterRecall(sCmd, sParam: string);
    procedure CmdFriendRecall(sCmd, sParam: string);
    procedure CmdSbkDoorControl(sCmd, sParam: string);
    procedure CmdClearBagItem(Cmd: pTGameCmd; sHumanName: string);
    procedure CmdShowUseItemInfo(Cmd: pTGameCmd; sHumanName: string);
    procedure CmdBindUseItem(Cmd: pTGameCmd; sHumanName, sItem, sType: string);
    procedure CmdUnBindUseItem(Cmd: pTGameCmd; sHumanName, sItem, sType: string);
    procedure CmdLockLogin(Cmd: pTGameCmd);
    procedure CmdViewDiary(sCmd: string; nFlag: Integer);
    procedure CmdUserMoveXY(sCmd, sX, sY: string);
    procedure CmdSearchHuman(sCmd, sHumanName: string);
    procedure CmdGroupRecall(sCmd: string; AllRecall: Boolean = False);
    procedure CmdAllowGroupReCall(sCmd, sParam: string);
    procedure CmdGuildRecall(sCmd, sParam: string);
    procedure CmdChangeAttackMode(nMode: Integer);
    procedure CmdChangeSalveStatus();
    procedure CmdChangeTigerStatus;
    procedure CmdTakeOnHorse(sCmd, sParam: string);
    procedure CmdTakeOffHorse(sCmd, sParam: string);
    procedure CmdPrvMsg(sCmd: string; nPermission: Integer; sHumanName: string);
    procedure CmdHumanLocal(Cmd: pTGameCmd; sHumanName: string);
    procedure CmdMapMove(Cmd: pTGameCmd; sMapName: string);
    procedure CmdPositionMove(Cmd: pTGameCmd; sMapName, sX, sY: string);
    procedure CmdHumanInfo(Cmd: pTGameCmd; sHumanName: string);
    procedure CmdReLoadAdmin(sCmd: string);
    procedure CmdReloadNpc(sParam: string);
    procedure CmdReloadManage(Cmd: pTGameCmd; sParam: string);
    procedure CmdReloadRobotManage;
    procedure CmdReloadRobot;
    procedure CmdReloadMonItems();
    procedure CmdAdjustExp(human: TPlayObject; nExp: Integer);
    procedure CmdAddGuild(Cmd: pTGameCmd; sGuildName, sGuildChief: string);
    procedure CmdDelGuild(Cmd: pTGameCmd; sGuildName: string);
    procedure CmdGuildWar(sCmd, sGuildName: string);
    procedure CmdChangeSabukLord(Cmd: pTGameCmd; sCASTLENAME, sGuildName: string; boFlag: Boolean);
    procedure CmdForcedWallconquestWar(Cmd: pTGameCmd; sCASTLENAME: string);
    procedure CmdOPTraining(sHumanName, sSkillName: string; nLevel: Integer);
    procedure CmdOPDeleteSkill(sHumanName, sSkillName: string);
    procedure CmdReloadGuildAll();
    procedure CmdReAlive(Cmd: pTGameCmd; sHumanName: string);
    procedure CmdAdjuestLevel(Cmd: pTGameCmd; sHumanName: string; nLevel: Integer);
    procedure CmdAdjuestExp(Cmd: pTGameCmd; sHumanName, sExp: string);
    procedure CmdBackStep(sCmd: string; nType, nCount: Integer);
    procedure CmdFreePenalty(Cmd: pTGameCmd; sHumanName: string);
    procedure CmdPKpoint(Cmd: pTGameCmd; sHumanName: string);
    procedure CmdIncPkPoint(Cmd: pTGameCmd; sHumanName: string; nPoint: Integer);
    procedure CmdHunger(sCmd, sHumanName: string; nHungerPoint: Integer);
    procedure CmdHair(Cmd: pTGameCmd; sHumanName: string; nHair: Integer);
    procedure CmdTrainingSkill(Cmd: pTGameCmd; sHumanName, sSkillName: string; nLevel: Integer);
    procedure CmdTrainingMagic(Cmd: pTGameCmd; sHumanName, sSkillName: string; nLevel: Integer);
    procedure CmdDelSkill(Cmd: pTGameCmd; sHumanName, sSkillName: string);
    procedure CmdDeleteItem(Cmd: pTGameCmd; sHumanName, sItemName: string; nCount: Integer);
    procedure CmdClearMission(Cmd: pTGameCmd; sHumanName: string);
    procedure CmdTraining(sSkillName: string; nLevel: Integer);
    procedure CmdChangeJob(Cmd: pTGameCmd; sHumanName, sJobName: string);
    procedure CmdChangeGender(Cmd: pTGameCmd; sHumanName, sSex: string);
    procedure CmdMission(Cmd: pTGameCmd; sX, sY: string);
    procedure CmdMobPlace(Cmd: pTGameCmd; sX, sY, sMonName, sCount: string);
    procedure CmdMobLevel(Cmd: pTGameCmd; Param: string);
    procedure CmdMobCount(Cmd: pTGameCmd; sMapName: string);
    procedure CmdHumanCount(Cmd: pTGameCmd; sMapName: string);
    procedure CmdDisableFilter(sCmd, sParam1: string);
    procedure CmdChangeUserFull(sCmd, sUserCount: string);
    procedure CmdChangeZenFastStep(sCmd, sFastStep: string);
    procedure CmdReconnection(sCmd, sIPaddr, sPort: string);
    procedure CmdContestPoint(Cmd: pTGameCmd; sGuildName: string);
    procedure CmdStartContest(Cmd: pTGameCmd; sParam1: string);
    procedure CmdEndContest(Cmd: pTGameCmd; sParam1: string);
    procedure CmdAnnouncement(Cmd: pTGameCmd; sGuildName: string);
    procedure CmdKill(Cmd: pTGameCmd; sHumanName: string);
    procedure CmdMakeItem(Cmd: pTGameCmd; sItemName: string; nCount: Integer);
    procedure CmdSmakeItem(Cmd: pTGameCmd; nWhere, nValueType: Integer; sOpCode: string; nValue: Integer);
    procedure CmdBonuPoint(Cmd: pTGameCmd; sHumName: string; nCount: Integer);
    procedure CmdDelBonuPoint(Cmd: pTGameCmd; sHumName: string);
    procedure CmdRestBonuPoint(Cmd: pTGameCmd; sHumName: string);
    procedure CmdFireBurn(nInt, nTime, nn: Integer);
    procedure CmdTestFire(sCmd: string; nRange, nType, nTime, nPoint: Integer);
    procedure CmdTestStatus(sCmd: string; nType, nTime: Integer);
    procedure CmdDelGold(Cmd: pTGameCmd; sHumName: string; nCount: Integer);
    procedure CmdAddGold(Cmd: pTGameCmd; sHumName: string; nCount: Integer);
    procedure CmdGameGold(Cmd: pTGameCmd; sHumanName: string; sCtr: string; nGold: Integer);
    procedure CmdGamePoint(Cmd: pTGameCmd; sHumanName: string; sCtr: string; nPoint: Integer);
    procedure CmdBindGold(Cmd: pTGameCmd; sHumanName: string; sCtr: string; nGold: Integer);
    procedure CmdBindGameGold(Cmd: pTGameCmd; sHumanName: string; sCtr: string; nGold: Integer);
    procedure CmdCreditPoint(Cmd: pTGameCmd; sHumanName: string; sCtr: string; nPoint: Integer);
    procedure CmdMob(Cmd: pTGameCmd; sMonName: string; nCount, nLevel: Integer; sShowName: string);
    procedure CmdRefineWeapon(Cmd: pTGameCmd; nDc, nMc, nSc, nHit: Integer);
    procedure CmdRecallMob(Cmd: pTGameCmd; sMonName: string; nCount, nLevel, nAutoChangeColor, nFixColor: Integer);
    procedure CmdLuckPoint(sCmd: string; nPermission: Integer; sHumanName, sCtr, sPoint: string);
    procedure CmdLotteryTicket(sCmd: string; nPermission: Integer; sParam1: string);
    procedure CmdReloadGuild(sCmd: string; nPermission: Integer; sParam1: string);
    procedure CmdReloadLineNotice(sCmd: string; nPermission: Integer; sParam1: string);
    procedure CmdReloadAbuse(sCmd: string; nPermission: Integer; sParam1: string);
    procedure CmdMobNpc(sCmd: string; nPermission: Integer; sParam1, sParam2, sParam3, sParam4: string);
    procedure CmdNpcScript(sCmd: string; nPermission: Integer; sParam1, sParam2, sParam3: string);
    procedure CmdDelNpc(sCmd: string; nPermission: Integer; sParam1: string);
    procedure CmdKickHuman(Cmd: pTGameCmd; sHumName: string);
    procedure CmdTing(Cmd: pTGameCmd; sHumanName: string);
    procedure CmdSuperTing(Cmd: pTGameCmd; sHumanName, sRange: string);
    procedure CmdMapMoveHuman(Cmd: pTGameCmd; sSrcMap, sDenMap: string);
    procedure CmdShutup(Cmd: pTGameCmd; sHumanName, sTime: string);
    procedure CmdShowMapInfo(Cmd: pTGameCmd; sParam1: string);
    procedure CmdShutupRelease(Cmd: pTGameCmd; sHumanName: string; boAll: Boolean);
    procedure CmdShutupList(Cmd: pTGameCmd; sParam1: string);
    procedure CmdShowSbkGold(Cmd: pTGameCmd; sCASTLENAME, sCtr, sGold: string);
    procedure CmdRecallHuman(Cmd: pTGameCmd; sHumanName: string);
    procedure CmdReGotoHuman(Cmd: pTGameCmd; sHumanName: string);
    procedure CmdShowHumanFlag(sCmd: string; nPermission: Integer; sHumanName, sFlag: string);
    procedure CmdShowHumanUnitOpen(sCmd: string; nPermission: Integer; sHumanName, sUnit: string);
    procedure CmdShowHumanUnit(sCmd: string; nPermission: Integer; sHumanName, sUnit: string);
    procedure CmdChangeAdminMode(sCmd: string; nPermission: Integer; sParam1: string; boFlag: Boolean);
    procedure CmdChangeObMode(sCmd: string; nPermission: Integer; sParam1: string; boFlag: Boolean);
    procedure CmdChangeSuperManMode(sCmd: string; nPermission: Integer; sParam1: string; boFlag: Boolean);
    procedure CmdChangeLevel(Cmd: pTGameCmd; sParam1: string);
    procedure CmdChangeDearName(Cmd: pTGameCmd; sHumanName: string; sDearName: string);
    procedure CmdChangeMasterName(Cmd: pTGameCmd; sHumanName: string; sMasterName, sIsMaster: string);
    procedure ChangeMasterName(sHumanName, sMasterName: string; boMaster: Boolean);
    procedure CmdStartQuest(Cmd: pTGameCmd; sQuestName, sMapName: string);
    procedure CmdSetPermission(Cmd: pTGameCmd; sHumanName, sPermission: string);
    procedure CmdClearMapMonster(Cmd: pTGameCmd; sMapName, sMonName, sItems, sGhost: string);
    procedure CmdReNewLevel(Cmd: pTGameCmd; sHumanName, sLevel: string);
    procedure CmdDenyIPaddrLogon(Cmd: pTGameCmd; sIPaddr, sFixDeny: string);
    procedure CmdDelDenyIPaddrLogon(Cmd: pTGameCmd; sIPaddr, sFixDeny: string);
    procedure CmdShowDenyIPaddrLogon(Cmd: pTGameCmd; sIPaddr, sFixDeny: string);
    procedure CmdDenyAccountLogon(Cmd: pTGameCmd; sAccount, sFixDeny: string);
    procedure CmdDelDenyAccountLogon(Cmd: pTGameCmd; sAccount, sFixDeny: string);
    procedure CmdShowDenyAccountLogon(Cmd: pTGameCmd; sAccount, sFixDeny: string);
    procedure CmdDenyCharNameLogon(Cmd: pTGameCmd; sCharName, sFixDeny: string);
    procedure CmdDelDenyCharNameLogon(Cmd: pTGameCmd; sCharName, sFixDeny: string);
    procedure CmdShowDenyCharNameLogon(Cmd: pTGameCmd; sCharName, sFixDeny: string);
    procedure CmdViewWhisper(Cmd: pTGameCmd; sCharName, sParam2: string);
    procedure CmdSpirtStart(sCmd: string; sParam1: string);
    procedure CmdSpirtStop(sCmd: string; sParam1: string);
    procedure CmdSetMapMode(sCmd: string; sMapName, sMapMode, sParam1, sParam2: string);
    procedure CmdShowMapMode(sCmd: string; sMapName: string);
    procedure CmdClearHumanPassword(sCmd: string; nPermission: Integer; sHumanName: string);
    procedure CmdChangeItemName(sCmd, sMakeIndex, sItemIndex, sItemName: string);
    procedure CmdDisableSendMsg(Cmd: pTGameCmd; sHumanName: string);
    procedure CmdEnableSendMsg(Cmd: pTGameCmd; sHumanName: string);
    procedure CmdDisableSendMsgList(Cmd: pTGameCmd);
    procedure CmdTestGetBagItems(Cmd: pTGameCmd; sParam: string);
    procedure CmdMobFireBurn(Cmd: pTGameCmd; sMAP, sX, sY, sType, sTime, sPoint: string);
    procedure CmdTestSpeedMode(Cmd: pTGameCmd; nWhere, nType: Integer);
    function ProcessUserCmd(sCmd, sParam1, sParam2, sParam3, sParam4, sParam5, sParam6, sParam7: string): Boolean;
    function ExecuteScript(ScriptObj: TObject; sLabel: string): Boolean; override;

    function GetTaskVal(const TaskID: Integer; ValID: Integer): Integer;
    function GetTaskStr(const TaskID: Integer; ValID: Integer): string;
    function GetColorTaskCount(): Integer;
    function GetTaskStep(const TaskID: Integer): Integer;
    function UpdateTaskStep(const TaskID: Integer; nStep: Integer): Integer;
    procedure RefreshTask(const TaskID, nStep: Integer);
    procedure SendColorTask(const TaskID, Color: Integer);
    procedure ClientDelTask(const TaskID: Integer);
    procedure ClientQueryEvilFollower;
    procedure ClearEvilFollower(nCode: Integer);
    function CheckMapRideOn(Envir: TEnvirnoment): Boolean;
    procedure DelPneuma(nIdx: Integer);
    procedure DelPneumaEnd(nIdx, btSex, btCount: byte);
    procedure TakeItemOn(sItemName: string; btWhere: Integer);
    procedure SendMagic_LvExp_Msg(const UserMagic: pTUserMagic; dwDelay: LongWord); override;
    procedure SendShopItems(BaseObject: TBaseObject; opcode: word); override;
    procedure SendShopResult(); override;
    function IsShop(): Boolean; override;                                                         //是否摆摊
    procedure GetUserShop(const pUserShop: PTUserShop); override;                                 //取摆摊状态
    function GetPetSoulItem(const nMakeIndex: Integer; boNew: Boolean = False): pTPetSoulItem;      //取一个魂佑装备位

    function GetAchievementInfo(const wIndex: word): PTAchievementInfo;
    procedure SendBroadVehicle(btCreatorType: Byte; VehicleExp: TVehicleExp);

    procedure SendWishAwardInfo();
published
    property m_nPetShopSize: Integer read PetDoShopCanSellCount;
end;

implementation
uses
Math, WolShare, Guild, HUtil32, ObjNpc, IdSrvClient, ItmUnit, Event, ObjMon, RandomEngine,aiplayer,
LocalDB, Castle, svMain, Magic, ObjMon3, ObjGoblin, EnvirMirror;

{ TPlayObject }

constructor TPlayObject.Create;                                                                     //004C9860
begin
inherited;
m_DelayCall := TList.Create;
m_MasterList := TList.Create;
//跑位魔法间隔
m_DynamicVarList := TList.Create;
m_ArrowList := TStringList.Create;
m_PetSoulItemsList := TList.Create;
m_CustomTableList := TList.Create;
m_AchievementList := TList.Create;
m_KnockEggList := TList.Create;
m_CheckCondition := TList.Create;
end;

destructor TPlayObject.Destroy;                                                                     //004C9B54
var
i, nCheckCode                         : Integer;
resourcestring
sExceptionMsg                         = ' TPlayObject::Destroy Code:=%d';
begin
nCheckCode := 0;
try
    //清空
    ClearFree;
    nCheckCode := 1;
    m_MasterList.free;
    nCheckCode := 2;
    m_DynamicVarList.free;
    nCheckCode := 3;
    m_DelayCall.free;
    nCheckCode := 4;
    m_ArrowList.free;
    m_PetSoulItemsList.free;
    FreeAndNil(m_CustomTableList);
    FreeAndNil(m_AchievementList);
    FreeAndNil(m_KnockEggList);
    FreeAndNil(m_CheckCondition);
except
    on E: Exception do begin
      MainOutMessage(Format(sExceptionMsg, ));
      MainOutMessage(E.Message);
    end;
end;
inherited;
end;

procedure TPlayObject.ClearUp(btFree: Boolean = False);
begin
inherited ClearUp(btFree);
m_btRaceServer := RC_PLAYOBJECT;
m_boEmergencyClose := False;
m_boSwitchData := False;
m_boReconnection := False;
m_boKickUserSessInfo := False;
m_boBagSend := False;
m_boKickFlag := False;
m_boSoftClose := False;
m_boReadyRun := False;
//bo698 := False;
m_dwHuanjingTick := GetTickCount;
m_nAnserIdx := -1;
//n69C := 0;
m_nHuanjingIdx := 0;
m_dwSaveRcdTick := GetTickCount();
m_boWantRefMsg := True;
m_boRcdSaved := False;
m_boDieInFight3Zone := False;

m_boTimeRecall := False;
m_sMoveMap := '';
m_nMoveX := 0;
m_nMoveY := 0;
m_dwRunTick := 0;                                                                                 //最后处理人物消息时间
m_nRunTime := 100;                                                                              //处理人物消息间隔    延时设置
m_dwSearchTime := 1000;
m_dwSearchTick := 0;
m_nViewRange := 12;
m_boNewHuman := False;
m_boLoginNoticeOK := False;
//bo6AB := False;
m_boSendNotice := False;

m_boRideOn := False;
m_boRideFightOn := False;
m_btHorseType := 0;
m_Horse := nil;
m_Pet := nil;
m_PackPet := nil;
FillChar(m_PetInfo, SizeOf(m_PetInfo), #0);
m_dwPneumaChangeTick := 0;
m_dwDoMotaeboMoveTick := GetTickCount();
m_dwEatTalismanTick := 0;
m_dwCheckDupObjTick := GetTickCount();
dwTick578 := GetTickCount();
m_boInSafeArea := False;
m_boInSafezone := False;
m_dwCheckSafeArea := GetTickCount();
m_dwMagicAttackTick := GetTickCount();
m_dwMagicAttackInterval := 0;
m_dwAttackTick := GetTickCount();
m_dwMoveTick := GetTickCount();
m_dwTurnTick := GetTickCount();
m_dwActionTick := GetTickCount();
m_dwAttackCount := 0;
m_dwAttackCountA := 0;
m_dwMagicAttackCount := 0;
m_dwMoveCount := 0;
m_dwMoveCountA := 0;
m_nOverSpeedCount := 0;
m_sOldSayMsg := '';
m_dwSayMsgTick := 0;
m_boDisableSayMsg := False;
m_dwDisableSayMsgTick := GetTickCount();

//n584 := 0;
//n588 := 0;
m_boSwitchData := False;
m_boSwitchDataSended := False;
m_nWriteChgDataErrCount := 0;
m_dwShowLineNoticeTick := GetTickCount();
m_nShowLineNoticeIdx := 0;
m_sMasterName := '';
m_sMasterName := '';
m_sMasterName := '';
m_nKillMonExpRate := 100;
m_wKillMonExpRate := 100;
m_dwKillMonBurstRateTime := 0;
m_dwKillMonExpRateTime := 0;
m_dwRateTick := GetTickCount();
m_dwDecAntvPowerTick := GetTickCount();
m_nPowerRate := 100;
m_dwPowerRateTime := 0;
m_nDefenceRate := 100;
m_dwDefenceRateTime := 0;
m_boSetStoragePwd := False;
m_boReConfigPwd := False;
m_boCheckOldPwd := False;
m_boUnLockPwd := False;
m_boUnLockStoragePwd := False;
m_boPasswordLocked := False;                                                                      //锁仓库
m_btPwdFailCount := 0;
m_sTempPwd := '';
m_sStoragePwd := '';

m_boFilterSendMsg := False;
m_DearHuman := nil;
m_MasterHuman := nil;

m_sStoreName := '';
m_nStoreMakeIndex := 0;
m_boCanMasterRecall := False;
m_boCanDearRecall := False;
m_dwDearRecallTick := GetTickCount();
m_dwMasterRecallTick := GetTickCount();
m_btReColorIdx := 0;
m_GetWhisperHuman := nil;
m_wContribution := 0;
m_sRankLevelName := g_sRankLevelName;

m_boFixedHideMode := True;
m_boFilterSendMsg := False;
m_boCanDeal := False;
m_boCanDrop := False;
m_boCanGetBackItem := False;
m_boCanWalk := False;
m_boCanRun := False;
m_boCanHit := False;
m_boCanSpell := False;
m_boCanUseItem := False;

m_nClientFlagMode := -1;
m_dwAutoGetExpTick := GetTickCount;
m_nAutoGetExpPoint := 0;
m_AutoGetExpEnvir := nil;
m_dwHitIntervalTime := g_Config.dwHitIntervalTime;                                                //攻击间隔
m_dwMagicHitIntervalTime := g_Config.dwMagicHitIntervalTime;                                    //魔法间隔
m_dwRunIntervalTime := g_Config.dwRunIntervalTime;                                                //走路间隔
m_dwWalkIntervalTime := g_Config.dwWalkIntervalTime;                                              //走路间隔
m_dwTurnIntervalTime := g_Config.dwTurnIntervalTime;                                              //换方向间隔
m_dwActionIntervalTime := g_Config.dwActionIntervalTime;                                          //组合操作间隔
m_dwRunLongHitIntervalTime := g_Config.dwRunLongHitIntervalTime;
//组合操作间隔
m_dwRunHitIntervalTime := g_Config.dwRunHitIntervalTime;                                          //组合操作间隔
m_dwWalkHitIntervalTime := g_Config.dwWalkHitIntervalTime;                                        //组合操作间隔
m_dwRunMagicIntervalTime := g_Config.dwRunMagicIntervalTime;
m_SessInfo := nil;
m_boTestSpeedMode := False;
m_boLockLogon := True;
m_boLockLogoned := False;

m_dwLastPersonalSetTick := GetTickCount - 60000;
m_dwLastRide := GetTickCount() - 3000;
m_dwWalkTick := 0;
m_boStickMode := False;
m_nMaxTaskCount := 10;                                                                            //最大任务总数
m_nAchievement := 0;                                                                              //活动任务
m_nTotalTaskCount := 0;                                                                           //总任务数
m_dwLastBuyShopitemTick := 0;
m_dwNextBannerNoticeTime := GetTickCount;
m_nBannerNoticeIdx := 0;
m_boHideBannerNotice := False;
m_boOfflineGetGamePoint := False;
m_boOfflineResume := False;
m_dwUseStoreTick := 0;
m_wGemCount := 0;
m_wGemCount := 0;
m_wGemCount := 0;
m_wGemCount := 0;
m_wGemCount := 0;                                                                              //红宝石、蓝宝石、绿宝石数量
m_nRefinePoint := 0;
m_nSpotDlgMode := 0;
m_nPetTargetX := -1;
m_nPetTargetY := -1;
m_sOffLineLabel := '';
m_nRunCount := 0;
m_FirstRunTick := GetTickCount;
m_sHorseName := '';
m_btSetHorseType := 0;
m_dwCallPneumaTick := 0;

m_nEatItemMakeIndex := 0;
m_nRandomGiveStep := 0;
m_nAutoOpenTreasureBox := 0;

m_dwTimerTick := 0;
m_dwTimerLong := 0;
m_sTimerLabel := '';

m_boSafeZoneOnLine := False;
m_boSaveKillMonExpRate := False;

m_btLastOutStatus := 0;
m_sLastMapName := '';
m_nLastCurrX := 0;
m_nLastCurrY := 0;
FillChar(m_Dan, SizeOf(TSoulBabyORDemonDanInfo), #0);
FillChar(m_ProvisionalAbil, SizeOf(TProvisionalAbil), #0);

FillChar(m_dwTimer, SizeOf(m_dwTimer), #0);
m_dwRideFightSkillTick := 0;
m_boInNonSuchPavilion := False;
m_wTotemStatus := 0;

m_boNeedKneel := False;
m_btRulerLevel := 0;
m_boCtrlMental := False;

m_Tiger := nil;
FillChar(m_TorDDM, SizeOf(TTigerORDemonDanMagic), #0);

m_boCreatePneuma := False;
m_pSwitchPneuma := nil;
m_nPneumaLastX := -1;
m_boInosculatePneuma := False;
m_dwInosculateTick := GetTickCount;
m_wCurFightValue := 0;                                                                            //当前元神战斗值
m_wInnerPneumaLevel := 0;                                                                         //内部元神战斗值
m_InosculatePneumaHP := 0;
m_InosculatePneumaMP := 0;
m_dwFieryDragonRunTick := 0;
m_sQueryName := '';
m_dwEatItemTick := 0;
m_dwEatDurgHPTick := 0;
m_dwEatDurgMPTick := 0;
m_boUnWater := False;
m_boQueryReLive := False;
FillChar(m_CustomValue, SizeOf(TCustomValue), #0);
FillChar(m_LimitValue, SizeOf(TLimitValue), #0);

m_boCatapultMode := False;
m_boCatapultAttackMode := False;
m_dwCatapultAttackTick := GetTickCount;
m_wCatapultHP := 0;
m_wCatapultMaxHP := 0;

FillChar(m_Shop, SizeOf(TShop), #0);
m_wShopItemCount := 0;
m_wShopKind := 0;
m_btShopBanner := 0;
m_nBannerColor := 0;
m_sMachineid := '';
m_btStorageSize := 39;

m_VersionManage := nil;                                                                           //客户端版本API控制
FillChar(m_SpiritInfo, SizeOf(TSpiritInfo), #0);                                                //神魂融合信息


m_nAllIncReply := 0;

m_boBeast := False;
FillChar(m_ReduceSkillLevel, SizeOf(m_ReduceSkillLevel), #0);
FillChar(m_ReduceSkillPoint, SizeOf(m_ReduceSkillPoint), #0);
m_ReduceSkillRate := 0;
m_FelementReduce := 0;
m_FelementRedouble := 0;
m_dwWenPeiJH := 0;                                                                              //纹佩精华
FillChar(m_WenPeiBox, SizeOf(TWenPeiBox), 0);                                                   //纹佩宝盒
m_wAchievePoint := 0;
m_nGatherExp := 0;
m_dwGatherExpTick := GetTickCount();
m_wPrenticeCount := 0;
m_boRideDragonMode := False;
m_dwTotalDamage := 0;
m_boOfficerGodWings := False;
m_wCentsOfficerLevel := 0;                                                                        //仙官等级
m_nCentsOfficerExp := 0;                                                                        //仙官经验
FillChar(m_VerifyCodeInfo, SizeOf(TVerifyCodeInfo), #0);
m_btComboPoint := 0;                                                                              //连击点
m_btComboTime := 0;                                                                               //连击点增加时间
m_btBroilHotStatuTime := 0;                                                                     //炙热效果
m_btRandomDanceTime := 0;
m_btGodRunTime := 0;                                                                              //神行
m_nMeatQuality := 0;
FillChar(m_UserConstellation, SizeOf(TUserConstellation), #0);
FillChar(m_GemSourcePow, SizeOf(TGemSourcePow), #0);
FillChar(m_GemLvInfo, SizeOf(TGemLvInfo), #0);
m_boSecretMode := False;
m_sSecretName := '';
m_btSecretDress := 0;
m_btSecretWeapon := 0;
m_btWalkLotus := 0;
m_nBodyLeathery := 0;
m_nSlaveType := 0;
m_boVehicleMaterial := False;
m_boRideOrthrusMode := False;
m_boFirstCarpenter := False;                                                                      //天下第一匠神
m_boGameManage := False;                                                                        //显示GM封号
m_boSoaring := False;                                                                           //显示渡劫飞升封号
m_btKingTitle := 0;                                                                               //王爵封号
m_btLoverTitle := 0;                                                                              //情人节封号
m_btColorSkill := 0;                                                                              //彩色技能
m_btLoverEvents := 0;
m_boBianShen := False;
m_nHiContribution := 0;
m_nCurContribution := 0;
FillChar(m_btSelfCreated, SizeOf(TSelfCreated), #0);                                              //自创材料
FillChar(m_SecretInfo, SizeOf(TSecretInfo), #0);

m_nDreamsType := 0;
m_nKillMonExpLoitRate := 100;
m_dwKillMonExpLoitRateTime := 0;
m_nKillMonRepressDemonRate := 100;
m_dwKillMonRepressDemonRateTime := 0;
FillChar(m_DreamsPass, SizeOf(TDreamsPass), 0);
FillChar(m_ExpeditionBox, SizeOf(TExpeditionBox), #0);
m_MagicOrder := '';
m_btMagicOrder := 0;
m_boComboMagic := false;
m_ConsignClass := 0;
m_GuildOfficial := 0;
m_KnockEggCount := 0;
FillChar(m_HumanDisarm, SizeOf(TDisarmInfo), #0);
FillChar(m_GuildSkill, SizeOf(TGuildManorSkill), #0);
FillChar(m_ScratchCard, SizeOf(TScratchCard), #0);
FillChar(m_VehicleExp, SizeOf(TVehicleExp), #0);
FillChar(m_RedPacket, SizeOf(TRedPacketsInfo), #0);
FillChar(m_ClanInsignia, SizeOf(TClanInsignia), #0);
FillChar(m_ButchItem, SizeOf(TButchItem), #0);
FillChar(m_RepressDemon, SizeOf(TRepressDemon), #0);
FillChar(m_HumWingInfo, SizeOf(THumWingInfo), #0);
FillChar(m_HumEquipsInfo, SizeOf(TRepressDemonEquipsInfo), #0);
m_boRulerhalo := false;
m_boUnSafeZone := False;
m_btDemonMode := 0;
m_btDemonForce := 0;
m_wMasterGeneral := 0;
FillChar(m_HumanDecLucky, SizeOf(TDisarmInfo), #0);
FillChar(m_dwStopMagic, SizeOf(m_dwStopMagic), 0);
FillChar(m_ErgumCount, SizeOf(TErgumCount), 0);
m_DealCreat := nil;
FillChar(m_boSuitSub, SizeOf(m_boSuitSub), 0);
FillChar(m_ExemptHurt, SizeOf(m_ExemptHurt), 0);


if btFree then
    ClearFree();
end;

procedure TPlayObject.ClearFree();
var
i, nCheckCode                         : Integer;
resourcestring
sExceptionMsg                         = ' TPlayObject::Destroy Code:=%d';
begin
nCheckCode := 0;
try
    nCheckCode := 1;

    m_MasterList.Clear;

    nCheckCode := 2;
    for i := 0 to m_DynamicVarList.Count - 1 do begin
      Dispose(pTDynamicVar(m_DynamicVarList.Items));
    end;
    m_DynamicVarList.Clear;

    nCheckCode := 3;
    for i := 0 to m_DelayCall.Count - 1 do begin
      Dispose(pTDelayCall(m_DelayCall.Items));
    end;
    m_DelayCall.Clear;

    nCheckCode := 4;
    for i := 0 to m_ArrowList.Count - 1 do begin
      Dispose(pTArrowRec(m_ArrowList.Objects));
    end;
    m_ArrowList.Clear;

    for i := 0 to m_PetSoulItemsList.Count - 1 do begin
      Dispose(pTPetSoulItem(m_PetSoulItemsList.Items));
    end;
    m_PetSoulItemsList.Clear;

    if m_pSwitchPneuma <> nil then
      Dispose(m_pSwitchPneuma);
    m_pSwitchPneuma := nil;

    //纹佩宝盒
    for i := 0 to m_AchievementList.Count - 1 do begin
      Dispose(PTAchievementInfo(m_AchievementList.Items));
    end;
    m_AchievementList.Clear;

    //自定义变量
    for i := 0 to m_CustomTableList.Count - 1 do begin
      TSQLiteTable(m_CustomTableList.Items).free;
    end;
    m_CustomTableList.Clear;

    if m_KnockEggList.Count > 0 then begin
      for I := 0 to m_KnockEggList.Count - 1 do begin
      if pTKnockEggItem(m_KnockEggList.Items) <> nil then
          Dispose(pTKnockEggItem(m_KnockEggList.Items));
      end;
    end;
    m_KnockEggList.Clear;

    if m_CheckCondition.Count > 0 then begin
      for I := 0 to m_CheckCondition.Count - 1 do begin
      if pTCondition(m_CheckCondition.Items) <> nil then
          Dispose(pTCondition(m_CheckCondition.Items));
      end;
    end;
    m_CheckCondition.Clear;
except
    on E: Exception do begin
      MainOutMessage(Format(sExceptionMsg, ));
      MainOutMessage(E.Message);
    end;
end;
end;

//执行消息命令

function TPlayObject.Operate(ProcessMsg: pTProcessMessage): Boolean;
var
CharDescEx                            : TCharDescEx;
CharDesc                              : TCharDesc;
UserShop                              : TUserShop;
nObjCount                           : Integer;
nArrItem                              : array of Integer;
s1C, sName, sData, sTmp, sGuildName   : string;
MessageBodyWL                         : TMessageBodyWL;
MessageBodyW                        : TMessageBodyW;
ShortMessage                        : TShortMessage;
CombineSkillEffect                  : TCombineSkillEffect;
dwDelayTime                           : LongWord;
nMsgCount                           : Integer;
Magic                                 : pTMagic;
i                                     : Integer;
AttackObject                        : TBaseObject;
NewMagicEff                           : TNewMagicEff;
HealthEffect                        : THealthEffect;
MagicEffect                           : TMagicEffect;
nX, nY, n18, n1C                      : Integer;
StdItem                               : pTStdItem;
btShiEld, btRShape                  : byte;
btType                              : Byte;
boBindGameGold                        : Boolean;
ColorItem                           : TColorItem;
UserItem                              : pTUserItem;
resourcestring
sHint1                              = '神奇的力量凝聚,你的元神分身被唤醒了。';
sHint2                              = '目前不能摆摊!!!';
sHint3                              = '目前不支持拍卖,请选择原地摆摊';
sHint4                              = '神奇的力量散去,你的元神分身开始沉睡。';
sHint5                              = '地图对象为空,无法处理地图切换!';
sSpeedExcept                        = '速度异常 Ident: %d Time: %d';
sOpDelay                              = '操作延迟 Ident: %d Time: %d';

begin
Result := True;
case ProcessMsg.wIdent of
    RM_TURN,
      RM_PUSH,
      RM_RUSH,
      RM_RUSHKUNG,
      RM_PUSH_LION: begin
      if (ProcessMsg.BaseObject <> nil) and ((TBaseObject(ProcessMsg.BaseObject) <> Self) or (ProcessMsg.wIdent = RM_PUSH) or
          (ProcessMsg.wIdent = RM_RUSH) or (ProcessMsg.wIdent = RM_RUSHKUNG) or (ProcessMsg.wIdent = RM_PUSH_LION)) then begin
          case ProcessMsg.wIdent of
            RM_PUSH:
            m_defMsg := MakeDefaultMsg(SM_BACKSTEP,
                Integer(ProcessMsg.BaseObject),
                ProcessMsg.nParam1 {x},
                ProcessMsg.nParam2 {y},
                MakeWord(ProcessMsg.wParam {dir},
                TBaseObject(ProcessMsg.BaseObject).m_btGender {light}));
            RM_RUSH:
            m_defMsg := MakeDefaultMsg(SM_RUSH,
                Integer(ProcessMsg.BaseObject),
                ProcessMsg.nParam1,
                ProcessMsg.nParam2,
                ProcessMsg.wParam);
            RM_RUSHKUNG:
            m_defMsg := MakeDefaultMsg(SM_RUSHKUNG,
                Integer(ProcessMsg.BaseObject), ProcessMsg.nParam1,
                ProcessMsg.nParam2, MakeWord(ProcessMsg.wParam,
                TBaseObject(ProcessMsg.BaseObject).m_btGender));
            RM_PUSH_LION:
            m_defMsg := MakeDefaultMsg(SM_LIONCRSH,
                Integer(ProcessMsg.BaseObject), ProcessMsg.nParam1,
                ProcessMsg.nParam2, MakeWord(ProcessMsg.wParam,
                TBaseObject(ProcessMsg.BaseObject).m_btGender));
          else begin
            m_defMsg := MakeDefaultMsg(SM_TURN,
                Integer(ProcessMsg.BaseObject),
                ProcessMsg.nParam1,
                ProcessMsg.nParam2,
                MakeWord(ProcessMsg.wParam, TBaseObject(ProcessMsg.BaseObject).m_btGender));
            end;
          end;

          if ProcessMsg.wIdent = RM_PUSH_LION then begin
            CharDesc.Feature := TBaseObject(ProcessMsg.BaseObject).GetFeature(Self);
            CharDesc.Status := TBaseObject(ProcessMsg.BaseObject).m_nCharStatus;
            CharDesc.Featurex := ProcessMsg.nParam3;
            s1C := EnCodeBuffer(@CharDesc, SizeOf(TCharDesc));
          end else begin
            CharDescEx.Feature := TBaseObject(ProcessMsg.BaseObject).GetFeature(Self);
            CharDescEx.Status := TBaseObject(ProcessMsg.BaseObject).m_nCharStatus;
            CharDescEx.Featurex := GetMaxHPCent(TBaseObject(ProcessMsg.BaseObject));
            s1C := EnCodeBuffer(@CharDescEx, SizeOf(TCharDescEx));
          end;

          if (ProcessMsg.wIdent <> RM_PUSH_LION) then begin
            if (ProcessMsg.sMsg <> '') then begin
            nObjCount := GetCharColor(TBaseObject(ProcessMsg.BaseObject));
            sTmp := ProcessMsg.sMsg + '/' + IntToStr(nObjCount) + TBaseObject(ProcessMsg.BaseObject).GetCharTurnMsg;
            s1C := s1C + EnCodeBuffer(@sTmp, Length(sTmp));                                    //sTmp不包含字符串长度
            end else if ProcessMsg.BaseObject <> nil then begin
            if (CheckSPCode(TBaseObject(Self).m_dwRuleCtrlCode, SP_MON_DARKENMONSTER)) or (TBaseObject(ProcessMsg.BaseObject).m_btRaceServer = 23) then begin
                nObjCount := GetCharColor(TBaseObject(ProcessMsg.BaseObject));
                sTmp := TBaseObject(ProcessMsg.BaseObject).GetShowName() + '/' + IntToStr(nObjCount) + TBaseObject(ProcessMsg.BaseObject).GetCharTurnMsg;
                s1C := s1C + EnCodeBuffer(@sTmp, Length(sTmp));
            end;
            end;
          end;
          SendSocket(@m_defMsg, s1C);

          if (ProcessMsg.wIdent = RM_TURN) and (ProcessMsg.sMsg <> '') then begin
            if (TBaseObject(ProcessMsg.BaseObject).m_btRaceServer = RC_PLAYOBJECT) then begin

            //发送Featur的消息
            i := TBaseObject(ProcessMsg.BaseObject).GetFeatureToLong(Self);
            m_defMsg := MakeDefaultMsg(SM_FEATURECHANGED,
                Integer(ProcessMsg.BaseObject),
                LoWord(i),
                HiWord(i),
                TBaseObject(ProcessMsg.BaseObject).GetGender);
            SendSocket(@m_defMsg, TBaseObject(ProcessMsg.BaseObject).GetFeatureChangedMsg());

            //金刚护体、风影盾等
            if (TBaseObject(ProcessMsg.BaseObject).m_nMagicStatus in ) then
                SendDefMessage(SM_FENGHAO,
                  Integer(ProcessMsg.BaseObject),
                  TBaseObject(ProcessMsg.BaseObject).m_nMagicStatus,
                  TBaseObject(ProcessMsg.BaseObject).m_nCharStatus,
                  0, '');
            //幻彩、幻影套装
            if TBaseObject(ProcessMsg.BaseObject).m_wHuancaiSuite > 0 then
                SendDefMessage(SM_FENGHAO,
                  Integer(ProcessMsg.BaseObject),
                  16,
                  TBaseObject(ProcessMsg.BaseObject).m_wHuancaiSuite,
                  0, '');

            //发送封号和翅膀
            if (TBaseObject(ProcessMsg.BaseObject).m_wExtraLevel > 0) or
                (TBaseObject(ProcessMsg.BaseObject).m_btAmbitLevel > 0) then begin
                if (TBaseObject(ProcessMsg.BaseObject).m_btRaceServer = RC_PLAYOBJECT) then
                  SendDefMessage(SM_FENGHAO,
                  Integer(ProcessMsg.BaseObject),
                  MakeWord(8, LoByte(TBaseObject(ProcessMsg.BaseObject).m_wExtraLevel)),          //元神境界
                  TBaseObject(ProcessMsg.BaseObject).GetPneumaAmbit,
                  HiByte(TBaseObject(ProcessMsg.BaseObject).m_wExtraLevel),
                  TBaseObject(ProcessMsg.BaseObject).GetExtraLevelName)
                else if (TBaseObject(ProcessMsg.BaseObject).m_wExtraLevel = 2) then
                  SendDefMessage(SM_FENGHAO,
                  Integer(ProcessMsg.BaseObject),
                  MakeWord(8, _Max(0,
                  TBaseObject(ProcessMsg.BaseObject).m_wExtraLevel - 1)),
                  0,
                  0,
                  '');
            end;
            if TBaseObject(ProcessMsg.BaseObject).m_wBianshenAppr <> 0 then begin
                SendDefMessage(SM_FENGHAO,
                  Integer(ProcessMsg.BaseObject),
                  64,
                  TBaseObject(ProcessMsg.BaseObject).m_wBianshenImg,
                  TBaseObject(ProcessMsg.BaseObject).m_wBianshenAppr, '');
            end;

            //金刚护体,护身真气 绿色血条
            if (TBaseObject(ProcessMsg.BaseObject).m_wStatusTimeArr > 0) then
                SendDefMessage(SM_HIDE,
                  Integer(ProcessMsg.BaseObject),
                  CalcCent(TBaseObject(ProcessMsg.BaseObject).m_nHushenDura,
                  TBaseObject(ProcessMsg.BaseObject).m_nHushenDuraMax),
                  100,
                  g_HushenLvColor,
                  '')
            else if (TBaseObject(ProcessMsg.BaseObject).m_wStatusTimeArr > 0) then
                SendDefMessage(SM_HIDE,
                  Integer(ProcessMsg.BaseObject),
                  CalcCent(TBaseObject(ProcessMsg.BaseObject).m_nHushenDura,
                  TBaseObject(ProcessMsg.BaseObject).m_nHushenDuraMax),
                  100,
                  g_HushenLvColor,
                  '');

            //融合元神的神魂值
            if TBaseObject(ProcessMsg.BaseObject).m_boPneuma and (ProcessMsg.BaseObject is TPlayObject) then begin
                if TPlayObject(ProcessMsg.BaseObject).m_boInosculatePneuma and TPlayObject(ProcessMsg.BaseObject).m_SpiritInfo.boMag then begin
                  if (TPlayObject(ProcessMsg.BaseObject).m_PneumaObject = Self) then begin
                  m_defMsg := MakeDefaultMsg(SM_SPIRITHP,
                      Integer(ProcessMsg.BaseObject),
                      TPlayObject(ProcessMsg.BaseObject).m_SpiritInfo.wCurHP,
                      TPlayObject(ProcessMsg.BaseObject).m_SpiritInfo.wMaxHP,
                      0);
                  end else begin
                  m_defMsg := MakeDefaultMsg(SM_SPIRITHP,
                      Integer(ProcessMsg.BaseObject),
                      CalcCent(TPlayObject(ProcessMsg.BaseObject).m_SpiritInfo.wCurHP,
                      TPlayObject(ProcessMsg.BaseObject).m_SpiritInfo.wMaxHP),
                      100,
                      0);
                  end;
                  n18 := 0;
                  SendSocket(@m_defMsg, EnCodeBuffer(@n18, 2));
                end;
            end;

            //技能效果
            m_defMsg := MakeDefaultMsg(SM_CHARSTATUSCHANGED,
                Integer(ProcessMsg.BaseObject),
                LoWord(TBaseObject(ProcessMsg.BaseObject).m_nCharStatus),
                HiWord(TBaseObject(ProcessMsg.BaseObject).m_nCharStatus),
                TBaseObject(ProcessMsg.BaseObject).m_nHitSpeed);

            SendSocket(@m_defMsg, TBaseObject(ProcessMsg.BaseObject).GetCharStatusMsg);

            //发送心魔、人类 攻击值
{$IF DEMONSERVER = 1}
            if m_btDemonMode > 0 then begin
                g_PacketManage3.Init;
                g_PacketManage3.WriteByte(1);
                g_PacketManage3.WriteByte(m_btDemonForce);
                g_PacketManage3.WriteInteger(Integer(Self));
                g_PacketManage3.WriteInteger(0);
                SendRefMsg(RM_DEMONHIT, 0, Integer(Self), 0, 0, g_PacketManage3.GetMsg);
                if (m_btDemonForce = 0) then begin
                  m_btDemonMode := 0;
                end;
            end;
{$IFEND}
            end;
            //元神灵珠模式
            if TBaseObject(ProcessMsg.BaseObject).m_boPneuma and
            (TBaseObject(ProcessMsg.BaseObject).m_boPneumaEffMode) then
            SendDefMessage(3082, Integer(ProcessMsg.BaseObject), 1, 0, 0, '');

            //发送摆摊状态
            if TBaseObject(ProcessMsg.BaseObject).IsShop then begin
            TBaseObject(ProcessMsg.BaseObject).GetUserShop(@UserShop);
            //发送操作结果和商店名称
            if (TBaseObject(ProcessMsg.BaseObject).m_btRaceServer = RC_PLAYOBJECT) then
                m_defMsg := MakeDefaultMsg(SM_USERDOSHOP,
                  Integer(ProcessMsg.BaseObject),
                  TBaseObject(ProcessMsg.BaseObject).m_nCurrX,
                  TBaseObject(ProcessMsg.BaseObject).m_nCurrY,
                  TBaseObject(ProcessMsg.BaseObject).m_btDirection)
            else
                m_defMsg := MakeDefaultMsg(SM_PETDOSHOP,
                  Integer(ProcessMsg.BaseObject),
                  TBaseObject(ProcessMsg.BaseObject).m_nHomeX,
                  TBaseObject(ProcessMsg.BaseObject).m_nHomeY,
                  TBaseObject(ProcessMsg.BaseObject).m_btJob);
            SendSocket(@m_defMsg, EnCodeBuffer(@UserShop, 62));
            end;
            //弓箭手下跪
            if m_boNeedKneel then begin
            if (TBaseObject(ProcessMsg.BaseObject).m_btRaceServer in ) then begin
                TBaseObject(ProcessMsg.BaseObject).m_btDirection := GetNextDirection(TBaseObject(ProcessMsg.BaseObject).m_nCurrX,
                  TBaseObject(ProcessMsg.BaseObject).m_nCurrY,
                  m_nCurrX,
                  m_nCurrY);
                TBaseObject(ProcessMsg.BaseObject).SendRefMsg(RM_HIT,
                  MakeWord(TBaseObject(ProcessMsg.BaseObject).m_btDirection, 1),
                  TBaseObject(ProcessMsg.BaseObject).m_nCurrX,
                  TBaseObject(ProcessMsg.BaseObject).m_nCurrY,
                  0,
                  TBaseObject(ProcessMsg.BaseObject).GetShowName);
            end;
            end;
            //灵魂墙
            if TBaseObject(ProcessMsg.BaseObject).m_boSpiritWall then begin
            SendMsg(TBaseObject(ProcessMsg.BaseObject), RM_GHOST, 0, 0, 0, 0, '');
            end;
            //投石车 1140 1137

          end;
      end;
      end;
    CM_WALK: begin                                                                                  //3011                     //行走   //---------------
      if ClientWalkXY(ProcessMsg.wIdent, ProcessMsg.nParam1 {x}, ProcessMsg.nParam2 {y}, ProcessMsg.boLateDelivery, dwDelayTime) then begin
          m_dwActionTick := GetTickCount;
          SendSocket(nil, sSTATUS_GOOD + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
          if g_Config.boStartMapEvent then begin
            StartMapEventOfWalk();                                                                  //跑步事件触发
          end;
          //生活技能挖掘中移动中断
          if (m_ButchItem.PlayObject > 0) and (m_ButchItem.BaseObject > 0) and (m_dwButchItemTime > 0) then begin
            m_dwButchItemTime := 0;
            g_PacketManage3.Init;
            g_PacketManage3.WriteInteger(m_ButchItem.PlayObject);
            g_PacketManage3.FillWrite(8, 0);
            g_PacketManage3.WriteInteger($05);
            g_PacketManage3.WriteByte(0);
            g_PacketManage3.WriteByte(m_btDirection);
            g_PacketManage3.FillWrite(6, 0);
            SendDefMessage(2161, Integer(self), 0, 0, 0, g_PacketManage3.GetMsg, True);
            m_sScriptParam := TBaseObject(m_ButchItem.BaseObject).m_sCharName;
            ExecuteScript(g_FunctionNPC, '@采集中断_' + IntToStr(m_ButchItem.nID));
          end;
      end else begin
          if (not g_Config.boDisableM2SpeedCtrl) then begin
            if dwDelayTime = 0 then begin
            SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
            end else begin
            nMsgCount := GetWalkMsgCount();
            if nMsgCount >= g_Config.nMaxWalkMsgCount then begin
                Inc(m_nOverSpeedCount);                                                             //超速次数
                if m_nOverSpeedCount > g_Config.nOverSpeedKickCount then begin
                  if g_Config.boKickOverSpeed then begin
                  SysMsg(g_sKickClientUserMsg {'请勿使用非法软件!!!'}, c_Red, t_Hint);
                  m_boEmergencyClose := True;
                  end;
                  if g_Config.boViewHackMessage then begin
                  MainOutMessage(Format(g_sWalkOverSpeed, ));
                  end;
                end;
                //如果超速则发送攻击失败信息
                SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
                if m_boTestSpeedMode then
                  SysMsg(Format(sSpeedExcept, ), c_Red, t_Hint);
            end else begin
                if (dwDelayTime > g_Config.dwDropOverSpeed) and
                  (g_Config.btSpeedControlMode = 1) and m_boFilterAction then begin
                  SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
                  if m_boTestSpeedMode then
                  SysMsg(Format(sSpeedExcept, ), c_Red, t_Hint);
                end else begin
                  if m_boTestSpeedMode then
                  SysMsg(Format(sOpDelay, ), c_Red, t_Hint);
                  SendDelayMsg(Self, ProcessMsg.wIdent, ProcessMsg.wParam,
                  ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.nParam3, '',
                  dwDelayTime);
                  Result := False;
                end;
            end;
            end;
          end else
            SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
      end;
      end;
    RM_WALK: begin                                                                                  //10002      //走
      if TBaseObject(ProcessMsg.BaseObject) <> Self then begin
          m_defMsg := MakeDefaultMsg(SM_WALK, Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1, ProcessMsg.nParam2, MakeWord(ProcessMsg.wParam,
            TBaseObject(ProcessMsg.BaseObject).m_nLight));
          CharDescEx.Feature := TBaseObject(ProcessMsg.BaseObject).GetFeature(Self);
          CharDescEx.Status := TBaseObject(ProcessMsg.BaseObject).m_nCharStatus;
          CharDescEx.Featurex := GetMaxHPCent(TBaseObject(ProcessMsg.BaseObject));
          SendSocket(@m_defMsg, EnCodeBuffer(@CharDescEx, SizeOf(TCharDescEx)));
      end;
      end;
    CM_RUN: begin                                                                                 //3013       //跑
      if ClientRunXY(ProcessMsg.wIdent, ProcessMsg.nParam1 {x},
          ProcessMsg.nParam2 {y}, ProcessMsg.nParam3, dwDelayTime) then begin
          m_dwActionTick := GetTickCount;
          SendSocket(nil, sSTATUS_GOOD + IntToStr(ProcessMsg.nParam1) + '/' + IntToStr(ProcessMsg.nParam2));
          if g_Config.boStartMapEvent then begin
            StartMapEventOfRun();                                                                   //跑步事件触发
          end;
          //生活技能挖掘中移动中断
          if (m_ButchItem.PlayObject > 0) and (m_ButchItem.BaseObject > 0) and (m_dwButchItemTime > 0) then begin
            m_dwButchItemTime := 0;
            g_PacketManage3.Init;
            g_PacketManage3.WriteInteger(m_ButchItem.BaseObject);
            g_PacketManage3.FillWrite(8, 0);
            g_PacketManage3.WriteInteger($05);
            g_PacketManage3.WriteByte(0);
            g_PacketManage3.WriteByte(m_btDirection);
            g_PacketManage3.FillWrite(6, 0);
            SendDefMessage(2161, Integer(self), 0, 0, 0, g_PacketManage3.GetMsg, True);
            m_sScriptParam := TBaseObject(m_ButchItem.BaseObject).m_sCharName;
            ExecuteScript(g_FunctionNPC, '@采集中断_' + IntToStr(m_ButchItem.nID));
          end;
      end else begin
          if (not g_Config.boDisableM2SpeedCtrl) then begin
            if dwDelayTime = 0 then begin
            SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
            end else begin
            nMsgCount := GetRunMsgCount();
            if nMsgCount >= g_Config.nMaxRunMsgCount then begin
                Inc(m_nOverSpeedCount);
                if m_nOverSpeedCount > g_Config.nOverSpeedKickCount then begin
                  if g_Config.boKickOverSpeed then begin
                  SysMsg(g_sKickClientUserMsg {'请勿使用非法软件!!!'}, c_Red, t_Hint);
                  m_boEmergencyClose := True;
                  end;
                  if g_Config.boViewHackMessage then begin
                  MainOutMessage(Format(g_sRunOverSpeed, ));
                  end;
                end;
                //如果超速则发送攻击失败信息
                SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
            end else begin
                if (dwDelayTime > g_Config.dwDropOverSpeed) and
                  (g_Config.btSpeedControlMode = 1) and m_boFilterAction then begin
                  SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
                  if m_boTestSpeedMode then
                  SysMsg(Format(sSpeedExcept, ), c_Red, t_Hint);
                end else begin
                  if m_boTestSpeedMode then
                  SysMsg(Format(sOpDelay, ), c_Red, t_Hint);
                  SendDelayMsg(Self, ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1, ProcessMsg.nParam2, CM_RUN, '', dwDelayTime);
                  Result := False;
                end;
            end;
            end;
          end else
            SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
      end;
      end;
    RM_RUN: begin                                                                                 ////跑
      if TBaseObject(ProcessMsg.BaseObject) <> Self then begin
          m_defMsg := MakeDefaultMsg(SM_RUN, Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1, ProcessMsg.nParam2, MakeWord(ProcessMsg.wParam,
            TBaseObject(ProcessMsg.BaseObject).m_nLight));
          CharDescEx.Feature := TBaseObject(ProcessMsg.BaseObject).GetFeature(Self);
          CharDescEx.Status := TBaseObject(ProcessMsg.BaseObject).m_nCharStatus;
          CharDescEx.Featurex := GetMaxHPCent(TBaseObject(ProcessMsg.BaseObject));
          s1C := EnCodeBuffer(@CharDescEx, SizeOf(CharDescEx));

          nObjCount := GetCharColor(TBaseObject(ProcessMsg.BaseObject));
          if ProcessMsg.sMsg <> '' then
            s1C := s1C + (EnCodeString(ProcessMsg.sMsg + '/' + IntToStr(nObjCount)));
          SendSocket(@m_defMsg, s1C);
      end;
      end;
    RM_HIT: begin                                                                                 ////攻击
      if TBaseObject(ProcessMsg.BaseObject) <> Self then begin
          m_defMsg := MakeDefaultMsg(SM_HIT, Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.wParam);
          CharDescEx.Feature := TBaseObject(ProcessMsg.BaseObject).GetFeature(Self);
          CharDescEx.Status := TBaseObject(ProcessMsg.BaseObject).m_nCharStatus;
          SendSocket(@m_defMsg, EnCodeBuffer(@CharDescEx, 8));
      end;
      end;
    CM_SPELL: begin                                                                                 //3017004D76FD   //魔法攻击
      if not m_boNoAttackMode and ClientSpellXY(ProcessMsg.wIdent,
          ProcessMsg.wParam, ProcessMsg.nParam1, ProcessMsg.nParam2,
          TBaseObject(ProcessMsg.nParam3), ProcessMsg.boLateDelivery, dwDelayTime) then begin
          m_dwActionTick := GetTickCount;

          SendSocket(nil, sSTATUS_GOOD + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));

      end else begin
          if m_boNoAttackMode then
            SysMsg('观众模式不能参与攻击', c_Red, t_Hint);

          if (not g_Config.boDisableM2SpeedCtrl) then begin
            if dwDelayTime = 0 then begin
            SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));      //-----------传世行走失败
            end else begin
            nMsgCount := GetSpellMsgCount();
            if nMsgCount >= g_Config.nMaxSpellMsgCount then begin
                Inc(m_nOverSpeedCount);
                if m_nOverSpeedCount > g_Config.nOverSpeedKickCount then begin
                  if g_Config.boKickOverSpeed then begin
                  SysMsg(g_sKickClientUserMsg {'请勿使用非法软件!!!'}, c_Red, t_Hint);
                  m_boEmergencyClose := True;
                  end;
                  if g_Config.boViewHackMessage then begin
                  MainOutMessage(Format(g_sSpellOverSpeed, ));
                  end;
                end;
                //如果超速则发送攻击失败信息
                SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));      //-----------传世行走失败
            end else begin
                if (dwDelayTime > g_Config.dwDropOverSpeed) and
                  (g_Config.btSpeedControlMode = 1) and m_boFilterAction then begin
                  SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));    //-----------传世行走失败
                  if m_boTestSpeedMode then
                  SysMsg(Format(sSpeedExcept, ), c_Red, t_Hint);
                end else begin
                  if m_boTestSpeedMode then
                  SysMsg(Format(sOpDelay, ), c_Red, t_Hint);
                  SendDelayMsg(Self, ProcessMsg.wIdent, ProcessMsg.wParam,
                  ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.nParam3, '', dwDelayTime);
                  Result := False;
                end;
            end;
            end;
          end else
            SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
      end;
      end;
    RM_SPELL: begin                                                                                 // 10007//魔法
      if (TBaseObject(ProcessMsg.BaseObject) <> Self) or GetSpellToSelf(ProcessMsg.nParam3) then begin
          m_defMsg := MakeDefaultMsg(SM_SPELL,
            Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1,                                                                     //X
            ProcessMsg.nParam2,                                                                     //Y
            ProcessMsg.wParam);                                                                     //btEffect
          SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
      end;
    RM_SPELL2: begin
      if TBaseObject(ProcessMsg.BaseObject) <> Self then begin
          m_defMsg := MakeDefaultMsg(SM_POWERHIT,
            Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1,
            ProcessMsg.nParam2,
            ProcessMsg.wParam);
          SendSocket(@m_defMsg, '');
      end;
      end;
    RM_HEALTHSPELLCHANGED: begin                                                                  //10052
      if TBaseObject(ProcessMsg.BaseObject) <> Self then begin
          m_defMsg := MakeDefaultMsg(SM_HEALTHSPELLCHANGED,
            Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1,
            ProcessMsg.nParam3,
            ProcessMsg.nParam2);
          SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
      end;
    CM_HIT,                                                                                       //3014               //攻击动作
      CM_HEAVYHIT,                                                                                  //3015
      CM_BIGHIT,                                                                                    //3016
      CM_POWERHIT,                                                                                  //3018
      CM_LONGHIT,                                                                                 //3019
      CM_WIDEHIT,                                                                                 //3024
      CM_CRSHIT,
      CM_TWNHIT,
      CM_FIREHIT,
      CM_3026: begin                                                                              //3025
      //      {$IF USESDK = DEBUG}
      //      MainOutMessage(Format('攻击动作:%s-%d-%d-%d-%d-%d %s',
      //          [m_sCharName, ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
      //          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg]));
      //      {$IFEND}

      if not m_boNoAttackMode and ClientHitXY(ProcessMsg.wIdent {ident},
          ProcessMsg.nParam1 {x}, ProcessMsg.nParam2 {y}, ProcessMsg.wParam {dir},
          ProcessMsg.nParam3, ProcessMsg.boLateDelivery, dwDelayTime) then begin
          m_dwActionTick := GetTickCount;

          SendSocket(nil, sSTATUS_GOOD + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
      end else begin
          if m_boNoAttackMode then
            SysMsg('观众模式不能参与攻击', c_Red, t_Hint);

          if (not g_Config.boDisableM2SpeedCtrl) then begin
            if dwDelayTime = 0 then begin
            SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
            end else begin
            nMsgCount := GetHitMsgCount();
            if nMsgCount >= g_Config.nMaxHitMsgCount then begin
                Inc(m_nOverSpeedCount);
                if m_nOverSpeedCount > g_Config.nOverSpeedKickCount then begin
                  if g_Config.boKickOverSpeed then begin
                  SysMsg(g_sKickClientUserMsg {'请勿使用非法软件!!!'}, c_Red, t_Hint);
                  m_boEmergencyClose := True;
                  end;
                  if g_Config.boViewHackMessage then begin
                  MainOutMessage(Format(g_sHitOverSpeed, ));
                  end;
                end;
                //如果超速则发送攻击失败信息
                SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
            end else begin
                if (dwDelayTime > g_Config.dwDropOverSpeed) and
                  (g_Config.btSpeedControlMode = 1) and m_boFilterAction then begin
                  //SendUpdateMsg(Self, 65535, 0, m_nCurrX, m_nCurrY, 0, '');
                  SendSocket(nil, sSTATUS_GOOD + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
                  if m_boTestSpeedMode then
                  SysMsg(Format(sSpeedExcept, ), c_Red, t_Hint);
                end else begin
                  if m_boTestSpeedMode then begin
                  SysMsg(Format(sOpDelay, ), c_Red, t_Hint);
                  end;
                  SendDelayMsg(Self, ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.nParam3, '', dwDelayTime);
                  Result := False;
                end;
            end;
            end;
          end else
            SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
      end;
      end;
    RM_ANYINGLEIDIAN: begin                                                                         //显示暗影雷电的效果
      ShortMessage.Ident := $12;
      ShortMessage.wMsg := ProcessMsg.nParam3;
      m_defMsg := MakeDefaultMsg($2BDC,
          ProcessMsg.nParam1,
          LoWord(ProcessMsg.nParam2),
          HiWord(ProcessMsg.nParam2),
          ProcessMsg.wParam);
      SendSocket(@m_defMsg, EnCodeBuffer(@ShortMessage,
          SizeOf(TShortMessage)));
      end;
    CM_3078: begin                                                                                  //释放了元神
      DeCodeBuffer(ProcessMsg.sMsg, @nObjCount, SizeOf(Integer));
      if (m_PneumaObject <> nil) and (nObjCount = Integer(m_PneumaObject)) then begin
          SysMsg(sHint1, c_Red, t_Hint);
      end;
{$IF USESDK = DEBUG}
      MainOutMessage(Format('元神消息:%s-%d-%d-%d-%d-%d %s-%d',
          [m_sCharName, ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg, nObjCount]));
{$IFEND}
      end;
    RM_SENDMYNAME: begin
      SendDefMessage(SM_9609, Integer(Self), 0, 0, 0, m_sCharName);
      end;
    CM_3080: begin                                                                                  //释放或收起元神
      PneumaLogin();
{$IF USESDK = DEBUG}
      MainOutMessage(Format('元神消息:%s-%d-%d-%d-%d-%d %s-%s',
          [m_sCharName, ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg,
            DeCodeString(ProcessMsg.sMsg)]));
{$IFEND}
      end;
    CM_OPPNEUMAITEM: begin                                                                        //把人物包裹物品移动到元神包裹
      ClientOpPneumaBagItem(ProcessMsg.sMsg);
      end;
    CM_3077: begin                                                                                  //人物和元神之间交换金币
      ClientOpPneumaGold(ProcessMsg.sMsg)
      end;
    CM_3079: begin                                                                                  //估计是寻找主人的位置消息
      if m_boPneuma and (m_PneumaObject <> nil) and ((m_PEnvir <> m_PneumaObject.m_PEnvir) or
          (abs(m_nCurrX - m_PneumaObject.m_nCurrX) > 15) or (abs(m_nCurrY - m_PneumaObject.m_nCurrY) > 15)) then begin
          if m_PneumaObject.GetRightPosition(nX, nY) then begin
            if m_PneumaObject.GetCanMovePosition(nX, nY, 3, n18, n1C) then begin
            SendRefMsg(RM_SPACEMOVE_FIRE, 0, 0, 0, 0, '');
            SpaceMove(m_PneumaObject.m_sMapName, n18, n1C, 0, nil);
            end;
          end;
      end;
      end;
    CM_3082: begin                                                                                  //在灵珠模式和人形模式间切换
{$IF USESDK = DEBUG}
      MainOutMessage(Format('元神灵珠消息 %d-%d-%d-%d-%d %s',
          [ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg]));
{$IFEND}
      ChangePneumaState();
      end;
    RM_YSSTATECHANGED: begin
      SendDefMessage(3082, ProcessMsg.nParam1, ProcessMsg.wParam, 0, 0, '');
      end;
    CM_OPENRANK: begin
      if (ProcessMsg.nParam2 = 0) then begin                                                      //0、自己点的; 1、服务器更新//查看英雄榜
          if not g_Config.boUseRankList then
            ExecuteScript(g_ManageNPC, '@OpenRank')
          else begin
            if m_WAbil.level >= g_Config.nViewRankLevel then begin
{$IF DEMONSERVER = 1}
            if g_Config.boNightMareServer then
                SendDefMessage($9702, Integer(Self), g_Config.nUseRanking, 2, 0, '')
            else
{$IFEND}
                SendDefMessage($9702, Integer(Self), g_Config.nUseRanking, 1, 0, '')
            end else begin
            SysMsg(Format('您当前等级还没有达到%d级,无法查询排行榜', ), c_Red, t_Hint);
            end;
          end;
      end;
      end;
    CM_SENDRANK: begin                                                                              //查询对应的排行榜
      if m_WAbil.level >= g_Config.nRankLevel then
          g_RankManage.OnQueryRankListOrd(Self, ProcessMsg.nParam2, ProcessMsg.wParam);
      end;
    CM_RECALLEVIL: begin
      ClientEvilOp(ProcessMsg.nParam2, ProcessMsg.nParam1,
          MakeLong(ProcessMsg.nParam3, ProcessMsg.wParam));
{$IF USESDK = DEBUG}
      MainOutMessage(Format('心魔控制消息 %d-%d-%d-%d-%d %s',
          [ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg]));
{$IFEND}
      end;
    CM_ERNIE: begin
      ClientErnie(ProcessMsg.nParam2);
{$IF USESDK = DEBUG}
      MainOutMessage(Format('神龙献宝消息 %d-%d-%d-%d-%d %s',
          [ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg]));
{$IFEND}
      end;
    CM_HUANJING: begin
      ClientOpenHuanjing(ProcessMsg.nParam1, ProcessMsg.nParam2,
          ProcessMsg.nParam3);
{$IF USESDK = DEBUG}
      MainOutMessage(Format('天关幻境消息 %d-%d-%d-%d-%d %s',
          [ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg]));
{$IFEND}
      end;
    CM_PERSONSET: begin                                                                           //个性化设置
{$IF USESDK = DEBUG}
      MainOutMessage(Format('内挂设置消息 %d-%d-%d-%d-%d %s',
          [ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg]));
{$IFEND}
      ClientPersonalSet(ProcessMsg.wParam, ProcessMsg.nParam2,
          ProcessMsg.nParam3, ProcessMsg.sMsg);
      end;
    CM_WOLSHOP: begin
      if ProcessMsg.nParam2 = 1 then begin
          //滚动消息
          m_defMsg := MakeDefaultMsg(SM_WOLSHOP, Integer(Self), 0, 0, 0);
          SendSocket(@m_defMsg, EnCodeString(UserEngine.GetShopScrollMsg));
          //热点标题
          m_defMsg.Param := 10;
          SendSocket(@m_defMsg, EnCodeString(UserEngine.GetShopHotTitle));
          //热销排行榜
          m_defMsg.Param := 1;
          SendSocket(@m_defMsg, EnCodeString(UserEngine.GetHotSellItems));
          //首页子栏目列表
          m_defMsg.Param := 2;
          s1C := UserEngine.GetBandItems('10');
          SendSocket(@m_defMsg, EnCodeString(s1C));
          //首页第一子栏目商品
          m_defMsg.Param := 3;
          s1C := UserEngine.GetSubBandItems(self, '1010');
          SendSocket(@m_defMsg, EnCodeString(s1C));
      end else if ProcessMsg.nParam2 = 2 then begin
          //子栏目列表
          m_defMsg := MakeDefaultMsg(SM_WOLSHOP, Integer(Self), 2, 0, 0);
          s1C := UserEngine.GetBandItems(DeCodeString(ProcessMsg.sMsg));
          SendSocket(@m_defMsg, EnCodeString(s1C));
          //第一子栏目商品列表
          if s1C <> '&' then begin
            m_defMsg := MakeDefaultMsg(SM_WOLSHOP, Integer(Self), 3, 0, 0);
            s1C := UserEngine.GetSubBandItems(Self, DeCodeString(ProcessMsg.sMsg) + '10');
            SendSocket(@m_defMsg, EnCodeString(s1C));
          end;
      end else if ProcessMsg.nParam2 = 3 then begin                                             //查询子栏目商品列表
          s1C := DeCodeString(ProcessMsg.sMsg);
          if s1C <> '&' then begin
            m_defMsg := MakeDefaultMsg(SM_WOLSHOP, Integer(Self), 3, 0, 0);
            s1C := UserEngine.GetSubBandItems(Self, s1C);
            SendSocket(@m_defMsg, EnCodeString(s1C));
          end;
      end else if ProcessMsg.nParam2 = 4 then begin
          //商品描述信息
          s1C := UserEngine.GetStdItemDesc(Self, DeCodeString(ProcessMsg.sMsg));
          m_defMsg := MakeDefaultMsg(SM_WOLSHOP, Integer(Self), 4, 0, 0);
          SendSocket(@m_defMsg, EnCodeString(s1C));
      end else if (ProcessMsg.nParam2 in ) or (ProcessMsg.nParam2 = $0105) then begin   //购买 5=元宝16=绑定元宝
          SetLength(s1C, Round(Length(ProcessMsg.sMsg) * 3 / 4));
          boBindGameGold := ProcessMsg.nParam2 = 16;
          DeCodeBuffer(ProcessMsg.sMsg, @s1C, Length(s1C));
          if s1C <> '' then begin
            //商品编号 赠送人 留言
            i := 1;
            sData := GetToken(s1C, #0, i);
            sData := GetToken(s1C, #0, i);
            sTmp := GetToken(s1C, #0, i);
            if Pos(#0, s1C) > 0 then Delete(s1C, Pos(#0, s1C), Length(s1C));
            if ProcessMsg.nParam2 = $0105 then                                                      //传世商城
            UserEngine.BuyWolShopItem(Self, sData, s1C, sTmp, boBindGameGold, False)
            else                                                                                    //普通商品
            UserEngine.BuyWolShopItem(Self, sData, s1C, sTmp, boBindGameGold, True);
{$IF USESDK = DEBUG}
            MainOutMessage(Format('商城购买信息:%s-%s-%s', ));
{$IFEND}
          end;
      end else if (ProcessMsg.nParam2 = 6) then begin
          ExecuteScript(g_ManageNPC, '@OpenWolShop' + IntToStr(ProcessMsg.wParam))
      end
      else begin
{$IF CHECKNEWMSG = 1}
          MainOutMessage(Format('未知商城消息:%d-%d-%d-%d-%d %s',
            [ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
            ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg]));
{$IFEND}
      end;
      end;
    CM_BAGORDER: begin                                                                              //人物下线之前保存的数据
      ClientSetBagOrder(ProcessMsg.wParam, ProcessMsg.sMsg);
      end;
    CM_OPENPETBAG: begin
      if not m_boBagSend then
          SendDelayMsg(Self, CM_QUERYBAGITEMS, 0, 0, 0, 0, '', 1000);
      m_defMsg := MakeDefaultMsg(SM_9600, DateTimeToWolTIme(Date + Time), 0, 0, 0);
      SendSocket(@m_defMsg, '');
      end;
    CM_MOVEITEMTOPETBAG: begin
      ClientStorageItemToPetBag(ProcessMsg.nParam1);
      end;
    CM_MOVEITMETOBAG: begin
      ClientTakebackPetItem(ProcessMsg.nParam1);
      end;
    CM_DOSHOP: begin                                                                              //摆摊
      ClientDoShop(ProcessMsg.nParam2, ProcessMsg.sMsg);
      end;

    CM_REQUESTDOSHOP: begin
{$IF USESDK = DEBUG}
      MainOutMessage(Format('摆摊消息 %d-%d-%d-%d-%d %s',
          [ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg]));
{$IFEND}
      if m_boRideOn or m_PEnvir.m_MapFlag.boNoDoShop or m_boArrow then
          SysMsg(sHint2, c_Red, t_Hint)
      else begin
          case ProcessMsg.nParam2 of
            0: begin
                ClientPetStopDoShop();                                                            //停止摆摊
            end;
            2: begin                                                                              //取卖物所得
                ClientGetbackPetMoney();
            end;
            3: begin                                                                              //取摆摊物品
                if (m_Pet <> nil) then ClientGetbackPetShopItem();
            end;
            5: begin
                ClientRequestPetDoShop();                                                         //请求摆摊
            end;
            7: begin
                if (m_PackPet <> nil) then
                  SendDefMessage(34979,
                  0,
                  1,
                  0,
                  0,
                  Format('你的宠物豹在%s(%d:%d)为你守摊。', ))
                else
                  SendDefMessage(34979, 0, 0, 0, 0, '没有守摊的豹子');
            end;
          end;
      end;
      end;
    CM_UPDATESHOPITEM: begin                                                                        //更新宠物摊位
      ClientUpdatePetShop(ProcessMsg.nParam1, ProcessMsg.nParam3,
          ProcessMsg.sMsg);
      end;
    CM_PETDOSHOP: begin                                                                           //24245 豹子摆摊
      ClientPetDoShop(ProcessMsg.nParam1, ProcessMsg.nParam2,
          ProcessMsg.sMsg);
      end;
    RM_DOSHOP: begin
      if (ProcessMsg.BaseObject <> Self) then begin
          m_defMsg := MakeDefaultMsg(SM_USERDOSHOP,
            Integer(ProcessMsg.BaseObject),
            LoWord(ProcessMsg.nParam1),
            HiWord(ProcessMsg.nParam1),
            ProcessMsg.wParam);
          SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
      end;

    RM_PETDOSHOP: begin
      if (ProcessMsg.BaseObject <> Self) then begin
          m_defMsg := MakeDefaultMsg(SM_PETDOSHOP,
            ProcessMsg.nParam3,
            LoWord(ProcessMsg.nParam1),
            HiWord(ProcessMsg.nParam1),
            ProcessMsg.wParam);
          SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
      end;
    RM_SENDSHOPITEMS: begin
      if m_PackPet <> nil then
          m_PackPet.SendShopItems(Self, 1);
      end;
    CM_ADDFRIEND: begin
      ClientAddFriend(ProcessMsg.sMsg);
      end;
    CM_DELFRIEND: begin
      ClientDelFriend(ProcessMsg.sMsg);
      end;
    CM_RESPADDFRIEND: begin
      ClientRespAddFriend(ProcessMsg.nParam1, ProcessMsg.sMsg);
      end;
    $E67B: begin                                                                                    //点彩虹客服MM,触发脚本
      ExecuteScript(g_ManageNPC, '@客服功能');
      end;
    $9707: begin
      SendDefMessage(SM_9708, 0, 256, 0, 0, '');
      //SendDefMessage($FFFF, 0, m_nCurrX, m_nCurrY, 0, '');                                        //未知
      end;
    $0710: begin
      ExecuteScript(g_ManageNPC, '@商城功能_' + IntToStr(ProcessMsg.wParam));
      end;
    3044: ;                                                                                       //未知消息
    1811: begin
      SendDefMessage(SM_MENU_OK, Integer(Self), 0, 0, 0, sHint3);
      end;
    192: begin                                                                                    //黄榜大旗放到旗座上
      MakeFlagOwner(ProcessMsg.wParam, ProcessMsg.nParam1, ProcessMsg.nParam2,
          ProcessMsg.nParam3, ProcessMsg.sMsg);
      end;
    193: begin                                                                                    //Ident 193 Param 1 P1 268831256 P2 1 P3 0 Msg
      ClickQueryMsg(ProcessMsg.nParam1, ProcessMsg.nParam2);
      end;
    654: begin                                                                                    //黄榜大旗留言
      AddFlagComment(ProcessMsg.nParam2, ProcessMsg.nParam1,
          ProcessMsg.nParam3, ProcessMsg.sMsg);
      end;
    CM_TREASURE: begin
{$IF USESDK = DEBUG}
      MainOutMessage('祈愿树(宝箱):' + Format('%d-%d-%d-%d-%d-%d %s',
          [Integer(ProcessMsg.BaseObject), ProcessMsg.wIdent, ProcessMsg.wParam,
          ProcessMsg.nParam1,
            ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg]));
{$IFEND}
      GetTreasureBoxItem(ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg);
      end;
    RM_TREASURE: begin
      m_defMsg := MakeDefaultMsg(SM_627, Integer(ProcessMsg.BaseObject),
          ProcessMsg.wParam, ProcessMsg.nParam1, 0);
      SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
    RM_SENDFRIENDLIST: begin
      //好友的处理:装载并发送好友列表
      SendFiendList;
      //发送在线状态
      SendMeOnlineState(1);
      end;
    CM_QUERYUSERNAME: begin                                                                         //80查询玩家名称
      ClientQueryUserName(TBaseObject(ProcessMsg.nParam1), ProcessMsg.nParam2, ProcessMsg.nParam3); //004D7931
      end;
    CM_QUERYBAGITEMS: begin                                                                         //81 查询包裹物品
      ClientQueryBagItems();
      ClientQueryTreasureBoxItems(True);                                                          //灵犀宝盒
      end;
    CM_QUERYUSERSTATE: begin                                                                        //82查询角色状态
      ClientQueryUserState(TPlayObject(ProcessMsg.nParam1), ProcessMsg.nParam2, ProcessMsg.nParam3);
      end;
    CM_QUERYUSERSET: begin                                                                        //物品快捷交易
      ClientQueryUserSet(ProcessMsg);
      end;
    CM_64: begin                                                                                    //上马下马的命令
{$IF USESDK = DEBUG}
      MainOutMessage('骑宠信息:' + Format('%d-%d-%d-%d-%d-%d %s',
          [Integer(ProcessMsg.BaseObject), ProcessMsg.wIdent, ProcessMsg.wParam,
          ProcessMsg.nParam1,
            ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg]));
{$IFEND}
      //1秒内禁止重复上下马
      if (GetTickCount - m_dwLastRide < 500) or (not ClientRide) then
          SendSocket(nil, sSTATUS_GOOD + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
      end;
    CM_DROPITEM: begin                                                                              //1000丢掉物品
      if ClientDropItem(ProcessMsg.sMsg, ProcessMsg.nParam1) then
          SendDefMessage(SM_DROPITEM_SUCCESS, ProcessMsg.nParam1, 0, 0, 0,
            ProcessMsg.sMsg)
      else
          SendDefMessage(SM_DROPITEM_FAIL, ProcessMsg.nParam1, 0, 0, 0,
            ProcessMsg.sMsg);
      end;
    CM_PICKUP: begin                                                                              //1001004D78F9   捡物品
      if (m_nCurrX = ProcessMsg.nParam2) and (m_nCurrY = ProcessMsg.nParam3) then
          ClientPickUpItem(ProcessMsg.nParam2, ProcessMsg.nParam3, 0);
      end;
    CM_PETPICKUP: begin                                                                           //1001004D78F9   宠物豹捡物品
      if (m_Pet <> nil) and (not m_Pet.m_boGhost) and (not m_Pet.m_boDeath)
          and (not m_Pet.m_boDealOK) and (not m_Pet.IsShop) then
          PetPickUpItem(ProcessMsg.nParam2, ProcessMsg.nParam3);
      end;
    CM_OPENDOOR: begin                                                                              //1002    开门
      ClientOpenDoor(ProcessMsg.nParam2, ProcessMsg.nParam3);
      end;
    CM_TAKEONITEM: begin                                                                            //1003戴上装备
      ClientTakeOnItems(ProcessMsg.nParam2, ProcessMsg.nParam1, ProcessMsg.sMsg, False);
      end;
    CM_TAKEOFFITEM: begin                                                                           //1004 取下装备
      ClientTakeOffItems(ProcessMsg.nParam2, ProcessMsg.nParam1, ProcessMsg.sMsg);
      end;
    CM_TAKEENTOPTICITEM: begin                                                                      //装备元神内视装备,魂骨
      case LoByte(ProcessMsg.nParam2) of
          0: ClientTakeOnEntopticItems(HiByte(ProcessMsg.nParam2), ProcessMsg.nParam1);
          1: ClientTakeOffEntopticItems(HiByte(ProcessMsg.nParam2), ProcessMsg.nParam1);
          2: ClientEntopticSmelt(HiByte(ProcessMsg.nParam2), ProcessMsg.sMsg);
      end;
      end;
    CM_ILLUMEHEARTFATEPOINT: begin
      ClientIllumeHeartPoint(LoByte(ProcessMsg.nParam3) - 1, HiByte(ProcessMsg.nParam3));
      end;

    CM_EAT: begin                                                                                 //1006       吃药、学技能
      ClientUseItems(ProcessMsg.nParam1, ProcessMsg.sMsg, MakeLong(ProcessMsg.nParam2, ProcessMsg.nParam3));
      end;
    CM_BUTCH: begin                                                                                 //1007   挖肉
      if not ClientGetButchItem(TBaseObject(ProcessMsg.nParam1),
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.wParam, dwDelayTime) then begin
          if (not g_Config.boDisableM2SpeedCtrl) then begin
            if dwDelayTime <> 0 then begin
            nMsgCount := GetDigUpMsgCount();
            if nMsgCount >= g_Config.nMaxDigUpMsgCount then begin
                Inc(m_nOverSpeedCount);
                if m_nOverSpeedCount > g_Config.nOverSpeedKickCount then begin
                  if g_Config.boKickOverSpeed then begin
                  SysMsg(g_sKickClientUserMsg {'请勿使用非法软件!!!'}, c_Red, t_Hint);
                  m_boEmergencyClose := True;
                  end;
                  if g_Config.boViewHackMessage then begin
                  MainOutMessage(Format(g_sBunOverSpeed, ));
                  end;
                end;
                //如果超速则发送攻击失败信息
                SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));      //-----------传世行走失败
            end else begin
                if dwDelayTime < g_Config.dwDropOverSpeed then begin
                  if m_boTestSpeedMode then
                  SysMsg(Format('速度异常 Ident: %d Time: %d', ), c_Red, t_Hint);
                  SendSocket(nil, sSTATUS_GOOD + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
                end else begin
                  SendDelayMsg(Self, ProcessMsg.wIdent, ProcessMsg.wParam,
                  ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.nParam3, '', dwDelayTime);
                  Result := False;
                end;
            end;
            end;
          end;                                                                                    // else
          //SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
      end;
      end;
    CM_MAGICKEYCHANGE: begin                                                                        //1008设置魔法快捷键
      ClientChangeMagicKey(ProcessMsg.nParam1, ProcessMsg.nParam2);
      end;
    CM_SOFTCLOSE: begin                                                                           //小退
      //if not m_boOfflineGetGamePoint then begin
      m_boReconnection := True;
      m_boSoftClose := True;
      //end;
      end;
    CM_106: begin                                                                                 //大退
      if (g_Config.boEnableOffLinePlayer or m_boSafeZoneOnLine) and not m_boDeath and not m_boGhost and InSafeZone then begin
          m_boOfflineGetGamePoint := True;
          m_sAutoSayMsg := g_sOffLineMsg;
          m_boSuperMan := g_Config.boOffLineSuperMode;
          m_boAllowDeal := False;                                                                   //禁止交易
          m_boAllowGuild := False;                                                                  //禁止加入行会
          m_boAllowGroup := False;                                                                  //禁止组队
          m_boCanMasterRecall := False;                                                             //禁止师徒传送
          m_boCanDearRecall := False;                                                               //禁止夫妻传送
          m_boAllowGuildReCall := False;                                                            //禁止行会合一
          m_boAllowGroupReCall := False;                                                            //禁止天地合一
          m_wStatusTimeArr := 0;
          m_wStatusTimeArr := 0;
          m_wStatusTimeArr := 0;
          m_wStatusTimeArr := 0;
          m_wStatusTimeArr := 0;
          m_boAbilMag70Defence := False;
          m_boAbilMagHuShenDefence := False;
          m_boAbilMagJingangDefence := False;
          m_boAbilMagBubbleDefence := False;
          //清除宝宝
          for i := 0 to m_SlaveList.Count - 1 do begin
            TBaseObject(m_SlaveList.Items).MakeGhost();
          end;
          m_SlaveList.Clear;
      end;
      //if m_boOfflineGetGamePoint then m_boSoftClose := False;
      end;
    CM_CLICKNPC: begin                                                                              //1010      点NPC
      ClientClickNPC(ProcessMsg.nParam1);
      end;
    CM_MERCHANTDLGSELECT:                                                                           //1011      商品列表选择
      ClientMerchantDlgSelect(ProcessMsg.nParam1, Trim(ProcessMsg.sMsg), ProcessMsg.nParam2);
    CM_MERCHANTQUERYSELLPRICE:                                                                      //1012 询价
      ClientMerchantQuerySellPrice(ProcessMsg.nParam1,
      MakeLong(ProcessMsg.nParam2, ProcessMsg.nParam3), ProcessMsg.sMsg);
    CM_USERSELLITEM:                                                                              //1013      卖东西
      ClientUserSellItem(ProcessMsg.nParam1, MakeLong(ProcessMsg.nParam2, ProcessMsg.nParam3), ProcessMsg.sMsg);
    CM_USERBUYITEM:                                                                                 //1014004D7AD4   买东西
      ClientUserBuyItem(ProcessMsg.wIdent, ProcessMsg.nParam1, MakeLong(ProcessMsg.nParam2, ProcessMsg.nParam3), ProcessMsg.wParam, ProcessMsg.sMsg);
    CM_USERGETDETAILITEM:                                                                           //1015 004D7AB6       //取商品列表
      ClientUserBuyItem(ProcessMsg.wIdent, ProcessMsg.nParam1, 0, ProcessMsg.wParam, ProcessMsg.sMsg);
    CM_DROPGOLD: begin                                                                              //1016004D7AFC       丢掉金币
      if ProcessMsg.nParam1 > 0 then ClientDropGold(ProcessMsg.nParam1);
      end;
    CM_1017: SendDefMessage(1, 0, 0, 0, 0, '');

    CM_GROUPMODE: begin                                                                           //1019      //改变组队模式
      if ProcessMsg.nParam2 = 0 then ClientGropuClose()
      else m_boAllowGroup := True;
      if m_boAllowGroup then
          SendDefMessage(SM_GROUPMODECHANGED, 0, 1, 0, 0, '')
      else SendDefMessage(SM_GROUPMODECHANGED, 0, 0, 0, 0, '');
      end;
    CM_CREATEGROUP: begin                                                                           //1020      //创建组队
      ClientCreateGroup(Trim(ProcessMsg.sMsg));
      end;
    CM_ADDGROUPMEMBER: begin                                                                        //1021   //增加队伍成员
      ClientAddGroupMember(Trim(ProcessMsg.sMsg));
      end;
    CM_DELGROUPMEMBER: begin                                                                        //1022   //删除队伍成员
      ClientDelGroupMember(Trim(ProcessMsg.sMsg));
      end;
    CM_USERREPAIRITEM: begin                                                                        //1023   //修理物品
      ClientRepairItem(ProcessMsg.nParam1, MakeLong(ProcessMsg.nParam2,
          ProcessMsg.nParam3), ProcessMsg.wParam, ProcessMsg.sMsg);
      end;
    CM_MERCHANTQUERYREPAIRCOST: begin                                                               //1024   //询问修理价格
      ClientQueryRepairCost(ProcessMsg.nParam1, MakeLong(ProcessMsg.nParam2,
          ProcessMsg.nParam3), ProcessMsg.wParam, ProcessMsg.sMsg);
      end;
    CM_DEALTRY: begin                                                                               //1025
      ClientDealTry(Trim(ProcessMsg.sMsg));                                                       //交易尝试
      end;
    CM_DEALADDITEM: begin                                                                           //1026                  添加交易物品
      ClientAddDealItem(ProcessMsg.nParam1, ProcessMsg.sMsg);
      end;
    CM_DEALDELITEM: begin                                                                           //1027               //删除交易物品
      ClientDelDealItem(ProcessMsg.nParam1, ProcessMsg.sMsg);
      end;
    CM_DEALCANCEL: begin                                                                            //1028                  //取消交易
      ClientCancelDeal();
      end;
    CM_DEALCHGGOLD: begin                                                                           //1029               //改变交易价格
      if ProcessMsg.nParam2 = 0 then
          ClientChangeDealGold(ProcessMsg.nParam1, 0)
      else if ProcessMsg.nParam2 = 1 then
          ClientChangeDealGold(0, ProcessMsg.nParam1);
      end;
    CM_DEALEND: begin                                                                               //1030                     //交易完成
      ClientDealEnd();
      end;
    CM_USERSTORAGEITEM: begin                                                                     //保存物品到仓库取回物品
      ClientStorageItem(TObject(ProcessMsg.nParam1),
          MakeLong(ProcessMsg.nParam2, ProcessMsg.nParam3), ProcessMsg.wParam = 1,
          ProcessMsg.sMsg);
      end;
    CM_USERTAKEBACKSTORAGEITEM: begin                                                               //1032   //从仓库取回物品
      ClientTakeBackStorageItem(TObject(ProcessMsg.nParam1),
          MakeLong(ProcessMsg.nParam2, ProcessMsg.nParam3), ProcessMsg.wParam = 1,
          ProcessMsg.sMsg);
      end;
    CM_WANTMINIMAP: begin                                                                           //1033               //需要小地图
      ClientGetMinMap();
      end;
    CM_USERMAKEDRUGITEM: begin                                                                      //1034            //炼药
      ClientMakeDrugItem(TObject(ProcessMsg.nParam1), ProcessMsg.sMsg);
      end;
    CM_OPENGUILDDLG: begin                                                                        //1035                //打开行会窗口
      ClientOpenGuildDlg();
      end;
    CM_GUILDHOME: begin                                                                           //1036                   //行会首页
      ClientGuildHome();
      end;
    CM_GUILDMEMBERLIST: begin                                                                     //行会成员列表
      ClientGuildMemberList();
      end;
    CM_GUILDADDMEMBER: begin                                                                        //添加行会成员
      ClientGuildAddMember(ProcessMsg.sMsg);
      end;
    CM_GUILDDELMEMBER: begin                                                                        //删除行会成员
      ClientGuildDelMember(ProcessMsg.sMsg);
      end;
    CM_GUILDUPDATENOTICE: begin                                                                     //行会公告修改
      ClientGuildUpdateNotice(ProcessMsg.sMsg);
      end;
    CM_GUILDUPDATERANKINFO: begin                                                                   //1041         //行会职位修改
      ClientGuildUpdateRankInfo(ProcessMsg.sMsg);
      end;
    CM_GUILDEXP: begin
      if m_MyGuild <> nil then begin
          SendDefMessage(717, 0, TGuild(m_MyGuild).Count, 0, 0, TGuild(m_MyGuild).GuildsMsg(m_GuildExp));
      end;
      end;
//    CM_ADJUST_BONUS: begin                                                                        //调整技能点数
//      ClientAdjustBonus(ProcessMsg.nParam1, ProcessMsg.sMsg);
//      end;
    CM_DECOMPOSE: begin
      ClientDECOMPOSE(ProcessMsg.nParam2, ProcessMsg.nParam1);
      end;
    CM_GEMREMOVE: begin                                                                           //拆除原石
      ClientGEMREMOVE(ProcessMsg.nParam2, ProcessMsg.nParam1);
      //1044-0-39440184-2-0
{$IF USESDK = DEBUG}
      MainOutMessage(Format('%d-%d-%d-%d-%d %s',
          [ProcessMsg.wIdent, ProcessMsg.wParam,
          ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg]));
{$IFEND}
      end;
    //    CM_GUILDALLY: begin                                                                           //1044                  //行会联盟
    //      ClientGuildAlly();
    //      end;
    CM_YIWANGDAN: begin                                                                           //1045   //遗忘丹
      ClientYIWANGDAN(ProcessMsg.nParam1, DeCodeString(ProcessMsg.sMsg));
      end;
    CM_TURN: begin                                                                                  //3010    004D73DD            //人物转身(出现)
      if ClientChangeDir(ProcessMsg.wIdent, ProcessMsg.nParam1 {x},
          ProcessMsg.nParam2 {y}, ProcessMsg.wParam {dir}, dwDelayTime) then begin
          m_dwActionTick := GetTickCount;

          SendSocket(nil, sSTATUS_GOOD + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
      end else begin
          if (not g_Config.boDisableM2SpeedCtrl) then begin
            if dwDelayTime = 0 then begin
            SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
            end else begin
            nMsgCount := GetTurnMsgCount();
            if nMsgCount >= g_Config.nMaxTurnMsgCount then begin
                Inc(m_nOverSpeedCount);
                if m_nOverSpeedCount > g_Config.nOverSpeedKickCount then begin
                  if g_Config.boKickOverSpeed then begin
                  SysMsg(g_sKickClientUserMsg, c_Red, t_Hint);
                  m_boEmergencyClose := True;
                  end;
                  if g_Config.boViewHackMessage then begin
                  MainOutMessage(Format(g_sBunOverSpeed, ));
                  end;
                end;
                //如果超速则发送攻击失败信息
                SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
            end else begin
                if dwDelayTime < g_Config.dwDropOverSpeed then begin
                  SendSocket(nil, sSTATUS_GOOD + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
                  if m_boTestSpeedMode then
                  SysMsg(Format(sSpeedExcept, ), c_Red, t_Hint);
                end else begin
                  SendDelayMsg(Self, ProcessMsg.wIdent, ProcessMsg.wParam,
                  ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.nParam3, '', dwDelayTime);
                  Result := False;
                end;
            end;
            end;
          end else
            SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
      end;
      end;
    CM_STOP: begin                                                                                  //3020 在走 动作结束时接收到
      //SendUpdateMsg(Self, 65535, 0, m_nCurrX, m_nCurrY, 0, '');
      SendSocket(nil, sSTATUS_GOOD + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrX));
      SendRefMsg(SM_204, 0, 0, 0, 0, '');
      end;
    SM_204: begin
      if ProcessMsg.BaseObject <> Self then
          SendDefMessage(SM_204, Integer(ProcessMsg.BaseObject), 0, 0, 0, '');
      end;
    CM_3021: begin                                                                                  //作揖动作
      SendRefMsg(RM_3021, m_btDirection, m_nCurrX, m_nCurrY, 0, '');
      end;
    RM_3021: begin
      if ProcessMsg.BaseObject <> Self then
          SendDefMessage(SM_3021, Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.wParam, '');
      end;
    (*
    CM_HORSERUN: begin                                                                              //3009         //骑马走
      if ClientHorseRunXY(ProcessMsg.wIdent, ProcessMsg.nParam1 {x},
          ProcessMsg.nParam2 {y}, ProcessMsg.boLateDelivery, dwDelayTime) then begin
          m_dwActionTick := GetTickCount;
          SendSocket(nil, sSTATUS_GOOD + IntToStr(ProcessMsg.nParam1) + '/' + IntToStr(ProcessMsg.nParam2));
      end else begin
          if (not g_Config.boDisableM2SpeedCtrl) then begin
            if dwDelayTime = 0 then begin
            SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
            end else begin
            nMsgCount := GetRunMsgCount();
            if nMsgCount >= g_Config.nMaxRunMsgCount then begin
                Inc(m_nOverSpeedCount);
                if m_nOverSpeedCount > g_Config.nOverSpeedKickCount then begin
                  if g_Config.boKickOverSpeed then begin
                  SysMsg(g_sKickClientUserMsg {'请勿使用非法软件!!!'}, c_Red, t_Hint);
                  m_boEmergencyClose := True;
                  end;
                  if g_Config.boViewHackMessage then
                  MainOutMessage(Format(g_sRunOverSpeed, ));
                end;
                //如果超速则发送攻击失败信息
                SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
                if m_boTestSpeedMode then
                  SysMsg(Format(sSpeedExcept, ), c_Red, t_Hint);
            end else begin
                if m_boTestSpeedMode then
                  SysMsg(Format(sOpDelay, ), c_Red, t_Hint);
                SendDelayMsg(Self, ProcessMsg.wIdent, ProcessMsg.wParam,
                  ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.nParam3, '', dwDelayTime);
                Result := False;
            end;
            end;
          end else
            SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
      end;
      end;
    *)
    CM_SITDOWN: begin                                                                               //3012
      if ClientSitDownHit(ProcessMsg.nParam1, ProcessMsg.nParam2,
          ProcessMsg.wParam, dwDelayTime) then begin
          m_dwActionTick := GetTickCount();

          SendSocket(nil, sSTATUS_GOOD + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
      end else begin
          if (not g_Config.boDisableM2SpeedCtrl) then begin
            if dwDelayTime = 0 then begin
            SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
            end else begin
            nMsgCount := GetSiteDownMsgCount();
            if nMsgCount >= g_Config.nMaxSitDonwMsgCount then begin
                Inc(m_nOverSpeedCount);
                if m_nOverSpeedCount > g_Config.nOverSpeedKickCount then begin
                  if g_Config.boKickOverSpeed then begin
                  SysMsg(g_sKickClientUserMsg {'请勿使用非法软件!!!'}, c_Red, t_Hint);
                  m_boEmergencyClose := True;
                  end;
                  if g_Config.boViewHackMessage then
                  MainOutMessage(Format(g_sBunOverSpeed, ));
                end;
                //如果超速则发送攻击失败信息
                SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
            end else begin
                if dwDelayTime < g_Config.dwDropOverSpeed then begin
                  SendSocket(nil, sSTATUS_GOOD + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
                  if m_boTestSpeedMode then
                  SysMsg(Format(sSpeedExcept, ), c_Red, t_Hint);
                end else begin
                  if m_boTestSpeedMode then
                  SysMsg(Format(sOpDelay, ), c_Red, t_Hint);
                  SendDelayMsg(Self, ProcessMsg.wIdent, ProcessMsg.wParam,
                  ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.nParam3, '', dwDelayTime);
                  Result := False;
                end;
            end;
            end;
          end else
            SendSocket(nil, sSTATUS_FAIL + IntToStr(m_nCurrX) + '/' + IntToStr(m_nCurrY));
      end;
      end;
    RM_170: begin                                                                                 //化身蝙蝠
      m_defMsg := MakeDefaultMsg(SM_170, Integer(ProcessMsg.BaseObject),
          ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.wParam);
      SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
    CM_SAY: begin                                                                                 //3030         //说
      if ProcessMsg.sMsg <> '' then begin
          ProcessUserLineMsg(ProcessMsg.sMsg, ProcessMsg.wParam);
      end;
      end;
    CM_PASSWORD: begin                                                                              //仓库密码
      ProcessClientPassword(ProcessMsg);
      end;
    RM_HORSERUN: begin                                                                              //10003 004D860A   //骑马跑
      if TBaseObject(ProcessMsg.BaseObject) <> Self then begin
          m_defMsg := MakeDefaultMsg(SM_HORSERUN,
            Integer(ProcessMsg.BaseObject), ProcessMsg.nParam1,
            ProcessMsg.nParam2, MakeWord(ProcessMsg.wParam,
            TBaseObject(ProcessMsg.BaseObject).m_nLight));
          CharDescEx.Feature := TBaseObject(ProcessMsg.BaseObject).GetFeature(Self);
          CharDescEx.Status := TBaseObject(ProcessMsg.BaseObject).m_nCharStatus;
          CharDescEx.Featurex := GetMaxHPCent(TBaseObject(ProcessMsg.BaseObject));
          s1C := EnCodeBuffer(@CharDescEx, SizeOf(CharDescEx));
          nObjCount := GetCharColor(TBaseObject(ProcessMsg.BaseObject));
          if ProcessMsg.sMsg <> '' then
            s1C := s1C + (EnCodeString(ProcessMsg.sMsg + '/' +
            IntToStr(nObjCount)));
          SendSocket(@m_defMsg, s1C);
      end;
      end;
    RM_HEAVYHIT: begin                                                                              //004D88CD      //烈火
      if TBaseObject(ProcessMsg.BaseObject) <> Self then begin
          m_defMsg := MakeDefaultMsg(SM_HEAVYHIT,
            Integer(ProcessMsg.BaseObject), ProcessMsg.nParam1,
            ProcessMsg.nParam2, ProcessMsg.wParam);
          SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
      end;
    RM_BIGHIT: begin                                                                              //004D893A         //半月
      if TBaseObject(ProcessMsg.BaseObject) <> Self then begin
          m_defMsg := MakeDefaultMsg(SM_BIGHIT, Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.wParam);
          SendSocket(@m_defMsg, '');
      end;
      end;
    RM_POWERHIT: begin
      //      //if TBaseObject(ProcessMsg.BaseObject) <> Self then begin
      m_defMsg := MakeDefaultMsg(SM_POWERHIT,
          Integer(ProcessMsg.BaseObject),
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          ProcessMsg.wParam);
      SendSocket(@m_defMsg, ProcessMsg.sMsg);
      //      //end;
      end;
    $1213: begin                                                                                    //打开输入对话框
      m_defMsg := MakeDefaultMsg($1213, Integer(ProcessMsg.BaseObject),
          ProcessMsg.wParam, 0, 0);
      SendSocket(@m_defMsg, EnCodeString(ProcessMsg.sMsg));
      end;
    $6891: begin                                                                                    //客户端输入数据保存和执行下一步代码
      ClientInput(ProcessMsg.nParam1, DeCodeString(ProcessMsg.sMsg));
      end;
    197: begin                                                                                    //刻回城石 197 Param 0 P1 1073750219 P2 512 P3 0 Msg
      RecordHomeXY(ProcessMsg.nParam1, HiByte(ProcessMsg.nParam2));
      end;
    1289: begin
      RecordHomeXY(ProcessMsg.nParam1, ProcessMsg.sMsg);                                          //完美回城仙石
      end;
    1300: begin
      ClientPerfectStoreMoveHome(ProcessMsg.nParam1, ProcessMsg.nParam2);
      end;
    $8810: begin                                                                                    //刻回城石、存放宝石 确认等
      ClientNamedStore(ProcessMsg.nParam1, MakeLong(ProcessMsg.nParam2, ProcessMsg.nParam3));
      end;
    $8850: begin                                                                                    //弹出刻回城石的对话框
      m_defMsg := MakeDefaultMsg($8850, 0, 0, 0, 0);
      SendSocket(@m_defMsg, EnCodeString(ProcessMsg.sMsg));
      end;
    $00C6: begin                                                                                    // 198 弹出拆分圣灵精华的对话框
{$IF USESDK = DEBUG}
      MainOutMessage(Format('%d-%d-%d-%d-%d-%d %s',
          [Integer(ProcessMsg.BaseObject),
          ProcessMsg.wIdent,
            ProcessMsg.wParam,
            ProcessMsg.nParam1,
            ProcessMsg.nParam2,
            ProcessMsg.nParam3,
            ProcessMsg.sMsg]));
{$IFEND}
      //2014/7/23 18:23:52 220118016-198-0-14350832-2-0
      if ProcessMsg.wParam = 0 then begin
          if (ProcessMsg.nParam1 < 100) then begin
            m_defMsg := MakeDefaultMsg($00C6,
            Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1,
            ProcessMsg.nParam2,
            ProcessMsg.wParam);
            SendSocket(@m_defMsg, '');
          end else
            ClientSplitItem(ProcessMsg.nParam1, ProcessMsg.nParam2, False);
      end else
          ClientSplitItem(ProcessMsg.nParam1, ProcessMsg.nParam2, True);
      end;
    CM_QUERYSLAVER: begin                                                                           //查看宝宝属性
      ClientQuerySlaverState;
      end;
    $9590: begin                                                                                    //刻石头结果
      m_defMsg := MakeDefaultMsg($9590, ProcessMsg.wParam, ProcessMsg.nParam1, 0, 0);
      SendSocket(@m_defMsg, EnCodeString(ProcessMsg.sMsg));
      end;
    CM_GEMCOUNT: begin
      ClientQueryBaoshi;
      end;
    CM_PETEQUIPUP: begin
      ClientPetEquipUp(ProcessMsg.nParam1, MakeLong(ProcessMsg.nParam3, ProcessMsg.wParam), ProcessMsg.sMsg);
      end;
    CM_GEMCONDENSE: begin                                                                           //宝石凝练    <我要凝炼宝石/@@gemcondense>
      ClientGemItems(ProcessMsg.nParam1, ProcessMsg.wParam, ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg);
      end;
    CM_ORIGINALSTONE: begin
      ClientOriginalStoneSmelt(ProcessMsg.nParam1, ProcessMsg.wParam, ProcessMsg.nParam2, ProcessMsg.sMsg);
      end;
    CM_GEMSMELT: begin
      ClientGemSmelt(ProcessMsg.wParam, LoByte(ProcessMsg.nParam2), HiByte(ProcessMsg.nParam2), ProcessMsg.nParam3, ProcessMsg.sMsg);
      end;
    CM_REFINE: begin
      ClientRefineItems(ProcessMsg.nParam2, ProcessMsg.nParam1, MakeLong(ProcessMsg.nParam3, ProcessMsg.wParam), ProcessMsg.sMsg);
      end;
    CM_FUSEEQUIP: begin
      ClientfuseequipItem(ProcessMsg.nParam2, ProcessMsg.nParam1, MakeLong(ProcessMsg.nParam3, ProcessMsg.wParam), ProcessMsg.sMsg);
      end;
    CM_SENDBLESS: begin
      ClientSendBlessMsg(ProcessMsg.nParam1, ProcessMsg.nParam3, DeCodeString(ProcessMsg.sMsg));
      end;
    RM_MOVEFAIL: begin                                                                              //移动失败
      m_defMsg := MakeDefaultMsg(SM_MOVEFAIL, Integer(Self), m_nCurrX, m_nCurrY, m_btDirection);
      CharDescEx.Feature := TBaseObject(ProcessMsg.BaseObject).GetFeature(Self);
      CharDescEx.Status := TBaseObject(ProcessMsg.BaseObject).m_nCharStatus;
      CharDescEx.Featurex := GetMaxHPCent(TBaseObject(ProcessMsg.BaseObject));
      s1C := EnCodeBuffer(@CharDescEx, SizeOf(CharDescEx));
      nObjCount := GetCharColor(TBaseObject(ProcessMsg.BaseObject));
      if ProcessMsg.sMsg <> '' then
          s1C := s1C + (EnCodeString(ProcessMsg.sMsg + '/' + IntToStr(nObjCount)));
      SendSocket(@m_defMsg, s1C);
      end;
    RM_LONGHIT: begin
      if TBaseObject(ProcessMsg.BaseObject) <> Self then begin
          m_defMsg := MakeDefaultMsg(SM_LONGHIT, Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.wParam);
          SendSocket(@m_defMsg, '');
      end;
      end;
    RM_WIDEHIT: begin
      if TBaseObject(ProcessMsg.BaseObject) <> Self then begin
          m_defMsg := MakeDefaultMsg(SM_WIDEHIT, Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.wParam);
          SendSocket(@m_defMsg, '');
      end;
      end;
    RM_FIREHIT: begin
      if TBaseObject(ProcessMsg.BaseObject) <> Self then begin
          m_defMsg := MakeDefaultMsg(SM_FIREHIT, Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.wParam);
          SendSocket(@m_defMsg, '');
      end;
      end;
    RM_CRSHIT: begin
      if TBaseObject(ProcessMsg.BaseObject) <> Self then begin
          m_defMsg := MakeDefaultMsg(SM_CRSHIT, Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.wParam);
          SendSocket(@m_defMsg, '');
      end;
      end;

    RM_42: begin
      if TBaseObject(ProcessMsg.BaseObject) <> Self then begin
          m_defMsg := MakeDefaultMsg(SM_42, Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.wParam);
          SendSocket(@m_defMsg, '');
      end;
      end;
    RM_43: begin
      if TBaseObject(ProcessMsg.BaseObject) <> Self then begin
          m_defMsg := MakeDefaultMsg(SM_43, Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.wParam);
          SendSocket(@m_defMsg, '');
      end;
      end;
    RM_60: begin
      if TBaseObject(ProcessMsg.BaseObject) <> Self then begin
          m_defMsg := MakeDefaultMsg(SM_60, Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.wParam);
          SendSocket(@m_defMsg, '');
      end;
      end;
    RM_STRUCK,                                                                                    //有目标被攻击
      RM_STRUCK_MAG,
      RM_STRUCK_NEWMAG1: begin
      if ProcessMsg.nParam1 > 0 then begin
          if (ProcessMsg.BaseObject <> nil) and (TBaseObject(ProcessMsg.BaseObject) = Self) then begin //本人被攻击,处理PK标志等
            if (TBaseObject(ProcessMsg.nParam3) {Attacker} <> nil) then begin
            if TBaseObject(ProcessMsg.nParam3) {Attacker}.m_btRaceServer = RC_PLAYOBJECT then begin //人攻击人
                SetPKFlag(TBaseObject(ProcessMsg.nParam3) {Attacker});
            end;
            SetLastHiter(TBaseObject(ProcessMsg.nParam3) {Attacker});
            end;

            if (g_CastleManager.IsCastleMember(Self) <> nil) and (TBaseObject(ProcessMsg.nParam3) {Attacker} <> nil) then begin
            TBaseObject(ProcessMsg.nParam3) {Attacker}.m_boGuardCanAttack := True;
            TBaseObject(ProcessMsg.nParam3) {Attacker}.m_dwGuardAttackTick := GetTickCount();
            end;

            m_nHealthTick := 0;
            m_nSpellTick := 0;
            Dec(m_nPerHealth);
            Dec(m_nPerSpell);
            m_dwStruckTick := GetTickCount();
          end;
          if ((ProcessMsg.wParam in ) or (g_Config.boDisableStruck)) and (ProcessMsg.wIdent <> RM_STRUCK_NEWMAG1) then begin
            //火雨不发送受伤动做
          end else begin
            SendStruckMsg(ProcessMsg.wIdent,
            TBaseObject(ProcessMsg.BaseObject),
            TBaseObject(ProcessMsg.nParam3),
            ProcessMsg.nParam1,
            ProcessMsg.wParam);
          end;
      end;
      end;
    RM_ASSISTSKILL: if not m_boPneuma then begin
      MagicEffect.nMonID := ProcessMsg.nParam1;
      MagicEffect.nX := LoWord(ProcessMsg.nParam3);
      MagicEffect.nY := HiWord(ProcessMsg.nParam3);
      MagicEffect.nType := ProcessMsg.wParam;

      m_defMsg := MakeDefaultMsg(SM_ASSISTSKILL, Integer(ProcessMsg.BaseObject), 0, 0, ProcessMsg.nParam2);
      SendSocket(@m_defMsg, EnCodeBuffer(@MagicEffect, SizeOf(TMagicEffect)));
      end;
    RM_USEBINDLINGFU: begin
      if not m_boPneuma then begin
          m_defMsg := MakeDefaultMsg(SM_USEBINDLINGFU, Integer(ProcessMsg.BaseObject), ProcessMsg.wParam, ProcessMsg.nParam2, ProcessMsg.nParam3);
          SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
      end;
    RM_25: begin
      if ProcessMsg.BaseObject <> Self then begin
          m_defMsg := MakeDefaultMsg(SM_25,
            Integer(ProcessMsg.BaseObject),
            LoWord(ProcessMsg.nParam1),
            HiWord(ProcessMsg.nParam1),
            ProcessMsg.wParam);
          NewMagicEff.MagicID := ProcessMsg.nParam2;
          NewMagicEff.ChrStatus := ProcessMsg.nParam3;
          SendSocket(@m_defMsg, EnCodeBuffer(@NewMagicEff, SizeOf(TNewMagicEff)));
      end;
      end;
    RM_DEATH: begin                                                                                 //死亡
      CharDescEx.Feature := TBaseObject(ProcessMsg.BaseObject).GetFeature(Self);
      CharDescEx.Status := TBaseObject(ProcessMsg.BaseObject).m_nCharStatus;
      CharDescEx.Featurex := GetMaxHPCent(TBaseObject(ProcessMsg.BaseObject));
      if ProcessMsg.nParam3 = 1 then begin
          m_defMsg := MakeDefaultMsg(SM_NOWDEATH,
            Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1,
            ProcessMsg.nParam2,
            ProcessMsg.wParam);
          CharDescEx.Featurex := 0;

          SendSocket(@m_defMsg, EnCodeBuffer(@CharDescEx, 9));
      end else begin
          m_defMsg := MakeDefaultMsg(SM_DEATH,
            Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1,
            ProcessMsg.nParam2,
            ProcessMsg.wParam);

          s1C := EnCodeBuffer(@CharDescEx, SizeOf(TCharDescEx));

          if ProcessMsg.sMsg <> '' then begin
            nObjCount := GetCharColor(TBaseObject(ProcessMsg.BaseObject));
            sTmp := ProcessMsg.sMsg + '/' + IntToStr(nObjCount) + TBaseObject(ProcessMsg.BaseObject).GetCharTurnMsg;
            s1C := s1C + EnCodeBuffer(@sTmp, Length(sTmp));
          end;
          SendSocket(@m_defMsg, s1C);
      end;
      end;
    RM_DISAPPEAR: begin                                                                           //消失
      m_defMsg := MakeDefaultMsg(SM_DISAPPEAR,
          Integer(ProcessMsg.BaseObject),
          TBaseObject(ProcessMsg.BaseObject).m_nCurrX,
          TBaseObject(ProcessMsg.BaseObject).m_nCurrY,
          TBaseObject(ProcessMsg.BaseObject).m_btDirection);
      SendSocket(@m_defMsg, '');
      end;
    RM_SITDOWN: begin                                                                               //上马下马
      m_defMsg := MakeDefaultMsg(SM_SITDOWN, Integer(ProcessMsg.BaseObject),
          LoWord(ProcessMsg.nParam1),
          HiWord(ProcessMsg.nParam1),
          ProcessMsg.wParam);
      if (ProcessMsg.sMsg <> '') then
          SendSocket(@m_defMsg, ProcessMsg.sMsg)                                                    //支持骑战
      else
          SendSocket(@m_defMsg, EnCodeBuffer(@ProcessMsg.nParam2, 4));
      end;
    RM_205: begin                                                                                 //自己发的消息
      m_defMsg := MakeDefaultMsg(SM_205, ProcessMsg.nParam3, 0, 0, 0);
      SendSocket(@m_defMsg, '');
      end;
    RM_PETBAGITEMS: begin
      SendPetBagItems;
      end;
    RM_SKELETON: begin                                                                              //10024 004D8D7B   //被攻击
      m_defMsg := MakeDefaultMsg(SM_SKELETON,
          Integer(ProcessMsg.BaseObject),
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          ProcessMsg.wParam);
      CharDescEx.Feature := TBaseObject(ProcessMsg.BaseObject).GetFeature(Self);
      CharDescEx.Status := TBaseObject(ProcessMsg.BaseObject).m_nCharStatus;
      CharDescEx.Featurex := GetMaxHPCent(TBaseObject(ProcessMsg.BaseObject));
      s1C := EnCodeBuffer(@CharDescEx, SizeOf(CharDescEx));

      nObjCount := GetCharColor(TBaseObject(ProcessMsg.BaseObject));
      if ProcessMsg.sMsg <> '' then
          s1C := s1C + (EnCodeString(ProcessMsg.sMsg + '/' + IntToStr(nObjCount)));
      SendSocket(@m_defMsg, s1C);
      end;
    RM_USERNAME: begin                                                                              //10043 004D9587   //查询用户名
      m_defMsg := MakeDefaultMsg(SM_USERNAME, Integer(ProcessMsg.BaseObject),
          GetCharColor(TBaseObject(ProcessMsg.BaseObject)), 0, 0);
      SendSocket(@m_defMsg, EnCodeString(ProcessMsg.sMsg));
      end;
    RM_WINEXP: begin                                                                              //10044//获得经验
      m_defMsg := MakeDefaultMsg(SM_WINEXP, Integer(m_Abil.Exp), LoWord(ProcessMsg.nParam1), HiWord(ProcessMsg.nParam1), 0);
      SendSocket(@m_defMsg, ProcessMsg.sMsg);
      if LongWord(ProcessMsg.nParam1) >= 10000 then begin
          RecalcAbilitys();
          SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
      end;
      end;
    RM_LEVELUP: begin                                                                               //10045 004D965B    //等级提升
      i := Integer(Self);
      m_defMsg := MakeDefaultMsg(SM_LEVELUP, m_Abil.Exp, _MIN(m_Abil.level, g_Config.nClientShowLevelLimit), LoWord(i), HiWord(i));
      SendSocket(@m_defMsg, EnCodeBuffer(@m_Abil.Exp, 8));                                        //防止客户端在升级后显示英雄榜
      RecalcAbilitys();
      SendUpdateMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
      SendUpdateMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
      end;
    RM_CHANGENAMECOLOR: begin                                                                     //10046 004D9555//名字颜色改变
      SendDefMessage(SM_CHANGENAMECOLOR,
          Integer(ProcessMsg.BaseObject),
          GetCharColor(TBaseObject(ProcessMsg.BaseObject)),
          0,
          0,
          '');
      end;
    RM_LOGON: begin                                                                                 //10050            //登陆
      if m_PEnvir.m_MapFlag.boDARK then nObjCount := 1
      else begin
          case m_nBright of
            1: nObjCount := 0;
            3: nObjCount := 1;
          else nObjCount := 1;
          end;
      end;
      if m_PEnvir.m_MapFlag.boDAY then nObjCount := 0;
      SendLogon();
      ClientQueryUserName(Self, m_nCurrX, m_nCurrY);
      RefUserState();
      SendMapDescription();
      nObjCount := 1;
      SendDefMessage(SM_VERSION_FAIL, $FFFFFFFFF2D505D7, 0, 0, 0, '');
      end;
    RM_HEAR,
      RM_WHISPER,
      RM_CRY,
      RM_SYSMESSAGE,
      RM_GROUPMESSAGE,
      RM_SYSMESSAGE2,
      RM_GUILDMESSAGE,
      RM_SYSMESSAGE3,
      RM_MERCHANTSAY,
      RM_TITLEMSM,
      RM_CLANMESSAGE,
      RM_COLORTASKSAY:
      begin
      case ProcessMsg.wIdent of
          RM_HEAR: m_defMsg := MakeDefaultMsg(SM_HEAR,
            Integer(ProcessMsg.BaseObject),
            MakeWord(ProcessMsg.nParam1, ProcessMsg.nParam2),
            0,
            ProcessMsg.nParam3);                                                                  //10030
          RM_WHISPER: m_defMsg := MakeDefaultMsg(SM_WHISPER,
            Integer(ProcessMsg.BaseObject),
            MakeWord(ProcessMsg.nParam1, ProcessMsg.nParam2),
            0,
            ProcessMsg.wParam);                                                                   //10031
          RM_CRY: m_defMsg := MakeDefaultMsg(SM_HEAR,
            Integer(ProcessMsg.BaseObject),
            MakeWord(ProcessMsg.nParam1, ProcessMsg.nParam2),
            0,
            1);                                                                                 //10032
          RM_SYSMESSAGE: m_defMsg := MakeDefaultMsg(SM_SYSMESSAGE,
            Integer(ProcessMsg.BaseObject),
            MakeWord(ProcessMsg.nParam1, ProcessMsg.nParam2),
            0,
            1);                                                                                 //10100 红色
          RM_GROUPMESSAGE: m_defMsg := MakeDefaultMsg(SM_SYSMESSAGE,
            Integer(ProcessMsg.BaseObject),
            MakeWord(ProcessMsg.nParam1, ProcessMsg.nParam2),
            0,
            1);                                                                                 //10102
          RM_GUILDMESSAGE: m_defMsg := MakeDefaultMsg(SM_GUILDMESSAGE,
            Integer(ProcessMsg.BaseObject),
            MakeWord(ProcessMsg.nParam1, ProcessMsg.nParam2),
            0,
            1);                                                                                 //10104
          RM_MERCHANTSAY: m_defMsg := MakeDefaultMsg(SM_MERCHANTSAY,
            Integer(ProcessMsg.BaseObject),
            MakeWord(ProcessMsg.nParam1, ProcessMsg.nParam2),
            ProcessMsg.nParam3,
            1);                                                                                 //10126
          RM_TITLEMSM: m_defMsg := MakeDefaultMsg(SM_SYSMESSAGE,
            Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1,
            ProcessMsg.nParam2,
            ProcessMsg.nParam3);
          RM_CLANMESSAGE: m_defMsg := MakeDefaultMsg(SM_CLANMESSAGE,
            1,
            MakeWord(ProcessMsg.nParam1, ProcessMsg.nParam2),
            0,
            0);
          RM_COLORTASKSAY: m_defMsg := MakeDefaultMsg(CM_COLORTASKSAY,
            Integer(ProcessMsg.BaseObject),
            0,
            0,
            ProcessMsg.wParam);
      end;
      if not m_boPneuma or (ProcessMsg.wIdent = RM_SYSMESSAGE) then
          //2006/7/12 防止元神听到说话内容而出现消息重复
          SendSocket(@m_defMsg, EnCodeString(ProcessMsg.sMsg));
      end;
    RM_FLYMSG: if not m_boPneuma then begin
      m_defMsg := MakeDefaultMsg(SM_FLYMSG, 0, ProcessMsg.wParam, 0,
          MakeWord(0, ProcessMsg.nParam1));
      SendSocket(@m_defMsg, EnCodeString(ProcessMsg.sMsg));
      end;
    RM_510: begin
      m_defMsg := MakeDefaultMsg(SM_510, Integer(ProcessMsg.BaseObject),
          ProcessMsg.wParam, ProcessMsg.nParam1, ProcessMsg.nParam2);
      SendSocket(@m_defMsg, EnCodeString(ProcessMsg.sMsg));
      end;
    RM_SENDBAGSIZE: begin
      SendDefMessage(SM_BAGSIZE, Integer(Self), 0, m_nBagSize, 0, '');
      end;
    RM_ABILITY: begin
      ClientQueryAbility();
      end;
    RM_HIDE: begin
      m_defMsg := MakeDefaultMsg(SM_HIDE,
          Integer(ProcessMsg.BaseObject),
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          ProcessMsg.nParam3);
      SendSocket(@m_defMsg, '');
      end;
    RM_DAYCHANGING: begin                                                                           //10053
      m_defMsg := MakeDefaultMsg(SM_DAYCHANGING, $FFFFFFFF, m_nBright,
          m_PEnvir.m_MapFlag.nWeather, m_PEnvir.m_MapFlag.wWindSpeed);
      nObjCount := m_PEnvir.m_MapFlag.dwWindColor;
      SendSocket(@m_defMsg, EnCodeBuffer(@nObjCount, SizeOf(Integer)));
      end;
    RM_FIREBURN: begin
      m_defMsg := MakeDefaultMsg(SM_FireBurn,
          Integer(ProcessMsg.BaseObject),
          LoWord(ProcessMsg.nParam1),
          HiWord(ProcessMsg.nParam1),
          ProcessMsg.wParam);
      SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
    RM_ITEMSHOW: begin
      if pTMapItem(ProcessMsg.nParam1).UserItem.btItemExt > 0 then                            //新增支持掉落物品名字颜色
      begin
          g_SmallPacketManage.Init();
          g_SmallPacketManage.WriteString(ProcessMsg.sMsg, 4);
          g_SmallPacketManage.WriteByte(0);
          g_SmallPacketManage.WriteByte(pTMapItem(ProcessMsg.nParam1).UserItem.btItemExt);
          SendDefMessage(SM_ITEMSHOW,
            ProcessMsg.nParam1,
            ProcessMsg.nParam2,
            ProcessMsg.nParam3,
            ProcessMsg.wParam,
            g_SmallPacketManage.GetMsg, True);
      end else begin
          SendDefMessage(SM_ITEMSHOW,
            ProcessMsg.nParam1,
            ProcessMsg.nParam2,
            ProcessMsg.nParam3,
            ProcessMsg.wParam,
            ProcessMsg.sMsg);
      end;
      UpdateVisibleItem(ProcessMsg.nParam2, ProcessMsg.nParam3, pTMapItem(ProcessMsg.nParam1));
      end;
    RM_ITEMHIDE: begin
      SendDefMessage(SM_ITEMHIDE,
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          ProcessMsg.nParam3,
          0,
          '');
      end;
    RM_DOOROPEN: begin                                                                              //10112 004D9D6A
      SendDefMessage(SM_OPENDOOR_OK,
          0,
          ProcessMsg.nParam1,                                                                     {x}
          ProcessMsg.nParam2,                                                                     {y}
          0,
          '');
      end;
    RM_DOORCLOSE: begin                                                                           //10113 004D9D8A
      SendDefMessage(SM_CLOSEDOOR,
          0,
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          0,
          '');
      end;
    RM_SENDUSEITEMS: begin
      SendUseitems();
      SendEntopticItems;
      SendTigerItem();
      end;
    RM_QUERYPETSOUL: begin
      //检测摆摊灵兽、凤凰探宝、魂佑附体
      CheckPackPetShop();
      ClientQueryPetSoulInfo;                                                                     //发送魂佑灵兽信息
      end;
    CM_QUERYPETSOULITEM: begin
      ClientQueryPetSoulItem(ProcessMsg.nParam1, ProcessMsg.nParam2);
      end;
    RM_WEIGHTCHANGED: begin                                                                         //10115 004D9DC4
      SendDefMessage(SM_WEIGHTCHANGED,
          m_WAbil.Weight,
          m_WAbil.WearWeight,
          m_WAbil.HandWeight,
          0,
          '');
      end;
    RM_FEATURECHANGED: begin                                                                        //10116
      //      if ProcessMsg.BaseObject <> Self then begin
      m_defMsg := MakeDefaultMsg(SM_FEATURECHANGED,
          Integer(ProcessMsg.BaseObject),
          LoWord(ProcessMsg.nParam1),
          HiWord(ProcessMsg.nParam1),
          ProcessMsg.wParam);
      SendSocket(@m_defMsg, ProcessMsg.sMsg);
      //         end;
      end;
    RM_CLEAROBJECTS: begin                                                                        //10117
      SendDefMessage(SM_CLEAROBJECTS,
          0,
          0,
          0,
          0,
          '');
      end;
    RM_CHANGEMAP: begin
      try
          if m_PEnvir = nil then begin
            MainOutMessage(sHint5);
            Exit;
          end;

          SendDefMessage(SM_CHANGEMAP, Integer(Self), m_nCurrX, m_nCurrY, 10240 {m_btDirection}, ProcessMsg.sMsg);

          RefUserState();
          SendMapDescription();
          SendMsg(Self, RM_DAYCHANGING, 0, 0, 0, 0, '');

          if ProcessMsg.wParam = 0 then begin                                                       //过地图,下马
            if not CheckMapRideOn(m_PEnvir) then ClientRideOff;

            if not m_PEnvir.m_MapFlag.boCanReCallEvil then begin                                    //不允许带心魔
            ClearEvilFollower(6);
            end;
            //雪莲过地图失效
            if g_Config.boChMapSaussureaFail then begin
            if m_nSuperIncHealth > 0 then begin
                SendMsg(Self, RM_510, 0, 0, 1, 0, '');
                m_nSuperIncHealth := 0;
            end;
            if m_nSuperIncSpell > 0 then begin
                m_nSuperIncSpell := 0;
                SendMsg(Self, RM_510, 0, 0, 2, 0, '');
            end;
            end;
          end;
          if m_Pet <> nil then begin
            m_Pet.m_nTargetX := -1;
            m_Pet.m_nTargetY := -1;
          end;
          m_nPetTargetX := -1;
          m_nPetTargetY := -1;

      except
      end;
      end;
    RM_BUTCH: begin                                                                                 //10119
      if ProcessMsg.BaseObject <> nil then begin
          m_defMsg := MakeDefaultMsg(SM_BUTCH,
            Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1,
            ProcessMsg.nParam2,
            ProcessMsg.wParam);
          SendSocket(@m_defMsg, '');
      end;

      end;
    RM_MAGICFIRE: begin
      m_defMsg := MakeDefaultMsg(SM_MAGICFIRE,
          Integer(ProcessMsg.BaseObject),
          ProcessMsg.nParam1,                                                                     //x
          ProcessMsg.nParam2,                                                                     //y
          ProcessMsg.wParam);                                                                     //Effect
      SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
    RM_MAGICFIREFAIL: begin                                                                         //10121
      SendDefMessage(SM_MAGICFIRE_FAIL, Integer(ProcessMsg.BaseObject), 0, 0,
          0, '');
      end;
    RM_SENDMYMAGIC: SendUseMagic();                                                               //10122
    RM_MAGIC_LVEXP: begin                                                                           //10123
      SendDefMessage(SM_MAGIC_LVEXP,
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          LoWord(ProcessMsg.nParam3),
          HiWord(ProcessMsg.nParam3),
          '');
      end;
    RM_DURACHANGE: begin                                                                            //10125
      SendDefMessage(SM_DURACHANGE,
          ProcessMsg.nParam1,
          ProcessMsg.wParam,
          LoWord(ProcessMsg.nParam2),
          HiWord(ProcessMsg.nParam2),
          '');
      end;
    RM_MERCHANTDLGCLOSE: begin                                                                      //10127
      if ProcessMsg.wParam = 0 then
          SendDefMessage(SM_MERCHANTDLGCLOSE,
            ProcessMsg.nParam1,
            0,
            0,
            0,
            '')
      else
          SendDefMessage(SM_KAITIANTOWERCLOSE,
            ProcessMsg.nParam1,
            0,
            0,
            0,
            '')
      end;
    RM_SENDGOODSLIST: begin
      if ProcessMsg.nParam3 = 1 then begin
          m_defMsg := MakeDefaultMsg(3039, ProcessMsg.nParam1, ProcessMsg.nParam2, 0, 0);
          SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end else if ProcessMsg.nParam3 = 2 then begin
          m_defMsg := MakeDefaultMsg(3039, ProcessMsg.nParam1, ProcessMsg.nParam2, 5, 0);
          SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end else
          SendDefMessage(SM_SENDGOODSLIST, ProcessMsg.nParam1, ProcessMsg.nParam2, 0, ProcessMsg.wParam, ProcessMsg.sMsg);
      end;
    RM_SENDINGOTGOODSLIST: begin
      SendDefMessage(SM_SENDINGOTGOODSLIST,
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          0,
          0,
          ProcessMsg.sMsg);
      end;
    RM_SENDUSERSELL: begin                                                                        //10129
      SendDefMessage(SM_SENDUSERSELL,
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          0,
          0,
          ProcessMsg.sMsg);
      end;
    RM_SENDBUYPRICE: begin                                                                        //10130004D9BAB
      SendDefMessage(SM_SENDBUYPRICE,
          ProcessMsg.nParam1,
          0,
          0,
          0,
          '');
      end;
    RM_USERSELLITEM_OK: begin                                                                     //10131004D9BC8
      SendDefMessage(SM_USERSELLITEM_OK,
          ProcessMsg.nParam1,
          0,
          0,
          0,
          '');
      end;
    RM_USERSELLITEM_FAIL: begin                                                                     //10132004D9BC8
      SendDefMessage(SM_USERSELLITEM_FAIL,
          ProcessMsg.nParam1,
          0,
          0,
          0,
          '');
      end;
    RM_BUYITEM_SUCCESS: begin                                                                     //10133004D9C02
      SendDefMessage(SM_BUYITEM_SUCCESS,
          ProcessMsg.nParam1,
          LoWord(ProcessMsg.nParam2),
          HiWord(ProcessMsg.nParam2),
          0,
          '');
      end;
    RM_BUYITEM_FAIL: begin                                                                        //10134004D9C2C
      SendDefMessage(SM_BUYITEM_FAIL,
          ProcessMsg.nParam1,
          0,
          0,
          0,
          '');
      end;
    RM_SENDDETAILGOODSLIST: begin                                                                   //10135004D9C83
      m_defMsg := MakeDefaultMsg(SM_SENDDETAILGOODSLIST,
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          ProcessMsg.nParam3,
          ProcessMsg.wParam);
      SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
    RM_GOLDCHANGED: begin                                                                           //10136
      SendDefMessage(SM_GOLDCHANGED,
          ProcessMsg.nParam1,
          ProcessMsg.wParam,
          0,
          0,
          '');
      end;
    RM_GAMEGOLDCHANGED: begin
      SendDefMessage(SM_GAMEGOLDCHANGED,
          ProcessMsg.nParam1,
          ProcessMsg.wParam,
          0,
          0,
          '');
      end;
    RM_GUILDGOLDCHANGED: begin
      SendDefMessage(SM_GUILDGOLDCHANGED,
          ProcessMsg.nParam1,
          0,
          0,
          0,
          '');
      end;
    RM_COLLECTPOINT: begin
      if m_nCollectPoint > 0 then
          SendDefMessage(SM_COLLECTPOINT, m_nCollectPoint, 0, 0, 0, '');
      end;
    RM_LAMPCHANGEDURA: begin                                                                        //10138
      SendDefMessage(SM_LAMPCHANGEDURA,
          ProcessMsg.nParam1,
          0,
          0,
          0,
          '');
      end;
    RM_CHARSTATUSCHANGED: begin
      m_defMsg := MakeDefaultMsg(SM_CHARSTATUSCHANGED,
          Integer(ProcessMsg.BaseObject),
          LoWord(ProcessMsg.nParam1),
          HiWord(ProcessMsg.nParam1),
          ProcessMsg.wParam);
      SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
    RM_FENGHAO: begin                                                                               //是否显示翅膀
      SendDefMessage(SM_FENGHAO,
          Integer(ProcessMsg.BaseObject),
          ProcessMsg.wParam,
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          ProcessMsg.sMsg);
      end;
    RM_GROUPCANCEL: begin                                                                           //10140 004D9F28
      SendDefMessage(SM_GROUPCANCEL,
          ProcessMsg.nParam1,
          0,
          0,
          0,
          '');
      end;
    RM_SENDUSERREPAIR,
      RM_SENDUSERSREPAIR: begin                                                                     //10141 004D9B3C
      SendDefMessage(SM_SENDUSERREPAIR,
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          0,
          0,
          '');
      end;
    RM_USERREPAIRITEM_OK: begin                                                                     //10143004D9CA6
      SendDefMessage(SM_USERREPAIRITEM_OK,
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          ProcessMsg.nParam3,
          0,
          '');
      end;
    RM_SENDREPAIRCOST: begin                                                                        //10142004D9CE4
      if ProcessMsg.wParam <> 0 then
          SendDefMessage(SM_SENDREPAIRCOST,
            ProcessMsg.nParam1,
            10 + ProcessMsg.wParam,
            0,
            0,
            '')
      else
          SendDefMessage(SM_SENDREPAIRCOST,
            ProcessMsg.nParam1,
            0,
            0,
            0,
            '');
      end;
    RM_USERREPAIRITEM_FAIL: begin                                                                   //10144004D9CC7
      SendDefMessage(SM_USERREPAIRITEM_FAIL,
          ProcessMsg.nParam1,
          0,
          0,
          0,
          '');
      end;
    RM_USERSTORAGEITEM: begin                                                                     //10146004D9B5B
      SendDefMessage(SM_SENDUSERSTORAGEITEM,
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          0,
          0,
          '');
      end;
    RM_USERGETBACKITEM: begin                                                                     //10147SM_SAVEITEMLIST
      SendSaveItemList(ProcessMsg.nParam1, ProcessMsg.wParam = 1);
      end;
    RM_SENDDELITEMLIST: begin                                                                     //10148SM_DELITEMS
      SendDelItemList(TStringList(ProcessMsg.nParam1));
      TStringList(ProcessMsg.nParam1).free;
      end;
    RM_USERMAKEDRUGITEMLIST: begin                                                                  //10149
      SendDefMessage(SM_SENDUSERMAKEDRUGITEMLIST,
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          0,
          0,
          ProcessMsg.sMsg);
      end;
    RM_MAKEDRUG_SUCCESS: begin                                                                      //10150 004D9C49
      SendDefMessage(SM_MAKEDRUG_SUCCESS,
          ProcessMsg.nParam1,
          0,
          0,
          0,
          '');
      end;
    RM_MAKEDRUG_FAIL: begin                                                                         //10151 004D9C66
      SendDefMessage(SM_MAKEDRUG_FAIL,
          ProcessMsg.nParam1,
          0,
          0,
          0,
          '');
      end;
    RM_ALIVE: begin                                                                                 //10153 004D8E09
      m_defMsg := MakeDefaultMsg(SM_ALIVE,
          Integer(ProcessMsg.BaseObject),
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          ProcessMsg.wParam);

      CharDescEx.Feature :=
          TBaseObject(ProcessMsg.BaseObject).GetFeature(Self);
      CharDescEx.Status := TBaseObject(ProcessMsg.BaseObject).m_nCharStatus;
      CharDescEx.Featurex := GetMaxHPCent(TBaseObject(ProcessMsg.BaseObject));

      SendSocket(@m_defMsg, EnCodeBuffer(@CharDescEx, SizeOf(TCharDescEx)));
      end;
    RM_DIGUP: begin                                                                                 //10200 004D91B4
      m_defMsg := MakeDefaultMsg(SM_DIGUP,
          Integer(ProcessMsg.BaseObject),
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          MakeWord(ProcessMsg.wParam,
          TBaseObject(ProcessMsg.BaseObject).m_btGender));
      MessageBodyWL.lParam1 := TBaseObject(ProcessMsg.BaseObject).GetFeature(Self);
      MessageBodyWL.lParam2 := TBaseObject(ProcessMsg.BaseObject).m_nCharStatus;
      MessageBodyWL.lTag1 := ProcessMsg.nParam3;
      MessageBodyWL.lTag2 := 0;
      s1C := EnCodeBuffer(@MessageBodyWL, SizeOf(TMessageBodyWL));
      SendSocket(@m_defMsg, s1C);
      end;
    RM_DIGDOWN: begin                                                                               //10201 004D9254
      m_defMsg := MakeDefaultMsg(SM_DIGDOWN,
          Integer(ProcessMsg.BaseObject),
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          0);
      SendSocket(@m_defMsg, '');
      end;
    RM_FLYAXE: begin                                                                              //10202 004D9358
      if TBaseObject(ProcessMsg.nParam3) <> nil then begin
          MessageBodyW.Param1 := TBaseObject(ProcessMsg.nParam3).m_nCurrX;
          MessageBodyW.Param2 := TBaseObject(ProcessMsg.nParam3).m_nCurrY;
          MessageBodyW.Tag1 := LoWord(ProcessMsg.nParam3);
          MessageBodyW.Tag2 := HiWord(ProcessMsg.nParam3);
          m_defMsg := MakeDefaultMsg(SM_FLYAXE,
            Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1,
            ProcessMsg.nParam2,
            ProcessMsg.wParam);
          SendSocket(@m_defMsg, EnCodeBuffer(@MessageBodyW, SizeOf(TMessageBodyW)));
      end;
      end;
    RM_2BDC: begin                                                                                  //魔眼攻击
      if TBaseObject(ProcessMsg.nParam3) <> nil then begin
          m_defMsg := MakeDefaultMsg($2BDC,
            Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1,                                                                     //X
            ProcessMsg.nParam2,                                                                     //Y
            ProcessMsg.wParam);                                                                     //Dir
          nObjCount := ProcessMsg.nParam3;
          SendSocket(@m_defMsg, EnCodeBuffer(@nObjCount, SizeOf(Integer)));
      end;
      end;
    RM_LIGHTING: begin                                                                              //10204 004D93FD
      if TBaseObject(ProcessMsg.nParam3) <> nil then begin
          MessageBodyWL.lParam1 := TBaseObject(ProcessMsg.nParam3).m_nCurrX;
          MessageBodyWL.lParam2 := TBaseObject(ProcessMsg.nParam3).m_nCurrY;
          MessageBodyWL.lTag1 := ProcessMsg.nParam3;
          MessageBodyWL.lTag2 := ProcessMsg.wParam;
          m_defMsg := MakeDefaultMsg(SM_LIGHTING,
            Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1,
            ProcessMsg.nParam2,
            TBaseObject(ProcessMsg.BaseObject).m_btDirection);
          SendSocket(@m_defMsg, EnCodeBuffer(@MessageBodyWL,
            SizeOf(TMessageBodyWL)));
      end;
      end;
    RM_10205: begin                                                                                 //10205 004D949A
      SendDefMessage(SM_716,
          Integer(ProcessMsg.BaseObject),
          ProcessMsg.nParam1 {x},
          ProcessMsg.nParam2 {y},
          ProcessMsg.nParam3 {type},
          '');
      end;
    RM_CHANGEGUILDNAME: begin
      SendChangeGuildName();
      end;
    RM_TAKEON2: begin
      SendDefMessage(SM_TAKEON2, ProcessMsg.nParam1, ProcessMsg.wParam, 0, 0, '');
      end;
    RM_SUBABILITY: begin
      QuerySubAbility();
      end;
    RM_BUILDGUILD_OK: begin                                                                         //10303 004D9F51
      SendDefMessage(SM_BUILDGUILD_OK,
          0,
          0,
          0,
          0,
          '');
      end;
    RM_BUILDGUILD_FAIL: begin                                                                     //10304 004D9F6D
      SendDefMessage(SM_BUILDGUILD_FAIL,
          ProcessMsg.nParam1,
          0,
          0,
          0,
          '');
      end;
    RM_DONATE_OK: begin                                                                           //10305 004D9FA7
      SendDefMessage(SM_DONATE_OK,
          ProcessMsg.nParam1,
          0,
          0,
          0,
          '');
      end;
    RM_DONATE_FAIL: begin                                                                           //10306 004D9F8A
      SendDefMessage(SM_DONATE_FAIL,
          ProcessMsg.nParam1,
          0,
          0,
          0,
          '');
      end;
    RM_MYSTATUS: begin
      SendDefMessage(SM_MYSTATUS, 0, GetMyStatus, 0, 0, '');
      end;
    RM_MENU_OK: begin                                                                               //10309004D9FC4
      SendDefMessage(SM_MENU_OK,
          ProcessMsg.nParam1,
          0,
          0,
          0,
          ProcessMsg.sMsg);
      end;
    RM_SPACEMOVE_FIRE,
      RM_SPACEMOVE_FIRE2: begin                                                                     //10330
      if ProcessMsg.wIdent = RM_SPACEMOVE_FIRE then begin
          m_defMsg := MakeDefaultMsg(SM_SPACEMOVE_HIDE,
            Integer(ProcessMsg.BaseObject),
            0,
            0,
            0);
      end else begin
          m_defMsg := MakeDefaultMsg(SM_SPACEMOVE_HIDE2,
            Integer(ProcessMsg.BaseObject),
            0,
            0,
            0);
      end;
      SendSocket(@m_defMsg, '');
      end;
    RM_SPACEMOVE_SHOW,
      RM_SPACEMOVE_SHOW2: begin
      if ProcessMsg.wIdent = RM_SPACEMOVE_SHOW then begin
          m_defMsg := MakeDefaultMsg(SM_SPACEMOVE_SHOW,
            Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1,
            ProcessMsg.nParam2,
            MakeWord(ProcessMsg.wParam,
            TBaseObject(ProcessMsg.BaseObject).m_btGender));
      end else begin
          m_defMsg := MakeDefaultMsg(SM_SPACEMOVE_SHOW2,
            Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1,
            ProcessMsg.nParam2,
            MakeWord(ProcessMsg.wParam,
            TBaseObject(ProcessMsg.BaseObject).m_btGender));
      end;
      CharDescEx.Feature := TBaseObject(ProcessMsg.BaseObject).GetFeature(Self);
      CharDescEx.Status := TBaseObject(ProcessMsg.BaseObject).m_nCharStatus;
      CharDescEx.Featurex := GetMaxHPCent(TBaseObject(ProcessMsg.BaseObject));

      s1C := EnCodeBuffer(@CharDescEx, SizeOf(TCharDescEx));
      nObjCount := GetCharColor(TBaseObject(ProcessMsg.BaseObject));
      if ProcessMsg.sMsg <> '' then begin
          s1C := s1C + EnCodeString(ProcessMsg.sMsg + '/' +
            IntToStr(nObjCount));
      end;
      SendSocket(@m_defMsg, s1C);
      end;
    RM_RECONNECTION: begin                                                                        //10332
      m_boReconnection := True;
      SendDefMessage(SM_RECONNECT, 0, 0, 0, 0, ProcessMsg.sMsg);
      end;
    RM_HIDEEVENT: begin                                                                           //10333
      SendDefMessage(SM_HIDEEVENT,
          ProcessMsg.nParam1,
          ProcessMsg.wParam,
          ProcessMsg.nParam2,
          ProcessMsg.nParam3,
          '');
      end;
    RM_SHOWEVENT: begin                                                                           //10334
      MessageBodyW.Param1 := HiWord(ProcessMsg.nParam2);
      MessageBodyW.Param2 := 0;
      MessageBodyW.Tag1 := 0;
      MessageBodyW.Tag2 := 0;
      m_defMsg := MakeDefaultMsg(SM_SHOWEVENT,
          ProcessMsg.nParam1,                                                                     //对象ID
          ProcessMsg.wParam,                                                                        //MapEvent.m_nEventType
          LoWord(ProcessMsg.nParam2),                                                               //X
          ProcessMsg.nParam3);                                                                      //Y
      SendSocket(@m_defMsg, EnCodeBuffer(@MessageBodyW,
          SizeOf(TMessageBodyW)));
      end;
    RM_ADJUST_BONUS: begin
      SendAdjustBonus();
      end;
    RM_10401: begin
      ChangeServerMakeSlave(pTSlaveInfo(ProcessMsg.nParam1));
      Dispose(pTSlaveInfo(ProcessMsg.nParam1));
      end;
    RM_FUSHEN: begin
      SendDefMessage(SM_FUSHEN,
          Integer(ProcessMsg.BaseObject),
          HiWord(ProcessMsg.nParam1),
          LoWord(ProcessMsg.nParam1),
          ProcessMsg.wParam,
          '');
      end;
    RM_BREAKWEAPON: begin                                                                           //10413
      SendDefMessage(SM_BREAKWEAPON,
          Integer(ProcessMsg.BaseObject),
          0,
          0,
          0,
          '');
      end;
    RM_INSTANCEHEALGUAGE: begin                                                                     //10414
      if (ProcessMsg.BaseObject = Self) then
          SendDefMessage(SM_INSTANCEHEALGUAGE,
            Integer(ProcessMsg.BaseObject),
            TBaseObject(ProcessMsg.BaseObject).m_WAbil.dwHP,
            TBaseObject(ProcessMsg.BaseObject).m_WAbil.dwMaxHP,
            0,
            '')
      else
          SendDefMessage(SM_INSTANCEHEALGUAGE,
            Integer(ProcessMsg.BaseObject),
            CalcCent(TBaseObject(ProcessMsg.BaseObject).m_WAbil.dwHP,
            TBaseObject(ProcessMsg.BaseObject).m_WAbil.dwMaxHP),
            TBaseObject(ProcessMsg.BaseObject).m_wMaxHPCent,
            0,
            '');

      end;
    RM_CHANGEFACE: begin                                                                            //10415
      if (ProcessMsg.nParam1 <> 0) and (ProcessMsg.nParam2 <> 0) then begin
          m_defMsg := MakeDefaultMsg(SM_CHANGEFACE,
            ProcessMsg.nParam1,
            LoWord(ProcessMsg.nParam2),
            HiWord(ProcessMsg.nParam2),
            0);
          CharDescEx.Feature := TBaseObject(ProcessMsg.nParam2).GetFeature(Self);
          CharDescEx.Status := TBaseObject(ProcessMsg.nParam2).m_nCharStatus;
          CharDescEx.Featurex := GetMaxHPCent(TBaseObject(ProcessMsg.BaseObject));

          SendSocket(@m_defMsg, EnCodeBuffer(@CharDescEx, SizeOf(TCharDescEx)));
      end;
      end;
    RM_PASSWORD: begin                                                                              //10416 004D9FE3
      SendDefMessage(SM_PASSWORD,
          0,
          0,
          0,
          0,
          '');
      end;
    RM_PLAYDICE: begin                                                                              //10500 004D9FFF
      MessageBodyWL.lParam1 := ProcessMsg.nParam1;
      MessageBodyWL.lParam2 := ProcessMsg.nParam2;
      MessageBodyWL.lTag1 := ProcessMsg.nParam3;

      m_defMsg := MakeDefaultMsg(SM_PLAYDICE,
          Integer(ProcessMsg.BaseObject),
          ProcessMsg.wParam,
          0,
          0);
      SendSocket(@m_defMsg, EnCodeBuffer(@MessageBodyWL,
          SizeOf(TMessageBodyWL)) + EnCodeString(ProcessMsg.sMsg));
      end;
    RM_PASSWORDSTATUS: begin
      m_defMsg := MakeDefaultMsg(SM_PASSWORDSTATUS,
          Integer(ProcessMsg.BaseObject),
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          ProcessMsg.nParam3);
      SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
    RM_GHOST: begin
      m_defMsg := MakeDefaultMsg(SM_GHOST, Integer(ProcessMsg.BaseObject),
          ProcessMsg.wParam, 0, 0);
      SendSocket(@m_defMsg, EnCodeBuffer(@ProcessMsg.nParam1,
          SizeOf(Integer)));
      end;
    CM_CALCELTASK: begin
      ClientDelTask(ProcessMsg.nParam1);
      end;
    RM_ADDTASK: begin
      SendDefMessage(SM_TASKINFO, ProcessMsg.nParam1, ProcessMsg.nParam2, 0, ProcessMsg.wParam, ProcessMsg.sMsg);
      SendDefMessage(SM_TASKINFO, 0, 0, 0, 0, Format(sTaskInfo, ));
      end;
    RM_YSSKILL: begin
      m_defMsg := MakeDefaultMsg(SM_YSSKILL,
          Integer(ProcessMsg.BaseObject),
          LoWord(ProcessMsg.nParam2),                                                               //60
          HiWord(ProcessMsg.nParam2),                                                               //15
          0);                                                                                       //1
      CombineSkillEffect.nMonID := ProcessMsg.nParam1;
      CombineSkillEffect.nSkillType := 0;
      CombineSkillEffect.nPneumaID := ProcessMsg.nParam3;
      s1C := EnCodeBuffer(@CombineSkillEffect, SizeOf(TCombineSkillEffect));

      SendSocket(@m_defMsg, s1C);
      end;
    RM_CHAINTHUNDER: begin
      m_defMsg := MakeDefaultMsg(SM_CHAINTHUNDER,
          Integer(ProcessMsg.BaseObject),
          LoWord(ProcessMsg.nParam2),
          HiWord(ProcessMsg.nParam2),
          ProcessMsg.wParam);
      SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
    RM_TOWERAAILITY: begin
      SendGuildTowerInfo();
      end;
    RM_PROWL: begin
      m_nCharStatus := GetCharStatus();
      StatusChanged();
      SendRefMsg(RM_DISAPPEAR, 0, 0, 0, 0, '');
      m_boObMode := True;
      end;
    CM_CATCHEVIL: begin                                                                           //俘获心魔
      ClientCatchEvil(TBaseObject(ProcessMsg.nParam1),
          MakeLong(ProcessMsg.nParam2, ProcessMsg.nParam3));
      end;
    CM_ADDEVILTOITEM: begin                                                                         //附魔到装备
      ClientAddEvilToItem(ProcessMsg.wParam, ProcessMsg.nParam1,
          MakeLong(ProcessMsg.nParam2, ProcessMsg.nParam3));
      end;
    CM_ADDANTIEVILPOWER: begin                                                                      //增加镇魔值
      ClientAddAntiEvilPower(ProcessMsg.wParam, ProcessMsg.nParam1,
          MakeLong(ProcessMsg.nParam2, ProcessMsg.nParam3));
      end;
    $889B: begin                                                                                    //书页
      ExecuteScript(g_ManageNPC, '@ReadBook' + IntToStr(ProcessMsg.nParam2));
      end;
    $5EB6: begin                                                                                    //收起元神
      if m_boPneuma and (m_PneumaObject <> nil) then begin
          TPlayObject(m_PneumaObject).PneumaLogin();                                                //24246   下线元神
      end;
{$IF USESDK = DEBUG}
      MainOutMessage(Format('元神消息:%s-%d-%d-%d-%d-%d %s-%S',
          [m_sCharName, ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg,
            DeCodeString(ProcessMsg.sMsg)]));
{$IFEND}
      end;
    $5EB7: begin                                                                                    //释放元神
      if m_boPneuma and (m_PneumaObject <> nil) then begin
          TPlayObject(m_PneumaObject).PneumaLogin();                                                //24246   下线元神
      end;
{$IF USESDK = DEBUG}
      MainOutMessage(Format('元神消息:%s-%d-%d-%d-%d-%d %s-%S',
          [m_sCharName, ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg,
            DeCodeString(ProcessMsg.sMsg)]));
{$IFEND}
      end;
    CM_ITEMPIC: begin
      SendScriptItemPic(ProcessMsg.sMsg, ProcessMsg.nParam2);
{$IF USESDK = DEBUG}
      MainOutMessage(Format('精彩活动:%s-%d-%d-%d-%d-%d %s-%S',
          [m_sCharName, ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg,
            DeCodeString(ProcessMsg.sMsg)]));
{$IFEND}
      end;
    CM_REQUESTMASTER: begin                                                                         //784-0-233480192-1-0   1 招收徒弟 2 请求拜师
      ClientRequest(ProcessMsg.wIdent, ProcessMsg.nParam1, ProcessMsg.nParam2);
      end;
    CM_REQUESTDEAL: begin                                                                           //786-0-232991184-1-0
      ClientRequest(ProcessMsg.wIdent, ProcessMsg.nParam1, ProcessMsg.nParam2);
      end;
    CM_EVOLUTION: begin
      DeCodeBuffer(ProcessMsg.sMsg, @nObjCount, SizeOf(nObjCount));
      ClientEvoluTion(ProcessMsg.wParam, ProcessMsg.nParam1, MakeLong(ProcessMsg.nParam2, ProcessMsg.nParam3), nObjCount);
{$IF USESDK = DEBUG}
      MainOutMessage(Format('幻化消息:%d-%d-%d-%d-%d %s-%d',
          [ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg, nObjCount]));
{$IFEND}
      end;
    $0334: begin
      ExecuteScript(g_ManageNPC, '@离开迷仙阵');
{$IF USESDK = DEBUG}
      MainOutMessage(Format('迷仙阵消息:%d-%d-%d-%d-%d %s',
          [ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg]));
{$IFEND}
      end;
    $9555: begin
      if m_PEnvir.m_MapFlag.boCanReLive then begin
          m_sScriptParam := m_sMapName;
          ExecuteScript(g_ManageNPC, '@原地复活');
      end;
{$IF USESDK = DEBUG}
      ReAlive;
      SendRefMsg(RM_510, 1, 0, 71, 0, '');
{$IFEND}
      end;
    SM_QUERYRELIVE: begin                                                                           //      涅槃重生技能询问复活
      if m_boQueryReLive then begin
          m_boQueryReLive := False;
          ReAlive;
          n18 := Round(m_WAbil.dwMaxHP / 3);
          Inc(m_nIncHealth, n18);
          n18 := m_WAbil.dwMaxHP - n18;
          IncHealthSpell(n18, 10);
          //m_WAbil.HP := m_WAbil.MaxHP;
          RecalcAbilitys();
          SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
          SendDefMessage($9555, Integer(Self), 0, 0, 1, '');
          SendRefMsg(RM_510, 1, 0, 130, 0, '');
      end;
      end;
    $033B: begin
      case ProcessMsg.nParam2 of
          1: ExecuteScript(g_ManageNPC, '@扩展包裹');
          2: ExecuteScript(g_ManageNPC, '@扩展钱袋');
          3: ExecuteScript(g_ManageNPC, '@扩展元神包裹');
          4, 5: ExecuteScript(g_ManageNPC, '@扩展仓库');
          6: ExecuteScript(g_ManageNPC, '@扩展灵兽包裹');
          7: ExecuteScript(g_ManageNPC, '@_VIP_扩展包裹');
          8: ExecuteScript(g_ManageNPC, '@_VIP_扩展仓库');
      end;
      end;
    CM_TREASUREBOX: begin
      case LoByte(ProcessMsg.nParam2) of
          1: ClientActivationTreasureBox();
          2: ClientEnlargeTreasureBox();
          3: ClientUPGradeTreasureBox(HiByte(ProcessMsg.nParam2), ProcessMsg.sMsg);
          4: ClientInjectPowerToTreasureBox(ProcessMsg.wParam);
          5: ClientTakeItemOutTreasureBox(ProcessMsg.nParam1);
          6: ClientTakeItemToTreasureBox(ProcessMsg.nParam1);
          7: begin
            if (m_TreasureBoxItem = nil) or (m_TreasureBoxItem.DuraMax >= 20) then Exit;
            SendDefMessage(CM_TREASUREBOX, 10, 7, 0, 0, '');
            end;
      end;
{$IF USESDK = DEBUG}
      MainOutMessage(Format('灵犀宝盒消息:%d-%d-%d-%d-%d %s',
          [ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg]));
{$IFEND}
      end;
    CM_TIGEREAT: begin
      m_sScriptParam := IntToStr(ProcessMsg.nParam1);
      ExecuteScript(g_ManageNPC, '@虎王喂食');
      end;
    CM_CALLTIGER: begin
      ClientCallTiger();
      end;
    CM_RECALLTIGER: begin
      ClientReCallTiger();
      end;
    CM_TIGERATTACK: begin
      ClientSetTigerTarget(ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.wParam);
      end;
    SM_ALLOTGUILDGOLD: begin
      ClientAllotGuildGold(DeCodeString(ProcessMsg.sMsg), ProcessMsg.nParam1);
      end;
    RM_BUILDGUILDTOWER: begin
      SendDefMessage(SM_BUILDGUILDTOWER,
          0,
          0,
          0,
          0,
          ProcessMsg.sMsg);
      end;
    SM_BUILDGUILDTOWER: begin
      sTmp := m_PEnvir.GetGuildTowerInfo;
      if sTmp <> '' then begin
          SendDefMessage(SM_BUILDGUILDTOWER, 0, 0, 0, 0, sTmp);
      end;
      end;
    SM_GUILDMEMBERLIST: ClientGuildMemberList();
    SM_GUILDOFFICIALPLAYER: SendNearbyGuildMemberList();
    SM_GUILDOFFICIAL: begin
      case ProcessMsg.nParam3 of
          1: ClientAskForGuildOfficial(ProcessMsg.nParam2, DeCodeString(ProcessMsg.sMsg));
      end;
      end;
    SM_QUESTGUILDOFFICIAL: begin
      ClientGuildOfficial(ProcessMsg.nParam3, ProcessMsg.nParam2, DeCodeString(ProcessMsg.sMsg));
      end;
    SM_TREASUREPAVILION: begin
{$IF USESDK = DEBUG}
      MainOutMessage(Format('珍宝阁消息:%d-%d-%d-%d-%d %s',
          [ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg]));
{$IFEND}
      case LoByte(ProcessMsg.nParam2) of
          0: begin
            SendTreasurePavilion();
            end;
          1: begin
            m_sScriptParam := IntToStr(HiByte(ProcessMsg.nParam2));
            ExecuteScript(g_GuildTowerNPC, '@珍宝阁开宝');
            end;
          2: begin                                                                                  //极品阁
            SendNonSuchPavilion(HiByte(ProcessMsg.nParam2));
            end;
          3: begin
            if not m_boInNonSuchPavilion then Exit;                                             //没有进入极品阁
            m_sScriptParam := IntToStr(HiByte(ProcessMsg.nParam2));
            ExecuteScript(g_GuildTowerNPC, '@极品阁开宝');
            end;
      end;
      end;
    SM_GUILDTOWER: begin
{$IF USESDK = DEBUG}
      MainOutMessage(Format('通灵塔消息:%d-%d-%d-%d-%d %s',
          [ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg]));
{$IFEND}
      case ProcessMsg.nParam1 of
          0: begin
            SendGuildTowerRes();
            end;
          1: begin                                                                                  //捐献资源
            FillChar(nArrItem, SizeOf(Integer) * 3, #0);
            DeCodeBuffer(ProcessMsg.sMsg, @nArrItem, SizeOf(Integer) * 3);
            m_sScriptParam := IntToStr(nArrItem);
            m_sScriptParam := IntToStr(nArrItem);
            m_sScriptParam := IntToStr(nArrItem);
            ExecuteScript(g_GuildTowerNPC, '@Contribute');
            end;
      end;
      end;
    RM_LOTUSINFO: begin
      SendDefMessage(SM_LOTUSINFO,
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          ProcessMsg.nParam3,
          ProcessMsg.wParam,
          ProcessMsg.sMsg);
      if ProcessMsg.nParam1 = 0 then                                                            //删除的,多发一次
          SendDefMessage(SM_LOTUSINFO,
            ProcessMsg.nParam1,
            ProcessMsg.nParam2,
            ProcessMsg.nParam3,
            ProcessMsg.wParam,
            ProcessMsg.sMsg);
      end;
    SM_LOTUSINFO: begin
      ClientQueryMapLotusInfo();
      end;
    $0352: begin
      m_sScriptParam := IntToStr(ProcessMsg.nParam1);
      m_sScriptParam := IntToStr(MakeLong(ProcessMsg.nParam3, ProcessMsg.wParam));
      DeCodeBuffer(ProcessMsg.sMsg, @nObjCount, SizeOf(Integer));
      m_sScriptParam := IntToStr(nObjCount);
      ExecuteScript(g_GuildTowerNPC, '@RefineItem');
      end;
    $0BE0: begin
      m_sScriptParam := IntToStr(MakeLong(ProcessMsg.nParam3, ProcessMsg.wParam));
      case ProcessMsg.nParam2 of
          1: ExecuteScript(g_ManageNPC, '@炼化内丹');
          2: ExecuteScript(g_ManageNPC, '@炼化元婴');
      end;
      end;
    $0BE1: begin
      ClientCreateSoul(0, LoByte(ProcessMsg.nParam2), HiByte(ProcessMsg.nParam2));
      end;
    $0BE2: begin
      ClientCreateSoul(1, ProcessMsg.nParam1, ProcessMsg.nParam2);
      end;
    $0BE3: begin
      ExecuteScript(g_ManageNPC, '@元婴散魂');
      end;
    $0BE6: begin
      case ProcessMsg.wParam of
          0: ClientFelementOrderFlag(ProcessMsg.nParam1, MakeLong(ProcessMsg.nParam2, ProcessMsg.nParam3));
          1: begin                                                                                  //1
            m_sScriptParam := '1';
            ExecuteScript(g_ManageNPC, '@离火封魔阵');
            SendDefMessage(SM_627, 0, 1037, 0, 0, '');
            end;
          10: begin                                                                                 //离开
            m_sScriptParam := '0';                                                             //0
            ExecuteScript(g_ManageNPC, '@离火封魔阵');
            end;
          266: begin                                                                              //在来一次
            m_sScriptParam := '2';                                                             //2
            ExecuteScript(g_ManageNPC, '@离火封魔阵');
            end;
      end;
      end;
    $0BE7: begin
      ClientReCallGuarder(ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.nParam3);
      end;
    CM_CTRLMENTAL: begin
      ClientCtrlMental(ProcessMsg.nParam2);                                                       //天元心法
      end;
    RM_3046: begin
      SendDefMessage(3046, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg);
      end;
    CM_PHOENIXSEARCH: begin                                                                         //凤凰探宝
      ClientPhoenixSearch(ProcessMsg.nParam1, ProcessMsg.nParam2);
      end;
    RM_TIGERADDABIL: begin
      m_defMsg := MakeDefaultMsg(SM_TIGERABIL, 0, 0, 0, 0);
      SendSocket(@m_defMsg, EnCodeBuffer(@m_TorDDM.Tiger.AddAbil, SizeOf(TAddAbilityOfTiger) - 4));
      end;
    CM_TIGERTAKEON: begin
      case LoByte(ProcessMsg.nParam2) of
          0: ClientTakeOnInosculatePneumaItem(HiByte(ProcessMsg.nParam2), ProcessMsg.nParam1);
          1: ClientTakeOffInosculatePneumaItem(HiByte(ProcessMsg.nParam2), ProcessMsg.nParam1);
          2: ClientTakeOnTigerItem(HiByte(ProcessMsg.nParam2), ProcessMsg.nParam1);
          3: ClientTakeOffTigerItem(HiByte(ProcessMsg.nParam2), ProcessMsg.nParam1);
          4: ClientTakeOnPetSoulItem(HiByte(ProcessMsg.nParam2), ProcessMsg.nParam1, ProcessMsg.nParam3);
          5: ClientTakeOffPetSoulItem(HiByte(ProcessMsg.nParam2), ProcessMsg.nParam1, ProcessMsg.nParam3);
      else
{$IF USESDK = DEBUG}
          MainOutMessage(Format('虎王消息:%d-%d-%d-%d-%d %s',
            ));
{$IFEND}
      end;
      end;
    RM_HEARTFATEPOINT: begin
      m_defMsg := MakeDefaultMsg(SM_HEARTFATEPOINT, 0, 0, 0, 0);
      SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
    RM_CTRLMENTAL: begin
      SendDefMessage(SM_CTRLMENTAL, ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.nParam3, 0, '');
      end;
    CM_GUILDCLAN: begin
      ClientQueryGuildClanList();
      end;
    CM_CLANOPERATE: begin
      ClientClanOperate(ProcessMsg.nParam2, ProcessMsg.sMsg);
{$IF USESDK = DEBUG}
      MainOutMessage(Format('宗族消息:%d-%d-%d-%d-%d %s',
          ));
{$IFEND}
      end;
    CM_CLANQUERY: begin
      ClientClanReQuery(ProcessMsg.nParam1, ProcessMsg.sMsg);
{$IF USESDK = DEBUG}
      MainOutMessage(Format('宗族消息:%d-%d-%d-%d-%d %s',
          ));
{$IFEND}
      end;
    RM_GETCATAPULT: begin
      m_defMsg := MakeDefaultMsg(SM_GETCATAPULT,
          Integer(ProcessMsg.BaseObject),
          ProcessMsg.nParam2,
          ProcessMsg.nParam3,
          ProcessMsg.wParam);

      SendSocket(@m_defMsg, EnCodeBuffer(@ProcessMsg.nParam1, 4));
      end;
    RM_CATAPULTSTATUS: begin
      SendDefMessage(SM_CATAPULTSTATUS, Integer(ProcessMsg.BaseObject), 0, 0, ProcessMsg.wParam, '');
      end;
    SM_CATAPULTSTATUS: begin
{$IF USESDK = DEBUG}
      MainOutMessage(Format('投石车消息:%d-%d-%d-%d-%d %s',
          [ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg]));
{$IFEND}
      if m_boCatapultMode then begin
          case ProcessMsg.wParam of
            0: begin                                                                              //移动
                m_boCatapultAttackMode := False;
                SendRefMsg(RM_CATAPULTSTATUS, 0, Integer(Self), 0, 0, '');
                SysMsg('投石车处于移动形态', c_Red, t_Hint);
            end;
            1: begin                                                                              //架起
                m_boCatapultAttackMode := True;
                SendRefMsg(RM_CATAPULTSTATUS, 1, Integer(Self), 0, 0, '');
                SysMsg('投石车处于架起形态', c_Red, t_Hint);
            end;
            2: begin                                                                              //弃车

            end;
          end;
      end;
      end;
    //      RM_CATAPULTATTACK: begin
    //      SendDefMessage(SM_CATAPULTATTACK, Integer(ProcessMsg.BaseObject), ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.wParam, '');
    //      end;
    SM_CATAPULTATTACK: begin
      ClientCatapultAttackTarget(ProcessMsg.wParam, ProcessMsg.nParam2, ProcessMsg.nParam3);
      end;
    CM_MAKEBABY: begin                                                                              //繁衍灵兽
      ClientPetMakeBaby(ProcessMsg.nParam1, MakeLong(ProcessMsg.nParam2, ProcessMsg.nParam3));
      end;
    CM_MAGBEAST: begin                                                                              //兽化
      ClientMagOfPetBeast(ProcessMsg.nParam1);
      end;
    RM_PETBEAST: begin
      m_defMsg := MakeDefaultMsg(SM_PETBEAST,
          Integer(ProcessMsg.BaseObject),
          LoWord(ProcessMsg.nParam1),
          HiWord(ProcessMsg.nParam1),
          ProcessMsg.wParam);
      SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
    RM_LAPIDATION: begin
      m_defMsg := MakeDefaultMsg(SM_LAPIDATION,
          Integer(ProcessMsg.BaseObject),
          ProcessMsg.nParam2,
          ProcessMsg.nParam3,
          ProcessMsg.wParam);
      SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
    RM_USESPIRIT: begin                                                                           //使用神魂融合技能
   {   if (ProcessMsg.BaseObject = Self) and (m_MagicSkills <> nil) then begin
          DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, nil);
      end;}
      end;

    RM_SPIRITHP: begin                                                                              //神魂融合   神魂值
      {if (ProcessMsg.BaseObject = Self) or (m_PneumaObject = ProcessMsg.BaseObject) then begin
          m_defMsg := MakeDefaultMsg(SM_SPIRITHP,
            Integer(ProcessMsg.BaseObject),
            ProcessMsg.nParam1,
            ProcessMsg.nParam2,
            0);
      end else begin
          m_defMsg := MakeDefaultMsg(SM_SPIRITHP,
            Integer(ProcessMsg.BaseObject),
            CalcCent(ProcessMsg.nParam1, ProcessMsg.nParam2),
            100,
            0);
      end;
      SendSocket(@m_defMsg, EnCodeBuffer(@ProcessMsg.wParam, 2));   }
      end;
    CM_CTRLDIVRATE: begin
      if not m_boPneuma and (m_PneumaObject <> nil) and (m_SpiritInfo.btLinkLv > 0) then begin
          m_SpiritInfo.btDivRate := _MIN((m_SpiritInfo.btLinkLv + 1) * 10, ProcessMsg.nParam2);
          SysMsg(Format('您的灵魂锁链当前可转移的的伤害比例为%d%%', ), c_Red, t_Hint);
      end;
      end;
    CM_COMPREHENDSKILL: begin
      m_sScriptParam := IntToStr(ProcessMsg.nParam1);
      m_sScriptParam := IntToStr(ProcessMsg.nParam2);
      if ProcessMsg.nParam3 = 0 then begin
          ExecuteScript(g_FunctionNPC, '@遗忘魂佑技能');
      end else begin
          ExecuteScript(g_FunctionNPC, '@领悟魂佑技能');
      end;
      end;
    CM_FREEPET: begin
      m_sScriptParam := IntToStr(ProcessMsg.nParam1);
      ExecuteScript(g_FunctionNPC, '@放生灵兽');
      end;
    CM_ACHIEVEMENT: begin                                                                           //成就系统
      ClientAchievementSystem();
      end;
    CM_MAKEWENPEI: begin                                                                            //制做纹佩
      ClientMakeWenPei(LoByte(ProcessMsg.nParam2),                                                //主纹
          HiByte(ProcessMsg.nParam2),                                                               //精纹
          LoByte(ProcessMsg.nParam3),                                                               //底纹
          HiByte(ProcessMsg.nParam3)                                                                //边纹
          );
      end;
    CM_GETWENPEI_DEMAND: begin
      ClientGetWenPeiDemand(ProcessMsg.nParam1, ProcessMsg.nParam2);
      end;
    CM_TAKEWENPEI: begin                                                                            //强化 或 拆解 纹佩
      ClientTakeWenPei(MakeLong(ProcessMsg.nParam2, ProcessMsg.nParam3), ProcessMsg.nParam1);
      end;
    CM_COLLECTSUITS: begin                                                                        //成就之收集套装
      ClientCollectSuits(ProcessMsg.nParam3, ProcessMsg.nParam2, ProcessMsg.sMsg);
      end;
    CM_CHECKVALIDCODE: begin
      ClientCheckVerifyCode(ProcessMsg.sMsg);
      end;
    RM_DIRSHADOWHIT: begin
      m_defMsg := MakeDefaultMsg(SM_DIRSHADOWHIT,
          ProcessMsg.nParam1,
          ProcessMsg.nParam2,
          ProcessMsg.nParam3,
          ProcessMsg.wParam);
      SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
    RM_UPDATEITEM_MSG: begin
      m_defMsg := MakeDefaultMsg(ProcessMsg.wParam, Integer(ProcessMsg.BaseObject), ProcessMsg.nParam2, 0, ProcessMsg.nParam3);
      SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
    RM_MAPEFFECT: begin
      SendDefMessage(SM_MAPEFFECT, ProcessMsg.wParam, ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg);
      end;
    RM_REFRESHRANK: begin                                                                           //刷新排行
      case ProcessMsg.nParam1 of
          0: g_RankManage.RefreshHeroRank(Self);
          1: g_RankManage.RefreshPneumaRank(Self);
          2: g_RankManage.RefreshOutPrenticeRank(Self);
          3: g_RankManage.RefreshPetRank(ProcessMsg.nParam2, Self);
          4: g_RankManage.RefreshGodPetRank(ProcessMsg.nParam2, Self);
          5: g_RankManage.RefreshMilitaryRank(Self);
          6: g_RankManage.RefreshRepressDemonRank(Self);
      end;
      end;
    RM_CHARSTATUSCHANGED_Delay: begin
      StatusChanged();
      end;
    RM_VEHICLEPOS: begin
      SendDefMessage(SM_VEHICLEPOS, ProcessMsg.wParam, ProcessMsg.nParam1, ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg);
      end;
    RM_REDPACKET: begin
      SendRedPacketWindow(ProcessMsg.wParam);
      end;
    RM_DEMONHIT: begin
      m_defMsg := MakeDefaultMsg(2454,
          Integer(ProcessMsg.BaseObject),
          ProcessMsg.nParam2,
          ProcessMsg.nParam3,
          ProcessMsg.wParam);
      SendSocket(@m_defMsg, ProcessMsg.sMsg);
      end;
   { 199:
    begin
      MainOutMessage(Format('精彩活动消息:%s-%d-%d-%d-%d-%d %s-%d',
          [m_sCharName, ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
          ProcessMsg.nParam2, ProcessMsg.nParam3, DeCodeString(ProcessMsg.sMsg), nObjCount]));
    end;    }
else begin
      Result := inherited Operate(ProcessMsg);
    end;
{$IF CHECKNEWMSG =1}
    if not Result then
      MainOutMessage(Format('未处理的消息:%d-%d-%d-%d-%d %s %s元神:%s',
      [ProcessMsg.wIdent, ProcessMsg.wParam, ProcessMsg.nParam1,
      ProcessMsg.nParam2, ProcessMsg.nParam3, ProcessMsg.sMsg, DeCodeString(ProcessMsg.sMsg), BoolToCStr(m_boPneuma)]));
{$IFEND}
end;
end;

{将心魔属性添加到装备}

procedure TPlayObject.AddEvilToItemB(nWhere: word; nMakeIndex, BottleIndex:
Integer);
var
UserItem, BottleItem                  : pTUserItem;
s                                     : string;
pStdItem                              : pTStdItem;
begin
GetUserItemByMakeIndex(BottleIndex, BottleItem);
GetUserItemByMakeIndex(nMakeIndex, UserItem);
if (UserItem <> nil) and (BottleItem <> nil) then begin
    if (BottleItem.Evil.sName = '') or (BottleItem.Evil.MakeIndex = 0) then begin
      SysMsg('无法从玉净瓶中感应到心魔气息,不能附魔!', c_Red, t_Hint);
      Exit;
    end;
    if BottleItem.Evil.wPower < 2000 then begin
      SysMsg('玉净瓶的镇魔力量太弱,不能附魔!', c_Red, t_Hint);
      Exit;
    end;
    UserItem.Evil := BottleItem.Evil;
    UserItem.Evil.MakeIndex := UserItem.MakeIndex;
    {获取心魔随机属性}
    ItemUnit.RandomItemEvil(UserItem);                                                            //获取附魔属性
    SendUpdateItem(UserItem, False);

    FillChar(BottleItem.Evil, SizeOf(TEvil), #0);                                                   //删除玉净瓶心魔数据
    SendUpdateItem(BottleItem, False);
    SendDefMessage(SM_ITEMEVIL, Integer(Self), LoWord(BottleIndex), HiWord(BottleIndex), 0, '');
    SendRefMsg(RM_510, 1, 0, 63, 0, '');
    pStdItem := UserEngine.GetStdItem(UserItem.wIndex);
    if (pStdItem <> nil) then
      SysMsg(Format('心魔的魔力精髓,已经附注到你的%s,你的%s获得了强大的威力!', ), c_Red, t_Hint);
end;
end;

{棋座留言}

procedure TPlayObject.AddFlagComment(nflagType: Integer; NPCID: Integer;
nMsgLen: Integer; sMsg: string);
var
s                                     : string;
NPC                                 : TNormNpc;
begin
NPC := UserEngine.FindMerchant(TObject(NPCID));
if NPC = nil then NPC := UserEngine.FindNPC(TObject(NPCID));
if NPC = nil then Exit;
if CheckFilterWords(sMsg) then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, '输入内容含有非法字符!');
    Exit;
end;
NPC.AddComment(Self, DeCodeString(sMsg));
end;

procedure TPlayObject.AddToFriendList(FriendName: string);
var
i                                     : Integer;
boFound                               : Boolean;
begin
boFound := False;
for i := 0 to m_FriendsList.Count - 1 do
    if m_FriendsList = FriendName then begin
      boFound := True;
      Break;
    end;
if not boFound then begin
    m_FriendsList.Add(FriendName);
    SendDefMessage(SM_AddFriend, 0, 0, 0, 0, FriendName);
end;
end;

procedure TPlayObject.BaseObjectMove(sMAP, sX, sY: string);                                       //004BD0C4
var
Envir                                 : TEnvirnoment;
nX, nY                              : Integer;
begin
Envir := m_PEnvir;
if sMAP = '' then sMAP := m_sMapName;
if (sX <> '') and (sY <> '') then begin
    nX := Str_ToInt(sX, 0);
    nY := Str_ToInt(sY, 0);
    SpaceMove(sMAP, nX, nY, 0, nil);
end else begin
    MapRandomMove(sMAP, 0, nil);
end;
if (Envir <> m_PEnvir) and (m_btRaceServer = RC_PLAYOBJECT) then begin
    m_boTimeRecall := False;
end;

end;

procedure TPlayObject.CancelDoShop;
var
DoShopResult                        : TDoShopResult;
begin
//如果当前在摆摊,则强制收摊
if m_wShopItemCount > 0 then begin
    m_wShopItemCount := 0;
    DoShopResult.ShopType := 0;
    DoShopResult.RetCode := $FF;
    DoShopResult.FlagType := 0;
    DoShopResult.FlagColor := 0;
    m_defMsg := MakeDefaultMsg(SM_DOSHOP, Integer(Self), m_nCurrX, m_nCurrY, m_btDirection);
    SendSocket(@m_defMsg, EnCodeBuffer(@DoShopResult, SizeOf(TDoShopResult)));
    SendRefMsg(RM_DOSHOP, m_btDirection, MakeLong(m_nCurrX, m_nCurrY), $FF, 0, '');
end;
end;

function TPlayObject.CancelGroup: Boolean;
resourcestring
sCanceGrop                            = '你的小组被解散了...';
begin
Result := True;
if m_GroupMembers.Count <= 1 then begin
    SendGroupText(sCanceGrop);
    m_GroupMembers.Clear;
    m_GroupOwner := nil;
    Result := False;
end;
end;

procedure TPlayObject.ChangeMasterName(sHumanName, sMasterName: string;
boMaster: Boolean);
var
PlayObject, Hum                     : TPlayObject;
begin
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject <> nil then begin
    if CompareText(sMasterName, '无') = 0 then begin
      if boMaster then begin
      PlayObject.m_sMasterName := '';
      PlayObject.m_sMasterName := '';
      PlayObject.m_sMasterName := '';
      end else begin
      PlayObject.m_sMasterName := '';
      end;
      PlayObject.m_boMaster := False;
    end else begin
      if boMaster then begin
      PlayObject.m_boMaster := True;
      if (PlayObject.m_sMasterName = '') then
          PlayObject.m_sMasterName := sMasterName
      else if (PlayObject.m_sMasterName = '') then
          PlayObject.m_sMasterName := sMasterName
      else if (PlayObject.m_sMasterName = '') then
          PlayObject.m_sMasterName := sMasterName;
      end else begin
      PlayObject.m_sMasterName := sMasterName;
      PlayObject.m_boMaster := False;
      PlayObject.SysMsg('拜师成功', c_Red, t_Hint);
      end;
    end;
    PlayObject.RefShowName;
    PlayObject.SendFiendList(1);
    Hum := UserEngine.GetPlayObject(sMasterName);
    if Hum <> nil then begin
      Hum.SendFiendList(2);
      Hum.SendMeOnlineState(1, 1);
      Hum.RefShowName;
    end;

    //    PlayObject.SendMeOnlineState(1, 2);
end;
end;

procedure TPlayObject.ChangePneumaState;
var
i, nSlave                           : Integer;
Slave                                 : TBaseObject;
resourcestring
sHint1                              = '魂魄力量暂时无法聚拢,你的元神分身不能幻化。';
sHint2                              = '魂魄力量聚拢,你的元神分身幻化成了元神灵珠。';
sHint3                              = '神奇的力量凝聚,你的元神分身被唤醒了。';
begin
if m_boPneuma then Exit;
if (m_PneumaObject = nil) or m_PneumaObject.m_boGhost or m_PneumaObject.m_boDeath then Exit;

//if TPlayObject(m_PneumaObject).m_boRideOn then Exit;

if not TPlayObject(m_PneumaObject).m_boPneumaEffMode then begin
    if g_Config.boNoElfBead then Exit;                                                            //不允许灵珠模式,则直接返回
    if GetTickCount - TPlayObject(m_PneumaObject).m_dwPneumaChangeTick < 9 * 1000 then Exit;      //防止客户端错误引起的刷屏
    if GetTickCount - TPlayObject(m_PneumaObject).m_dwPneumaChangeTick < 10 * 1000 then begin       //从人形转换为灵珠需要时间间隔
      SysMsg(sHint1, c_Red, t_Hint);
      Exit;
    end;
    SysMsg(sHint2, c_Red, t_Hint);
    TPlayObject(m_PneumaObject).m_boPneumaEffMode := True;
    m_PneumaObject.SendRefMsg(RM_YSSTATECHANGED, 1, Integer(m_PneumaObject), 0, 0, '');
    TPlayObject(m_PneumaObject).m_dwPneumaChangeTick := GetTickCount;

    //清除宝宝
    for i := 0 to m_PneumaObject.m_SlaveList.Count - 1 do begin
      Slave := TBaseObject(m_PneumaObject.m_SlaveList.Items);
      nSlave := Integer(Slave);
      TPlayObject(m_PneumaObject).SendDefMessage(SM_SLAVEINFO, Integer(m_PneumaObject), 0, 0, 1, EnCodeBuffer(@nSlave, SizeOf(Integer)));
      Slave.MakeGhost();
    end;
    m_PneumaObject.m_SlaveList.Clear;
end else begin
    TPlayObject(m_PneumaObject).m_dwPneumaChangeTick := GetTickCount;
    SysMsg(sHint3, c_Red, t_Hint);
    TPlayObject(m_PneumaObject).m_boPneumaEffMode := False;
    m_PneumaObject.SendRefMsg(RM_YSSTATECHANGED, 0, Integer(m_PneumaObject), 0, 0, '');
end;
end;

procedure TPlayObject.ChangeServerMakeSlave(SalveInfo: pTSlaveInfo);                              //004DF84C
var
nSlaveCount                           : Integer;
BaseObject                            : TBaseObject;
begin
if m_btJob = 2 then begin                                                                         //道士只允许招一个宝宝
    nSlaveCount := 1;
end else begin                                                                                    //其他职业允许招5个
    nSlaveCount := 5;
end;
BaseObject := MakeSlave(SalveInfo.sSalveName, 3, SalveInfo.btSalveLevel, nSlaveCount, SalveInfo.dwRoyaltySec, -1);
if BaseObject <> nil then begin
    BaseObject.m_nSlaveKillMonCount := SalveInfo.nKillCount;
    BaseObject.m_wSlaveExpLevel := SalveInfo.btSlaveExpLevel;
    BaseObject.m_WAbil.dwHP := SalveInfo.nHP;
    BaseObject.m_WAbil.dwMP := SalveInfo.nMP;
    if (1500 - SalveInfo.btSalveLevel * 200) < BaseObject.m_nWalkSpeed then begin
      BaseObject.m_nWalkSpeed := 1500 - SalveInfo.btSalveLevel * 200;
    end;
    if (2000 - SalveInfo.btSalveLevel * 200) < BaseObject.m_nNextHitTime then begin
      BaseObject.m_nNextHitTime := 2000 - SalveInfo.btSalveLevel * 200;
    end;
    RecalcAbilitys();
end;
end;

function TPlayObject.CheckActionStatus(wIdent: word; var dwDelayTime: LongWord):
Boolean;
var
dwCheckTime                           : LongWord;
//dwCurrTick:LongWord;
dwActionIntervalTime                  : LongWord;
begin
Result := False;
dwDelayTime := 0;
//检查人物弯腰停留时间
if not g_Config.boDisableStruck then begin
    dwCheckTime := GetTickCount - m_dwStruckTick;
    if g_Config.dwStruckTime > dwCheckTime then begin
      dwDelayTime := g_Config.dwStruckTime - dwCheckTime;
      m_btOldDir := m_btDirection;
      Exit;
    end;
end;

//检查二个不同操作之间所需间隔时间
dwCheckTime := GetTickCount - m_dwActionTick;

if m_boTestSpeedMode then begin
    SysMsg('间隔: ' + IntToStr(dwCheckTime), c_Blue, t_Notice);
end;

if m_wOldIdent = wIdent then begin                                                                //当二次操作一样时,则将 boFirst 设置为 真 ,退出由调用函数本身检查二个相同操作之间的间隔时间
    Result := True;
    Exit;
end;
if not g_Config.boControlActionInterval then begin
    Result := True;
    Exit;
end;

dwActionIntervalTime := m_dwActionIntervalTime;
case wIdent of
    CM_LONGHIT: begin
      //跑位刺杀
      if g_Config.boControlRunLongHit and (m_wOldIdent = CM_RUN) and
          (m_btOldDir <> m_btDirection) then begin
          dwActionIntervalTime := m_dwRunLongHitIntervalTime;
      end;
      end;
    CM_HIT: begin
      //走位攻击
      if g_Config.boControlWalkHit and (m_wOldIdent = CM_WALK) and (m_btOldDir <> m_btDirection) then begin
          dwActionIntervalTime := m_dwWalkHitIntervalTime;
      end;
      //跑位攻击
      if g_Config.boControlRunHit and (m_wOldIdent = CM_RUN) and (m_btOldDir <> m_btDirection) then begin
          dwActionIntervalTime := m_dwRunHitIntervalTime;
      end;
      end;
    CM_RUN: begin
      //跑位刺杀
      if g_Config.boControlRunLongHit and (m_wOldIdent = CM_LONGHIT) and
          (m_btOldDir <> m_btDirection) then begin
          dwActionIntervalTime := m_dwRunLongHitIntervalTime;
      end;
      //跑位攻击
      if g_Config.boControlRunHit and (m_wOldIdent = CM_HIT) and (m_btOldDir
          <> m_btDirection) then begin
          dwActionIntervalTime := m_dwRunHitIntervalTime;
      end;
      //跑位魔法
      if g_Config.boControlRunMagic and (m_wOldIdent = CM_SPELL) and
          (m_btOldDir <> m_btDirection) then begin
          dwActionIntervalTime := m_dwRunMagicIntervalTime;
      end;
      end;
    CM_WALK: begin
      //走位攻击
      if g_Config.boControlWalkHit and (m_wOldIdent = CM_HIT) and (m_btOldDir
          <> m_btDirection) then begin
          dwActionIntervalTime := m_dwWalkHitIntervalTime;
      end;
      //跑位刺杀
      if g_Config.boControlRunLongHit and (m_wOldIdent = CM_LONGHIT) and
          (m_btOldDir <> m_btDirection) then begin
          dwActionIntervalTime := m_dwRunLongHitIntervalTime;
      end;
      end;
    CM_SPELL: begin
      //跑位魔法
      if g_Config.boControlRunMagic and (m_wOldIdent = CM_RUN) and (m_btOldDir
          <> m_btDirection) then begin
          dwActionIntervalTime := m_dwRunMagicIntervalTime;
      end;
      end;
end;

//将几个攻击操作合并成一个攻击操作代码
if (wIdent = CM_HIT) or
    (wIdent = CM_HEAVYHIT) or
    (wIdent = CM_BIGHIT) or
    (wIdent = CM_POWERHIT) or
    //   (wIdent = CM_LONGHIT) or
(wIdent = CM_WIDEHIT) or
    (wIdent = CM_FIREHIT) or
    (wIdent = CM_3026) then begin

    wIdent := CM_HIT;
end;

if dwCheckTime >= dwActionIntervalTime then begin
    m_dwActionTick := GetTickCount();
    Result := True;
end else begin
    dwDelayTime := dwActionIntervalTime - dwCheckTime;
end;
m_wOldIdent := wIdent;
m_btOldDir := m_btDirection;
end;

function TPlayObject.CheckDenyLogon(): Boolean;
begin
Result := False;
if GetDenyIPaddrList(m_sIPaddr) then begin
    SysMsg(g_sYourIPaddrDenyLogon, c_Red, t_Hint);
    Result := True;
end else
    if GetDenyAccountList(m_sUserID) then begin
      SysMsg(g_sYourAccountDenyLogon, c_Red, t_Hint);
      Result := True;
    end else
      if GetDenyChrNameList(m_sCharName) then begin
      SysMsg(g_sYourCharNameDenyLogon, c_Red, t_Hint);
      Result := True;
      end;
if Result then m_boEmergencyClose := True;
end;

//检查物品和帐户之间的绑定关系

function TPlayObject.CheckItemBindUse(UserItem: pTUserItem): Boolean;
var
i                                     : Integer;
ItemBind                              : pTItemBind;
begin
Result := True;
//检查物品和帐号的绑定
for i := 0 to g_ItemBindAccount.Count - 1 do begin
    ItemBind := g_ItemBindAccount.Items;
    if (ItemBind.nMakeIdex = UserItem.MakeIndex) and
      (ItemBind.nItemIdx = UserItem.wIndex) then begin
      Result := False;
      if (CompareText(ItemBind.sBindName, m_sUserID) = 0) then begin
      Result := True;
      end else begin
      SysMsg(g_sItemIsNotThisAccount, c_Red, t_Hint);
      //此物品不为此帐号所有!!!
      end;
      Exit;
    end;
end;

//检查物品和IP的绑定
for i := 0 to g_ItemBindIPaddr.Count - 1 do begin
    ItemBind := g_ItemBindIPaddr.Items;
    if (ItemBind.nMakeIdex = UserItem.MakeIndex) and
      (ItemBind.nItemIdx = UserItem.wIndex) then begin
      Result := False;
      if (CompareText(ItemBind.sBindName, m_sIPaddr) = 0) then begin
      Result := True;
      end else begin
      SysMsg(g_sItemIsNotThisIPaddr, c_Red, t_Hint);
      //此物品不为此IP所有!!!
      end;
      Exit;
    end;
end;

//检查物品和人物的绑定
for i := 0 to g_ItemBindCharName.Count - 1 do begin
    ItemBind := g_ItemBindCharName.Items;
    if (ItemBind.nMakeIdex = UserItem.MakeIndex) and
      (ItemBind.nItemIdx = UserItem.wIndex) then begin
      Result := False;
      if (CompareText(ItemBind.sBindName, m_sCharName) = 0) then begin
      Result := True;
      end else begin
      SysMsg(g_sItemIsNotThisCharName, c_Red, t_Hint);
      //此物品不为你所有!!!
      end;
      Exit;
    end;
end;
if Result then begin
    Result := False;
    if m_Abil.level >= UserItem.btItemExt then begin
      Result := True;
    end else begin
      SysMsg(g_sLevelNot, c_Red, t_Hint);
    end;
end;
end;

function TPlayObject.CheckItemsNeed(StdItem: pTStdItem): Boolean;
var
Castle                              : TUserCastle;
begin
Result := True;
Castle := g_CastleManager.IsCastleMember(Self);
case StdItem.Need of
    6: begin                                                                                        //行会需要的物品
      if (m_MyGuild = nil) then begin
          Result := False;
      end;
      end;
    60: begin                                                                                       //掌门人的物品
      if (m_MyGuild = nil) or (m_nGuildRankNo <> 1) then begin
          Result := False;
      end;
      end;
    71: begin                                                                                       //城堡物品
      if Castle = nil then begin
          Result := False;
      end;
      end;
    70: begin                                                                                       //城主物品
      if (Castle = nil) or (m_nGuildRankNo <> 1) then begin
          Result := False;
      end;
      end;
    8: begin                                                                                        //会员物品
      if m_nMemberType = 0 then Result := False;
      end;
    81: begin                                                                                       //
      if (m_nMemberType <> LoWord(StdItem.NeedLevel)) or (m_nMemberLevel <
          HiWord(StdItem.NeedLevel)) then
          Result := False;
      end;
    82: begin
      if (m_nMemberType < LoWord(StdItem.NeedLevel)) or (m_nMemberLevel <
          HiWord(StdItem.NeedLevel)) then
          Result := False;
      end;
end;
end;

procedure TPlayObject.CheckMarry;
var
boIsfound                           : Boolean;
sUnMarryFileName                      : string;
LoadList                              : TStringList;
i                                     : Integer;
sSayMsg                               : string;
begin
boIsfound := False;
sUnMarryFileName := g_Config.sEnvirDir + 'UnMarry.txt';
if FileExists(sUnMarryFileName) then begin
    LoadList := TStringList.Create;
    LoadList.LoadFromFile(sUnMarryFileName);
    for i := LoadList.Count - 1 downto 0 do begin
      if CompareText(LoadList.Strings, m_sCharName) = 0 then begin
      LoadList.Delete(i);
      boIsfound := True;
      Break;
      end;
    end;
    LoadList.SaveToFile(sUnMarryFileName);
    LoadList.free;
end;
if boIsfound then begin
    if m_btGender = 0 then begin
      sSayMsg := AnsiReplaceText(g_sfUnMarryManLoginMsg, '%d', m_sDearName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%s', m_sDearName);
    end else begin
      sSayMsg := AnsiReplaceText(g_sfUnMarryWoManLoginMsg, '%d', m_sCharName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%s', m_sCharName);
    end;
    if g_Config.boShowScriptActionMsg then SysMsg(sSayMsg, c_Red, t_Hint);
    m_sDearName := '';
    RefShowName;
end;
m_DearHuman := UserEngine.GetPlayObject(m_sDearName);
if m_DearHuman <> nil then begin
    m_DearHuman.m_DearHuman := Self;
    if m_btGender = 0 then begin
      sSayMsg := AnsiReplaceText(g_sManLoginDearOnlineSelfMsg, '%d',
      m_sDearName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%s', m_sCharName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%m', m_DearHuman.m_PEnvir.m_sMapDesc);
      sSayMsg := AnsiReplaceText(sSayMsg, '%x', IntToStr(m_DearHuman.m_nCurrX));
      sSayMsg := AnsiReplaceText(sSayMsg, '%y', IntToStr(m_DearHuman.m_nCurrY));
      if g_Config.boShowScriptActionMsg then SysMsg(sSayMsg, c_Blue, t_Hint);

      sSayMsg := AnsiReplaceText(g_sManLoginDearOnlineDearMsg, '%d',
      m_sDearName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%s', m_sCharName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%m', m_PEnvir.m_sMapDesc);
      sSayMsg := AnsiReplaceText(sSayMsg, '%x', IntToStr(m_nCurrX));
      sSayMsg := AnsiReplaceText(sSayMsg, '%y', IntToStr(m_nCurrY));
      if g_Config.boShowScriptActionMsg then
      m_DearHuman.SysMsg(sSayMsg, c_Blue, t_Hint);
    end else begin
      sSayMsg := AnsiReplaceText(g_sWoManLoginDearOnlineSelfMsg, '%d',
      m_sDearName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%s', m_sCharName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%m', m_DearHuman.m_PEnvir.m_sMapDesc);
      sSayMsg := AnsiReplaceText(sSayMsg, '%x', IntToStr(m_DearHuman.m_nCurrX));
      sSayMsg := AnsiReplaceText(sSayMsg, '%y', IntToStr(m_DearHuman.m_nCurrY));
      if g_Config.boShowScriptActionMsg then SysMsg(sSayMsg, c_Blue, t_Hint);

      sSayMsg := AnsiReplaceText(g_sWoManLoginDearOnlineDearMsg, '%d',
      m_sDearName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%s', m_sCharName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%m', m_PEnvir.m_sMapDesc);
      sSayMsg := AnsiReplaceText(sSayMsg, '%x', IntToStr(m_nCurrX));
      sSayMsg := AnsiReplaceText(sSayMsg, '%y', IntToStr(m_nCurrY));
      if g_Config.boShowScriptActionMsg then
      m_DearHuman.SysMsg(sSayMsg, c_Blue, t_Hint);
    end;
end else begin
    if m_btGender = 0 then begin
      if g_Config.boOldClientShowHiLevel then
      SysMsg(g_sManLoginDearNotOnlineMsg, c_Red, t_Hint);
    end else begin
      if g_Config.boOldClientShowHiLevel then
      SysMsg(g_sWoManLoginDearNotOnlineMsg, c_Red, t_Hint);
    end;
end;
end;

procedure TPlayObject.CheckMaster;
var
boIsfound                           : Boolean;
sSayMsg, sHumName                     : string;
i                                     : Integer;
human                                 : TPlayObject;
begin
{处理强行脱离师徒关系}
boIsfound := False;
sHumName := '';
if not m_boMaster then begin                                                                      //徒弟上线
    g_UnForceMasterList.Lock;
    try
      for i := g_UnForceMasterList.Count - 1 downto 0 do begin
      if CompareText(g_UnForceMasterList.Strings, m_sCharName) = 0 then begin
          g_UnForceMasterList.Delete(i);
          SaveUnForceMasterList();
          boIsfound := True;
          Break;
      end;
      end;
    finally
      g_UnForceMasterList.UnLock;
    end;
    if boIsfound then begin
      sSayMsg := AnsiReplaceText(g_sfUnMasterListLoginMsg, '%d', m_sMasterName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%s', m_sMasterName);
      m_sMasterName := '';
      RefShowName;
      if g_Config.boOldClientShowHiLevel then SysMsg(sSayMsg, c_Blue, t_Hint);
    end;
end else begin                                                                                    //师傅上线
    g_UnForceMasterList.Lock;
    try
      for i := g_UnForceMasterList.Count - 1 downto 0 do begin
      sHumName := g_UnForceMasterList.Strings;
      if (CompareText(sHumName, m_sMasterName) = 0) or
          (CompareText(sHumName, m_sMasterName) = 0) or
          (CompareText(sHumName, m_sMasterName) = 0) then begin

          g_UnForceMasterList.Delete(i);
          SaveUnForceMasterList();
          boIsfound := True;
          Break;
      end;
      end;
    finally
      g_UnForceMasterList.UnLock;
    end;

    if boIsfound then begin
      sSayMsg := AnsiReplaceText(g_sfUnMasterLoginMsg, '%d', sHumName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%s', sHumName);
      if m_sMasterName = sHumName then m_sMasterName := ''
      else if m_sMasterName = sHumName then m_sMasterName := ''
      else if m_sMasterName = sHumName then m_sMasterName := '';
      RefShowName;
      if g_Config.boOldClientShowHiLevel then SysMsg(sSayMsg, c_Blue, t_Hint);
    end;
end;

{处理徒弟出师}
if (m_sMasterName <> '') and not m_boMaster then begin                                       //徒弟
    if m_Abil.level >= g_Config.nMasterOKLevel then begin                                           //出师等级
      human := UserEngine.GetPlayObject(m_sMasterName);
      {师傅在线}
      if (human <> nil) and (not human.m_boDeath) and (not human.m_boGhost) then begin
      sSayMsg := AnsiReplaceText(g_sYourMasterListUnMasterOKMsg, '%d', m_sCharName);

      if g_Config.boOldClientShowHiLevel then
          human.SysMsg(sSayMsg, c_Red, t_Hint);

      if g_Config.boOldClientShowHiLevel then
          SysMsg(g_sYouAreUnMasterOKMsg, c_Red, t_Hint);

      human.ExecuteScript(g_ManageNPC, '@徒弟出师');

      {从师傅的徒弟名单中删除}
      for i := human.m_MasterList.Count - 1 downto 0 do begin
          if human.m_MasterList.Items = Self then begin
            human.m_MasterList.Delete(i);
            Break;
          end;
      end;
      {将徒弟从师傅的名字上去掉}
      if m_sCharName = human.m_sMasterName then
          human.m_sMasterName := ''
      else if m_sCharName = human.m_sMasterName then
          human.m_sMasterName := ''
      else if m_sCharName = human.m_sMasterName then
          human.m_sMasterName := '';
      human.RefShowName;
      m_sMasterName := '';
      RefShowName;
      {师傅加声望}
      if human.m_wCreditPoint + g_Config.nMasterOKCreditPoint <= High(word) then begin
          Inc(human.m_wCreditPoint, g_Config.nMasterOKCreditPoint);
          human.SendUpdateMsg(human, RM_SUBABILITY, 0, 0, 0, 0, '');
      end;
      Inc(human.m_nBonusPoint, g_Config.nMasterOKBonusPoint);
      Inc(human.m_wPrenticeCount);                                                                //出师数量加 1
      human.SendMsg(human, RM_ADJUST_BONUS, 0, 0, 0, 0, '');
      //刷新出师排行
      g_RankManage.RefreshOutPrenticeRank(human);
      end else begin
      {如果师傅不在线,则保存到记录中}
      g_UnMasterList.Lock;
      try
          boIsfound := False;
          for i := 0 to g_UnMasterList.Count - 1 do begin
            if CompareText(g_UnMasterList.Strings, m_sCharName) = 0 then begin
            boIsfound := True;
            Break;
            end;
          end;
          if not boIsfound then begin
            g_UnMasterList.Add(m_sCharName);
          end;
      finally
          g_UnMasterList.UnLock;
      end;
      if not boIsfound then begin
          SaveUnMasterList();
      end;
      if g_Config.boOldClientShowHiLevel then
          SysMsg(g_sYouAreUnMasterOKMsg, c_Red, t_Hint);
      m_sMasterName := '';
      RefShowName;
      end;

      //徒弟出师加声望
      if g_Config.boPrenticeAddCredit and (m_wCreditPoint + g_Config.nPrenticeCreditPoint <= High(word)) then begin
      Inc(m_wCreditPoint, g_Config.nPrenticeCreditPoint);
      SendUpdateMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
      Inc(m_nBonusPoint, g_Config.nPrenticeBonusPoint);
      SendMsg(Self, RM_ADJUST_BONUS, 0, 0, 0, 0, '');
      end;
      //触发Qmanage.txt中的脚本
      ExecuteScript(g_ManageNPC, '@本人出师');
    end;
end;

if (not m_boMaster) and (m_sMasterName = '') then Exit;

//处理出师记录
boIsfound := False;
sHumName := '';
g_UnMasterList.Lock;
try
    for i := g_UnMasterList.Count - 1 downto 0 do begin
      if (CompareText(g_UnMasterList.Strings, m_sMasterName) = 0) or
      (CompareText(g_UnMasterList.Strings, m_sMasterName) = 0) or
      (CompareText(g_UnMasterList.Strings, m_sMasterName) = 0) then begin
      sHumName := g_UnMasterList.Strings;
      g_UnMasterList.Delete(i);                                                                   //从出师名单中删除
      SaveUnMasterList();
      boIsfound := True;
      Break;
      end;
    end;
finally
    g_UnMasterList.UnLock;
end;

if boIsfound and m_boMaster then begin
    SysMsg(g_sUnMasterLoginMsg, c_Red, t_Hint);                                                   //你的一个徒弟已经圆满出师了!!!
    if sHumName = m_sMasterName then m_sMasterName := ''
    else if sHumName = m_sMasterName then m_sMasterName := ''
    else if sHumName = m_sMasterName then m_sMasterName := '';
    RefShowName;
    if m_wCreditPoint + g_Config.nMasterOKCreditPoint <= High(word) then begin
      Inc(m_wCreditPoint, g_Config.nMasterOKCreditPoint);
      SendUpdateMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
    end;
    Inc(m_nBonusPoint, g_Config.nMasterOKBonusPoint);
    Inc(m_wPrenticeCount);                                                                        //出师数量加 1
    //刷新出师排行
    g_RankManage.RefreshOutPrenticeRank(Self);
    SendMsg(Self, RM_ADJUST_BONUS, 0, 0, 0, 0, '');
    ExecuteScript(g_ManageNPC, '@徒弟出师');
end;

if m_boMaster and (m_sMasterName = '') and (m_sMasterName = '') and (m_sMasterName = '') then begin
    m_boMaster := False;
    Exit;
end;
{
   if m_boMaster then begin
       //师父上线通知
       m_MasterHuman := UserEngine.GetPlayObject(m_sMasterName);
       if m_MasterHuman <> nil then begin
         m_MasterHuman.m_MasterHuman := Self;
         m_MasterList.Add(m_MasterHuman);

         sSayMsg := AnsiReplaceText(g_sMasterOnlineSelfMsg, '%d',
         m_sMasterName);
         sSayMsg := AnsiReplaceText(sSayMsg, '%s', m_sCharName);
         sSayMsg := AnsiReplaceText(sSayMsg, '%m',
         m_MasterHuman.m_PEnvir.m_sMapDesc);
         sSayMsg := AnsiReplaceText(sSayMsg, '%x',
         IntToStr(m_MasterHuman.m_nCurrX));
         sSayMsg := AnsiReplaceText(sSayMsg, '%y',
         IntToStr(m_MasterHuman.m_nCurrY));
         if g_Config.boOldClientShowHiLevel then SysMsg(sSayMsg, c_Blue, t_Hint);

         sSayMsg := AnsiReplaceText(g_sMasterOnlineMasterListMsg, '%d',
         m_sMasterName);
         sSayMsg := AnsiReplaceText(sSayMsg, '%s', m_sCharName);
         sSayMsg := AnsiReplaceText(sSayMsg, '%m', m_PEnvir.m_sMapDesc);
         sSayMsg := AnsiReplaceText(sSayMsg, '%x', IntToStr(m_nCurrX));
         sSayMsg := AnsiReplaceText(sSayMsg, '%y', IntToStr(m_nCurrY));
         if g_Config.boOldClientShowHiLevel then
         m_MasterHuman.SysMsg(sSayMsg, c_Blue, t_Hint);
       end else begin
         if g_Config.boOldClientShowHiLevel then
         SysMsg(g_sMasterNotOnlineMsg, c_Red, t_Hint);
       end;
   end else begin
       //徒弟上线通知
       if m_sMasterName <> '' then begin
         m_MasterHuman := UserEngine.GetPlayObject(m_sMasterName);
         if m_MasterHuman <> nil then begin

         if m_MasterHuman.m_sMasterName = m_sCharName then begin
             m_MasterHuman.m_MasterHuman := Self;
         end;

         m_MasterHuman.m_MasterList.Add(Self);

         sSayMsg := AnsiReplaceText(g_sMasterListOnlineSelfMsg, '%d',
             m_sMasterName);
         sSayMsg := AnsiReplaceText(sSayMsg, '%s', m_sCharName);
         sSayMsg := AnsiReplaceText(sSayMsg, '%m',
             m_MasterHuman.m_PEnvir.m_sMapDesc);
         sSayMsg := AnsiReplaceText(sSayMsg, '%x',
             IntToStr(m_MasterHuman.m_nCurrX));
         sSayMsg := AnsiReplaceText(sSayMsg, '%y',
             IntToStr(m_MasterHuman.m_nCurrY));
         if g_Config.boOldClientShowHiLevel then
             SysMsg(sSayMsg, c_Blue, t_Hint);

         sSayMsg := AnsiReplaceText(g_sMasterListOnlineMasterMsg, '%d',
             m_sMasterName);
         sSayMsg := AnsiReplaceText(sSayMsg, '%s', m_sCharName);
         sSayMsg := AnsiReplaceText(sSayMsg, '%m', m_PEnvir.m_sMapDesc);
         sSayMsg := AnsiReplaceText(sSayMsg, '%x', IntToStr(m_nCurrX));
         sSayMsg := AnsiReplaceText(sSayMsg, '%y', IntToStr(m_nCurrY));
         if g_Config.boOldClientShowHiLevel then
             m_MasterHuman.SysMsg(sSayMsg, c_Blue, t_Hint);
         end else begin
         if g_Config.boOldClientShowHiLevel then
             SysMsg(g_sMasterListNotOnlineMsg, c_Red, t_Hint);
         end;
       end;
   end;
   }
end;

procedure TPlayObject.CheckPackPetShop();
var
i                                     : Integer;
nCode                                 : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
tm                                    : LongWord;
resourcestring
sExceptionMsg                         = ' TPlayObject::CheckPackPetShop Name=%s Code=%d';
begin
try
    nCode := 0;
    if m_PetInfo.nMakeIndex <> 0 then begin
      m_PackPet := g_PetBoothManage.GetPetSellObject(m_dwDBIndex);
      nCode := 1;
      if (m_PackPet <> nil) and (not m_PackPet.m_boGhost) and (not m_PackPet.m_boDeath) then begin
      if (m_PetInfo.nMakeIndex = m_PetInfo.nMakeIndex) or
          (m_PetInfo.nMakeIndex = m_PetInfo.nMakeIndex) or
          (m_PetInfo.nMakeIndex = m_PetInfo.nMakeIndex) or
          (m_PetInfo.nMakeIndex = m_PetInfo.nMakeIndex) or
          (m_PetInfo.nMakeIndex = m_PetInfo.nMakeIndex) then begin
          PetHide(m_PetInfo.nMakeIndex);
      end;

      m_nPetTargetX := m_PackPet.m_nCurrX;
      m_nPetTargetY := m_PackPet.m_nCurrY;
      nCode := 2;
      SendDefMessage(34979, 0, 1, 0, 0, Format('你的宠物在%s(%d:%d)为你守摊。',
          ));
      SysMsg(Format('你的宠物在%s(%d:%d)为你守摊。',
          ), c_Red, t_Hint);
      nCode := 3;
      if GetUserItemByMakeIndex(m_PetInfo.nMakeIndex, UserItem) >= 0 then begin
          nCode := 4;
          m_PetInfo.wLevel := MakeWord(UserItem.btValue, UserItem.btValue);
          m_PetInfo.btType := 0;
          m_PetInfo.btReLive := UserItem.btValue;
          m_PetInfo.btRideFightSpeed := UserItem.btRideSpeed;
          m_PetInfo.btAttack := UserItem.btExtra.btAttack;                                       //骑战技能攻击距离
          //骑战速度
          StdItem := UserEngine.GetStdItem(UserItem.wIndex);
          nCode := 5;
          if (StdItem <> nil) then begin
            if (UserItem.btValue > 0) then begin
            nCode := 6;
            case StdItem.AniCount of
                0: m_PetInfo.btType := 10 + UserItem.btValue;
                1: m_PetInfo.btType := 13 + UserItem.btValue;
                2: m_PetInfo.btType := 16 + UserItem.btValue;
                3: m_PetInfo.btType := 19 + UserItem.btValue;
                4: m_PetInfo.btType := 22 + UserItem.btValue;
                5: m_PetInfo.btType := 25 + UserItem.btValue;
                6: m_PetInfo.btType := 28 + UserItem.btValue;
                7: m_PetInfo.btType := 31 + UserItem.btValue;
                8: m_PetInfo.btType := 34 + UserItem.btValue;
                9: m_PetInfo.btType := 37 + UserItem.btValue;
                10: m_PetInfo.btType := 38 + UserItem.btValue;
                11: m_PetInfo.btType := 43 + UserItem.btValue;
                12: m_PetInfo.btType := 44 + UserItem.btValue;
                13: m_PetInfo.btType := 45 + UserItem.btValue;
                14: m_PetInfo.btType := 40 + UserItem.btValue;
                15: m_PetInfo.btType := 46 + UserItem.btValue;
            end;
            end else begin
            nCode := 7;
            case StdItem.AniCount of
                0: m_PetInfo.btType := 11;
                1: m_PetInfo.btType := 14;
                2: m_PetInfo.btType := 17;
                3: m_PetInfo.btType := 20;
                4: m_PetInfo.btType := 23;
                5: m_PetInfo.btType := 26;
                6: m_PetInfo.btType := 29;
                7: m_PetInfo.btType := 32;
                8: m_PetInfo.btType := 35;
                9: m_PetInfo.btType := 38;
                10: m_PetInfo.btType := 39;
                11: m_PetInfo.btType := 44;
                12: m_PetInfo.btType := 45;
                13: m_PetInfo.btType := 46;
                14: m_PetInfo.btType := 41;
                15: m_PetInfo.btType := 47;
            end;
            end;
          end;
          nCode := 8;
          SendPetInfo($03);
          nCode := 9;
      end;
      end else begin
      nCode := 10;
      m_PackPet := nil;
      m_nSlaveKillMonCount := m_PetInfo.nMakeIndex;
      m_PetInfo.nMakeIndex := 0;
      SysMsg('灵兽守摊结束', c_Red, t_Hint);
      end;
    end;
    //凤凰探宝
    if m_PetInfo.nMakeIndex <> 0 then begin
      nCode := 11;
      if GetUserItemByMakeIndex(m_PetInfo.nMakeIndex, UserItem) >= 0 then begin
      nCode := 12;
      tm := MakeLong(MakeWord(UserItem.btValue, UserItem.btValue), MakeWord(UserItem.btValue, UserItem.btValue));
      if (DateTimeToWolTIme(Now) - tm) < 4 * 86400 then begin
          nCode := 13;
          m_PetInfo.wLevel := MakeWord(UserItem.btValue, UserItem.btValue);
          m_PetInfo.btType := 0;
          m_PetInfo.btReLive := UserItem.btValue;
          m_PetInfo.btRideFightSpeed := UserItem.btRideSpeed;
          m_PetInfo.btAttack := UserItem.btExtra.btAttack;                                       //骑战技能攻击距离
          StdItem := UserEngine.GetStdItem(UserItem.wIndex);
          if (StdItem <> nil) then begin
            if (UserItem.btValue > 0) then begin
            nCode := 14;
            case StdItem.AniCount of
                0: m_PetInfo.btType := 10 + UserItem.btValue;
                1: m_PetInfo.btType := 13 + UserItem.btValue;
                2: m_PetInfo.btType := 16 + UserItem.btValue;
                3: m_PetInfo.btType := 19 + UserItem.btValue;
                4: m_PetInfo.btType := 22 + UserItem.btValue;
                5: m_PetInfo.btType := 25 + UserItem.btValue;
                6: m_PetInfo.btType := 28 + UserItem.btValue;
                7: m_PetInfo.btType := 31 + UserItem.btValue;
                8: m_PetInfo.btType := 34 + UserItem.btValue;
                9: m_PetInfo.btType := 37 + UserItem.btValue;
                10: m_PetInfo.btType := 38 + UserItem.btValue;
                11: m_PetInfo.btType := 43 + UserItem.btValue;
                12: m_PetInfo.btType := 44 + UserItem.btValue;
                13: m_PetInfo.btType := 45 + UserItem.btValue;
                14: m_PetInfo.btType := 40 + UserItem.btValue;
                15: m_PetInfo.btType := 46 + UserItem.btValue;
            end;
            end else begin
            nCode := 15;
            case StdItem.AniCount of
                0: m_PetInfo.btType := 11;
                1: m_PetInfo.btType := 14;
                2: m_PetInfo.btType := 17;
                3: m_PetInfo.btType := 20;
                4: m_PetInfo.btType := 23;
                5: m_PetInfo.btType := 26;
                6: m_PetInfo.btType := 29;
                7: m_PetInfo.btType := 32;
                8: m_PetInfo.btType := 35;
                9: m_PetInfo.btType := 38;
                10: m_PetInfo.btType := 39;
                11: m_PetInfo.btType := 44;
                12: m_PetInfo.btType := 45;
                13: m_PetInfo.btType := 46;
                14: m_PetInfo.btType := 41;
                15: m_PetInfo.btType := 47;
            end;
            end;
          end;
          nCode := 16;
          SendPetInfo($09);
          nCode := 17;
      end else begin
          nCode := 18;
          ClientPhoenixSearch(m_PetInfo.nMakeIndex, 1);                                          //召回凤凰
          nCode := 19;
      end;
      end else begin
      m_PetInfo.nMakeIndex := 0;
      end;
    end;
    nCode := 20;
    //魂佑附体
    if m_PetInfo.nMakeIndex <> 0 then begin
      if GetUserItemByMakeIndex(m_PetInfo.nMakeIndex, UserItem) >= 0 then begin
      nCode := 21;
      tm := MakeLong(MakeWord(UserItem.btValue, UserItem.btValue), MakeWord(UserItem.btValue, UserItem.btValue));
      if (DateTimeToWolTIme(Now) - tm) < 4 * 86400 then begin
          nCode := 22;
          m_PetInfo.wLevel := MakeWord(UserItem.btValue, UserItem.btValue);
          m_PetInfo.btType := 0;
          m_PetInfo.btReLive := UserItem.btValue;
          m_PetInfo.btRideFightSpeed := UserItem.btRideSpeed;
          m_PetInfo.boUnWater := (UserItem.btItemExt <> 0);                                  //避水灵性
          m_PetInfo.btSoul := byte(UserItem.btItemExt >= 2);                                 //魂佑灵兽
          m_PetInfo.btAttack := UserItem.btExtra.btAttack;                                       //骑战技能攻击距离
          nCode := 23;
          StdItem := UserEngine.GetStdItem(UserItem.wIndex);
          if (StdItem <> nil) then begin
            nCode := 24;
            if (UserItem.btValue > 0) then begin
            nCode := 25;
            case StdItem.AniCount of
                0: m_PetInfo.btType := 10 + UserItem.btValue;
                1: m_PetInfo.btType := 13 + UserItem.btValue;
                2: m_PetInfo.btType := 16 + UserItem.btValue;
                3: m_PetInfo.btType := 19 + UserItem.btValue;
                4: m_PetInfo.btType := 22 + UserItem.btValue;
                5: m_PetInfo.btType := 25 + UserItem.btValue;
                6: m_PetInfo.btType := 28 + UserItem.btValue;
                7: m_PetInfo.btType := 31 + UserItem.btValue;
                8: m_PetInfo.btType := 34 + UserItem.btValue;
                9: m_PetInfo.btType := 37 + UserItem.btValue;
                10: m_PetInfo.btType := 38 + UserItem.btValue;
                11: m_PetInfo.btType := 43 + UserItem.btValue;
                12: m_PetInfo.btType := 44 + UserItem.btValue;
                13: m_PetInfo.btType := 45 + UserItem.btValue;
                14: m_PetInfo.btType := 40 + UserItem.btValue;
                15: m_PetInfo.btType := 46 + UserItem.btValue;
            end;
            end else begin
            nCode := 26;
            case StdItem.AniCount of
                0: m_PetInfo.btType := 11;
                1: m_PetInfo.btType := 14;
                2: m_PetInfo.btType := 17;
                3: m_PetInfo.btType := 20;
                4: m_PetInfo.btType := 23;
                5: m_PetInfo.btType := 26;
                6: m_PetInfo.btType := 29;
                7: m_PetInfo.btType := 32;
                8: m_PetInfo.btType := 35;
                9: m_PetInfo.btType := 38;
                10: m_PetInfo.btType := 39;
                11: m_PetInfo.btType := 44;
                12: m_PetInfo.btType := 45;
                13: m_PetInfo.btType := 46;
                14: m_PetInfo.btType := 41;
                15: m_PetInfo.btType := 47;
            end;
            end;
          end;
          nCode := 27;
          m_boBeast := True;
          UserItem.btItemExt := 3;
          SendUpdateItem(UserItem, False);
          SendDefMessage(1283, Integer(Self), m_nCurrX, m_nCurrY, 65535, '');
          SendRefMsg(RM_510, 1, 0, 170, 0, '');
          SendPetInfo($0A);
          RecalcPetSoulAbilitys;
          nCode := 28;
      end else begin
          nCode := 29;
          m_PetInfo.nMakeIndex := 0;
          UserItem.btItemExt := 2;
          SendUpdateItem(UserItem, False);
          nCode := 30;
      end;
      nCode := 31;
      RecalcAbilitys();                                                                           //重新计算属性
      SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
      SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
      nCode := 32;
      end;
    end;
except
    on E: Exception do
      MainOutMessage(Format(sExceptionMsg, ));
end;
end;

//检测是否有 潜行

procedure TPlayObject.CheckProwlMagic();
var
i                                     : Integer;
BaseObject                            : TBaseObject;
VisibleBaseObject                     : pTVisibleBaseObject;
begin
if m_boObMode and (m_wStatusTimeArr > 0) then begin
    m_boObMode := False;
    for i := 0 to m_VisibleActors.Count - 1 do begin
      VisibleBaseObject := pTVisibleBaseObject(m_VisibleActors.Items);
      BaseObject := TBaseObject(VisibleBaseObject.BaseObject);
      if BaseObject.m_btRaceServer = RC_PLAYOBJECT then
      TPlayObject(BaseObject).SendMsg(Self,
          RM_TURN, m_btDirection, m_nCurrX, m_nCurrY, CalcCent(m_WAbil.dwHP, m_WAbil.dwMaxHP), GetShowName);
    end;
    m_wStatusTimeArr := 1;
end;
end;

//检测用户身上过期装备

function TPlayObject.CheckUserItemTimeOut(UserItem: pTUserItem; StdItem: pTStdItem): Boolean;
var
tm, nowtm                           : DWORD;
begin
Result := False;
tm := 0;
if (StdItem.StdMode = 18) or ((StdItem.StdMode = 29) and (StdItem.Shape = 150)) then begin
    if (StdItem.StdMode = 29) and (StdItem.Shape = 150) and (StdItem.AniCount = 1) then
      tm := MakeLong(MakeWord(UserItem.btItemExt, UserItem.btItemExt), MakeWord(UserItem.btItemExt, UserItem.btItemExt))
    else
      tm := MakeLong(MakeWord(UserItem.btValue, UserItem.btValue), MakeWord(UserItem.btValue, UserItem.btValue));
    if (tm = 0) then begin                                                                        //第一次使用
      tm := DateTimeToWolTIme(Now);
      if (StdItem.StdMode = 29) and (StdItem.Shape = 150) and (StdItem.AniCount = 1) then begin
      UserItem.btItemExt := LoByte(LoWord(tm));
      UserItem.btItemExt := HiByte(LoWord(tm));
      UserItem.btItemExt := LoByte(HiWord(tm));
      UserItem.btItemExt := HiByte(HiWord(tm));
      end else begin
      UserItem.btValue := LoByte(LoWord(tm));
      UserItem.btValue := HiByte(LoWord(tm));
      UserItem.btValue := LoByte(HiWord(tm));
      UserItem.btValue := HiByte(HiWord(tm));
      end;
      SendUpdateItem(UserItem);
    end else begin
      nowtm := DateTimeToWolTIme(Now);
      if (StdItem.Shape = 150) and (tm + Round(UserItem.Dura / 1000) * 86400 < nowtm) then begin
      Result := True;
      end;
    end;
end else if (StdItem.StdMode = 6) and (StdItem.Shape = 20) and (StdItem.AniCount > 0) then begin
    tm := MakeLong(MakeWord(UserItem.btItemExt2, UserItem.btItemExt2), MakeWord(UserItem.btItemExt2, UserItem.btItemExt2));
    if (tm = 0) then begin
      tm := DateTimeToWolTIme(Now);
      UserItem.btItemExt2 := LoByte(LoWord(tm));
      UserItem.btItemExt2 := HiByte(LoWord(tm));
      UserItem.btItemExt2 := LoByte(HiWord(tm));
      UserItem.btItemExt2 := HiByte(HiWord(tm));
      SendUpdateItem(UserItem);
    end else begin
      nowtm := DateTimeToWolTIme(Now);
      if (tm + Round(StdItem.AniCount * 60) < nowtm) then begin
      Result := True;
      end;
    end;
end;
end;

procedure TPlayObject.ClearEvilFollower(nCode: Integer);
var
i                                     : Integer;
BaseObject                            : TBaseObject;
boChg                                 : Boolean;
begin
boChg := False;
for i := m_SlaveList.Count - 1 downto 0 do begin
    BaseObject := TBaseObject(m_SlaveList);
    if (BaseObject.m_btRaceServer = RC_EVIL) and (BaseObject.m_nSlaveType <> -2) then begin
      case nCode of
      0: begin
            BaseObject.m_dwEvilUniQueSkillTick := GetTickCount;                                     //心魔绝杀
            BaseObject.m_nCharStatus := BaseObject.GetCharStatus();
            BaseObject.StatusChanged();
          end;
      1: begin                                                                                    //心魔红名
            BaseObject.m_btNameColor := $F9;
            BaseObject.RefNameColor;
            BaseObject.RefShowName;
          end;
      2: begin                                                                                    //冻结心魔
            BaseObject.MakePosion(POISON_DONTMOVE, 6000, 0);
          end;
      3: begin                                                                                    //释放心魔
            SysMsg(Format('你的宠物(%s)叛变了', ), c_Pink, t_Hint);
            BaseObject.m_Master := nil;
            BaseObject.m_boSuperMan := False;
            BaseObject.m_wStatusTimeArr := 1;
            BaseObject.RefNameColor;
            BaseObject.RefShowName;
            BaseObject.HealthSpellChanged;
            m_SlaveList.Delete(i);
            SendDefMessage(CM_RECALLEVIL, 0, 1, 0, 0, '');
            m_nEvilFollowerPower := 0;
            boChg := True;
          end;
      4: begin                                                                                    //解除心魔冻结
            if BaseObject.m_wStatusTimeArr > 0 then begin
            BaseObject.m_wStatusTimeArr := 1;
            end;
            if (BaseObject.m_btNameColor <> $FF) then begin
            BaseObject.m_btNameColor := $FF;
            BaseObject.RefNameColor;
            BaseObject.RefShowName;
            end;
            BaseObject.HealthSpellChanged;
          end;
      5: begin
            BaseObject.HealthSpellChanged;
          end;
      6: begin
            BaseObject.MakeGhost;
            m_SlaveList.Delete(i);
            SendDefMessage(CM_RECALLEVIL, 0, 1, 0, 0, '');
            m_nEvilFollowerPower := 0;
            boChg := True;
          end;
      end;
    end;
end;
if boChg then ClientQueryEvilFollower();
end;

//清除人物状态时间标志

procedure TPlayObject.ClearStatusTime;
begin
FillChar(m_wStatusTimeArr, SizeOf(TStatusTime), 0);
end;

{查看棋座??}

procedure TPlayObject.ClickQueryMsg(NPCID: Integer; btnid: Integer);
function CheckBagItemDura(sItemName: string; nItemCount: Integer): Integer;
var
    i, nCurCount                        : Integer;
    UserItem                            : pTUserItem;
    StdItem                           : pTStdItem;
    nIndex                              : Integer;
begin
    Result := 0;
    if sItemName = '' then Exit;
    if nItemCount <= 0 then Exit;
    nIndex := UserEngine.GetStdItemIdx(sItemName);
    if nIndex > 0 then begin
      StdItem := UserEngine.GetStdItem(nIndex);
      if StdItem = nil then Exit;

      for i := m_ItemList.Count - 1 downto 0 do begin
      if nItemCount <= 0 then Break;
      UserItem := pTUserItem(m_ItemList.Items);
      if UserItem = nil then Exit;
      if UserItem.wIndex = nIndex then begin

          nCurCount := 0;
          if UserItem.Dura > nItemCount then begin
            nCurCount := nItemCount;
          end else begin
            nCurCount := UserItem.Dura;
          end;
          Dec(nItemCount, nCurCount);
          Inc(Result, nCurCount);
      end;
      end;
    end;
end;
function TakeBagItemDura(sItemName: string; nItemCount: Integer): Integer;
var
    i, nCurCount                        : Integer;
    UserItem                            : pTUserItem;
    StdItem                           : pTStdItem;
    nIndex                              : Integer;
begin
    Result := 0;
    if sItemName = '' then Exit;
    if nItemCount <= 0 then Exit;
    nIndex := UserEngine.GetStdItemIdx(sItemName);
    if nIndex > 0 then begin
      StdItem := UserEngine.GetStdItem(nIndex);
      if StdItem = nil then Exit;

      for i := m_ItemList.Count - 1 downto 0 do begin
      if nItemCount <= 0 then Break;
      UserItem := pTUserItem(m_ItemList.Items);
      if UserItem = nil then Exit;
      if UserItem.wIndex = nIndex then begin

          if StdItem.boGameLog = 1 then
            AddGameDataLog('10' + #9 +
            m_sMapName + #9 +
            IntToStr(m_nCurrX) + #9 +
            IntToStr(m_nCurrY) + #9 +
            m_sCharName + #9 +
            sItemName + #9 +
            IntToStr(UserItem.MakeIndex) + #9 +
            '1' + #9 +
            m_sCharName);

          nCurCount := 0;
          if UserItem.Dura > nItemCount then begin
            nCurCount := nItemCount;
            Dec(UserItem.Dura, nItemCount);
            SendUpdateItem(UserItem);
          end else begin
            nCurCount := UserItem.Dura;
            SendDelItems(UserItem);
            if UserItem.MakeIndex = m_nEatItemMakeIndex then
            m_nEatItemMakeIndex := 0;
            Dispose(UserItem);
            m_ItemList.Delete(i);
          end;
          Dec(nItemCount, nCurCount);
          Inc(Result, nCurCount);
      end;
      end;
    end;
end;
var
NPC                                 : TNormNpc;
nMakeIndex                            : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
begin
NPC := UserEngine.FindMerchant(TObject(NPCID));
if NPC = nil then NPC := UserEngine.FindNPC(TObject(NPCID));
if NPC <> nil then begin
    if NPC = nil then Exit;
    if m_sNextLabel <> '' then begin
      try
      NPC.GotoLable(Self, m_sNextLabel + IntToStr(btnid), False);
      except

      end;
    end;
end else begin
    //破碎物品修复
    if (Pos('Fracture', m_sNextLabel) > 0) and (btnid = 1) then begin
      nMakeIndex := Str_ToInt(Copy(m_sNextLabel, 10, Length(m_sNextLabel)), 0);
      GetUserItemByMakeIndex(nMakeIndex, UserItem);
      if UserItem <> nil then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem <> nil then begin
          if CheckBagItemDura('五色晶石', StdItem.Broken) >= StdItem.Broken then begin
            UserItem.btItemExt := 0;
            UserItem.Dura := UserItem.DuraMax;
            SendUpdateItem(UserItem);
            TakeBagItemDura('五色晶石', StdItem.Broken);
          end else SendMsg(Self, RM_SYSMESSAGE, 0, 255, 253, 0,
            '你包裹中没有五色晶石或者其持久不够,请到商城购买后再进行修复。');
      end;
      end;
    end;
end;
end;

resourcestring
sTreasureName                         = '灵犀宝盒';
sHaveNoNimBusPoint                  = '你身上没有这么多灵力,无法为灵犀宝盒注入灵力。';
sNeedInjectPower                      = '灵犀宝盒的灵力耗尽,不能向宝盒中存入物品和从宝盒中取出物品,需要重新冲入灵力。';
sCanNotInTreasureBox                  = '灵犀宝盒储物能力有限,不能保存%s';

procedure TPlayObject.ClientActivationTreasureBox();
var
UserItem                              : TUserItem;
pStdItem                              : pTStdItem;
tm                                    : DWORD;
d                                     : TDateTime;
begin
if m_boGhost or
    m_boDeath or
    (m_TreasureBoxItem <> nil) or
    (m_TreasureBoxItemList.Count > 0) then
    Exit;

if (m_Abil.wNimBusPoint < 10) then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, sHaveNoNimBusPoint);
    Exit;
end;

if UserEngine.CopyToUserItemFromName(sTreasureName, @UserItem) then begin
    Dec(m_Abil.wNimBusPoint, 10);
    RecalcAbilitys();
    SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
    tm := DateTimeToWolTimeEx(Now);
    Move(tm, UserItem.btValue, 4);                                                               //激活时间
    tm := DateTimeToWolTimeEx(AddDateTimeOfDay(Now, 8));                                          //到期时间
    Move(tm, UserItem.btValue, 4);
    UserItem.Dura := 0;
    UserItem.DuraMax := 10;                                                                         //开通的格子数量
    New(m_TreasureBoxItem);
    m_TreasureBoxItem^ := UserItem;
    ClientQueryTreasureBoxItems(False);
end else begin
    SysMsg('本功能尚未开放,敬请期待!', c_Red, t_Hint);
end;
end;

function TPlayObject.GetEvilRecByMakeIndex(nItemMakeIndex: Integer): pTEvil;
begin

end;

procedure TPlayObject.DelEvilRec(nItemMakeIndex: Integer; DisMem: Boolean = True);
begin

end;

{增加装备装备镇魔值}

procedure TPlayObject.ClientAddAntiEvilPower(nWhere: word; nMakeIndex,
nAntiEvilItem: Integer);
var
i                                     : Integer;
UserItem, Item                        : pTUserItem;
StdItem, StdItem34                  : pTStdItem;
nA, nB                              : word;
boOk                                  : Boolean;
begin
boOk := False;
nA := 0;
nB := 0;
if not m_boCanUseItem then Exit;
if (not m_boDeath) and (not m_boGhost) then begin
    GetUserItemByMakeIndex(nAntiEvilItem, UserItem);
    if nWhere = 256 then begin
      GetUserItemByMakeIndex(nMakeIndex, Item)
    end else begin
      Item := nil;
      if (nWhere < MAX_HUMITEM_COUNT) and (m_UseItems.wIndex > 0) then
      Item := @m_UseItems;                                                                //装备
    end;
    if (UserItem <> nil) and (Item <> nil) and (Item.MakeIndex = nMakeIndex) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);                                          //镇魔符
      StdItem34 := UserEngine.GetStdItem(Item.wIndex);                                              //装备
      if (StdItem34 <> nil) and (StdItem <> nil) then begin
      if UserItem.Dura > 0 then begin
          {镇魔值}
          if (Item.Evil.wPower >= 65000) then begin
            SysMsg(Format('%s的镇魔力量已经很强了,不需要在增加镇魔值!', ), c_Red, t_Hint);
            Exit;
          end;
          Item.Evil.wPower := _MIN(65000, Item.Evil.wPower + StdItem.AC * 1000);
          {黑暗魔力}
          if g_Config.boAntiEvilItemAddGloomPoint then begin
            nA := StdItem.AC * g_Config.nAddGloomPointRate + Random(g_Config.nAddGloomRandomPoint);
            Move(Item.btItemExt, nB, 2);
            nA := _MIN(High(word), nA + nB);
            Move(nA, Item.btItemExt, 2);
          end;
          {触发脚本}
          m_sScriptParam := Item.Evil.sName;
          m_sScriptParam := IntToStr(nWhere);
          m_sScriptParam := IntToStr(Item.MakeIndex);
          m_sScriptParam := IntToStr(UserItem.MakeIndex);
          m_sScriptParam := StdItem34.Name;
          m_sScriptParam := StdItem.Name;
          ExecuteScript(g_FunctionNPC, '@增加镇魔值');
          SendUpdateItem(Item);
          if nWhere = 256 then
            SendDefMessage(SM_ANTIEVILPOWER, Item.MakeIndex, Item.Evil.wPower, nWhere, 0, '');      //刷新镇魔值
          if not boOk then begin
            if (Item.Evil.wPower >= 65000) then
            SysMsg(Format('%s的镇魔值已满,黑暗魔力进一步提升!', ), c_Red, t_Hint)
            else
            SysMsg(Format('%s的镇魔值和黑暗魔力同时获得了提升!', ), c_Red, t_Hint);
          end;
          SendDefMessage(SM_EAT_OK, 0, 0, 0, 0, '');
          Dec(UserItem.Dura);
          SendUpdateItem(UserItem);
      end;
      end;
      if UserItem.Dura <= 0 then begin
      SendDelItems(UserItem);
      DelBagItem(UserItem.MakeIndex, UserEngine.GetStdItemName(UserItem.wIndex));
      end;
    end;
end;
end;

//添加要交易的物品

procedure TPlayObject.ClientAddDealItem(nItemIdx: Integer; sItemName: string);
var
i, ii                                 : Integer;
bo11                                  : Boolean;
UserItem                              : pTUserItem;
sName                                 : string;
StdName                               : string;
tm                                    : DWORD;
StdItem                               : pTStdItem;
begin
if (m_DealCreat = nil) or (not m_boDealing) then Exit;
bo11 := False;
if not m_DealCreat.m_boDealOK then begin
    for i := m_ItemList.Count - 1 downto 0 do begin
      UserItem := m_ItemList.Items;
      if UserItem.MakeIndex = nItemIdx then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem = nil then Break;
      //物品控制-禁止交易物品
      if CheckSPCode(StdItem.SPCode, SP_DISABLESALE) or
          ((UserItem.btItemExt and EX_BIND) = EX_BIND) then begin
          bo11 := False;
          Break;
      end;

      {魂佑灵兽禁止交易}
      if (StdItem.StdMode = 49) and (StdItem.Shape = 51) and (UserItem.btItemExt >= 2) then
          Break;

      {已放出豹禁止交易}
      if IsDownPetItem(UserItem.MakeIndex) then
          Break;

      {自定义物品名称}
      sName := '';
      ItemUnit.GetCustomItemName(UserItem, sName);

      if (CompareText(sItemName, sName) = 0) and (m_DealItemList.Count < 12) then begin
          m_DealItemList.Add(UserItem);
          TPlayObject(Self).SendAddDealItem(UserItem);
          m_ItemList.Delete(i);
          bo11 := True;
          Break;
      end;
      end;
    end;
end;
if not bo11 then
    SendDefMessage(SM_DEALADDITEM_FAIL, 0, 0, 0, 0, '');
end;

{附加心魔到装备}

procedure TPlayObject.ClientAddEvilToItem(nWhere: word; nMakeIndex, BottleIndex: Integer);
var
boOk                                  : Boolean;
UserItem, BottleItem                  : pTUserItem;
StdItem                               : pTStdItem;
begin
boOk := False;
if not m_boCanUseItem then Exit;
if (not m_boDeath) and (not m_boGhost) then begin
    GetUserItemByMakeIndex(BottleIndex, BottleItem);
    GetUserItemByMakeIndex(nMakeIndex, UserItem);
    if (UserItem <> nil) and (BottleItem <> nil) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem <> nil then begin
      if (BottleItem.Evil.sName = '') or (BottleItem.Evil.MakeIndex = 0) then begin
          SysMsg('无法从玉净瓶中感应到心魔气息,不能附魔!', c_Red, t_Hint);
          Exit;
      end;
      if CheckSPCode(StdItem.SPCode, SP_DISABLEGETEVIL) then begin                              //物品控制-禁止附魔
          SysMsg('该物品不能用于被附魔!', c_Red, t_Hint);
          Exit;
      end;
      if BottleItem.Evil.wPower < 2000 then begin
          SysMsg('玉净瓶的镇魔力量太弱,不能附魔!', c_Red, t_Hint);
          Exit;
      end else begin
          m_sScriptParam := BottleItem.Evil.sName;
          m_sScriptParam := IntToStr(nWhere);
          m_sScriptParam := IntToStr(UserItem.MakeIndex);
          m_sScriptParam := IntToStr(BottleItem.MakeIndex);
          m_sScriptParam := UserEngine.GetStdItemName(UserItem.wIndex);
          m_sScriptParam := UserEngine.GetStdItemName(BottleItem.wIndex);

          boOk := ExecuteScript(g_FunctionNPC, '@装备附魔');
          {直接给装备附魔}
          if not boOk then
            AddEvilToItemB(nWhere, nMakeIndex, BottleIndex);
      end;
      end;
    end;
end;
end;

//添加好友

procedure TPlayObject.ClientAddFriend(FriendName: string);
var
i, j                                  : Integer;
s                                     : string;
human                                 : TPlayObject;
C                                     : Char;
begin
//检查好友数量,不能超过100个
if m_FriendsList.Count >= _MIN(g_Config.nFriendCount, MAX_FRIENDS_COUNT) then begin
    SysMsg('你的好友数量已经达到最大,请删除一部分后再添加。', c_Red, t_Hint);
    Exit;
end;

//首先检查是否在已经有的好友名单中
for i := 0 to m_FriendsList.Count - 1 do begin
    if m_FriendsList = FriendName then begin
      //已经在好友列表中
      SendDefMessage(SM_RefuseAddFriend, 5, 0, 0, 0, FriendName);
      Exit;
    end;
end;
human := UserEngine.GetPlayObject(FriendName);
//对方在线
if (human <> nil) and (not human.m_boDeath) and (not human.m_boGhost) then begin
    //检查对方是否允许加为好友
    if human.m_boAllowAddFriend then begin
      human.SendDefMessage(SM_ReqAddFriend, 2, 0, 0, 0, m_sCharName);
      m_sScriptParam := FriendName;
      ExecuteScript(g_ManageNPC, '@人脉_添加好友');
    end else
      SysMsg(FriendName + '玩家暂时不能被添加为好友,添加失败。', c_Red, t_Hint);
end else begin                                                                                    //名字错误,或者不在线
    SendDefMessage(SM_RefuseAddFriend, 2, 0, 0, 0, FriendName);
end;
end;

//增加队伍成员

procedure TPlayObject.ClientAddGroupMember(sHumName: string);                                       //004DCE48
var
PlayObject                            : TPlayObject;
i                                     : Integer;
begin
PlayObject := UserEngine.GetPlayObject(sHumName);
if m_GroupOwner <> Self then begin
    SendDefMessage(SM_GROUPADDMEM_FAIL, -1, 0, 0, 0, '');
    Exit;
end;
if m_GroupMembers.Count > g_Config.nGroupMembersMax then begin
    SendDefMessage(SM_GROUPADDMEM_FAIL, -5, 0, 0, 0, '');
    Exit;
end;
if (PlayObject = nil) or (PlayObject = Self) or PlayObject.m_boDeath or
    PlayObject.m_boGhost then begin
    SendDefMessage(SM_GROUPADDMEM_FAIL, -2, 0, 0, 0, '');
    Exit;
end;

if (PlayObject.m_PEnvir <> m_PEnvir) then begin                                                   //增加控制:只有在同一地图才可以加入组队
    SendDefMessage(SM_GROUPADDMEM_FAIL, -2, 0, 0, 0, '');
    Exit;
end;

if (PlayObject.m_GroupOwner <> nil) then begin
    SendDefMessage(SM_GROUPADDMEM_FAIL, -3, 0, 0, 0, '');
    Exit;
end;

if (PlayObject.m_boPneuma) then begin
    SendDefMessage(SM_GROUPADDMEM_FAIL, -2, 0, 0, 0, '');
    Exit;
end;

//增加判断,组队中不允许同名队员xyfate 2005/10/19
for i := 0 to m_GroupMembers.Count - 1 do begin
    if m_GroupMembers = sHumName then begin
      SendDefMessage(SM_GROUPADDMEM_FAIL, -2, 0, 0, 0, '');
      Exit;
    end;
end;

if (not PlayObject.m_boAllowGroup) then begin
    SendDefMessage(SM_GROUPADDMEM_FAIL, -4, 0, 0, 0, '');
    Exit;
end;
m_GroupMembers.AddObject(sHumName, PlayObject);
PlayObject.JoinGroup(Self);
SendDefMessage(SM_GROUPADDMEM_OK, 0, 0, 0, 0, '');
SendGroupMembers();
ExecuteScript(g_FunctionNPC, '@_加入队伍');
end;

//调整属性值

procedure TPlayObject.ClientAdjustBonus(nPoint: Integer; sMsg: string);
//004DF804
var
BonusAbil                           : TNakedAbility;
nTotleUsePoint                        : Integer;
begin
FillChar(BonusAbil, SizeOf(TNakedAbility), #0);
DeCodeBuffer(sMsg, @BonusAbil, SizeOf(TNakedAbility));

nTotleUsePoint := BonusAbil.DC +
    BonusAbil.MC +
    BonusAbil.SC +
    BonusAbil.AC +
    BonusAbil.MAC +
    BonusAbil.HP +
    BonusAbil.MP +
    BonusAbil.Hit +
    BonusAbil.Speed +
    BonusAbil.X2;

if (nPoint + nTotleUsePoint) = m_nBonusPoint then begin
    m_nBonusPoint := nPoint;
    Inc(m_BonusAbil.DC, BonusAbil.DC);
    Inc(m_BonusAbil.MC, BonusAbil.MC);
    Inc(m_BonusAbil.SC, BonusAbil.SC);
    Inc(m_BonusAbil.AC, BonusAbil.AC);
    Inc(m_BonusAbil.MAC, BonusAbil.MAC);
    Inc(m_BonusAbil.HP, BonusAbil.HP);
    Inc(m_BonusAbil.MP, BonusAbil.MP);
    Inc(m_BonusAbil.Hit, BonusAbil.Hit);
    Inc(m_BonusAbil.Speed, BonusAbil.Speed);
    Inc(m_BonusAbil.X2, BonusAbil.X2);

    RecalcAbilitys();
    SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
    SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
end else begin
    SysMsg('非法数据调整!!!', c_Red, t_Hint);
end;
end;

procedure TPlayObject.ClientDECOMPOSE(nParam, nMakeIndex: Integer);
var
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
begin
m_sScriptParam := '';
m_sScriptParam := '';
if m_boGhost or m_boDeath then Exit;

if nMakeIndex > 0 then begin
    GetUserItemByMakeIndex(nMakeIndex, UserItem);
    if (UserItem <> nil) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem <> nil then begin
      m_sScriptParam := StdItem.Name;
      m_sScriptParam := IntToStr(nMakeIndex);
      case nParam of
          1: ExecuteScript(g_FunctionNPC, '@拆卸装备');
          0: ExecuteScript(g_FunctionNPC, '@拆卸开始');
      end;
      end;
    end;
end;
end;

procedure TPlayObject.ClientGEMREMOVE(nWhere, nMakeIndex: Integer);
var
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
ANpc                                  : TNormNpc;
begin
m_sScriptParam := '';
m_sScriptParam := '';
m_sScriptParam := '';
if m_boGhost or m_boDeath then Exit;
if m_ClickNPC = nil then Exit;
ANpc := TNormNpc(m_ClickNPC);

if nMakeIndex > 0 then begin
    GetUserItemByMakeIndex(nMakeIndex, UserItem);
    if (UserItem <> nil) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem <> nil then begin
      m_sScriptParam := StdItem.Name;
      m_sScriptParam := IntToStr(nMakeIndex);
      m_sScriptParam := IntToStr(nWhere);
      if (IsEnvir(ANpc.m_PEnvir) and (abs(ANpc.m_nCurrX - m_nCurrX) < 15) and (abs(ANpc.m_nCurrY - m_nCurrY) < 15)) or (ANpc.m_boIsHide) then begin
          ANpc.GotoLable(Self, '@@gemremove', False);
      end;
      end;
    end;
end;
end;

procedure TPlayObject.ClientYiWangDan(nMakeIndex: Integer; sSkillName: string);
var
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
Magic                                 : pTMagic;
UserMagic                           : pTUserMagic;
begin
if nMakeIndex > 0 then begin
    GetUserItemByMakeIndex(nMakeIndex, UserItem);
    if (UserItem <> nil) then begin
      DelItemSkill(sSkillName);
      SysMsg(Format('技能%s已删除。', ), c_Green, t_Hint);
      RecalcAbilitys();
      SendDelItems(UserItem);
      DelBagItem(UserItem.MakeIndex, '');
    end;
end;
end;

procedure TPlayObject.ClientAllotGuildGold(sName: string; nGold: Integer);
var
Hum                                 : TPlayObject;
begin
if m_boGhost or m_boDeath then Exit;
if m_MyGuild = nil then Exit;
if (TGuild(m_MyGuild).GetChiefName <> m_sCharName) then begin
    SysMsg('你不是行会会长,没有权限执行此操作!', c_Red, t_Hint);
    Exit;
end;
if (nGold <= 0) or (nGold > TGuild(m_MyGuild).dwGuildGold) then begin
    SysMsg('你输入的分配数量错误,请重新输入!', c_Red, t_Hint);
    Exit;
end;
Hum := UserEngine.GetPlayObject(sName);
if (Hum <> nil) and (not Hum.m_boGhost) and (not Hum.m_boDeath) then begin
    if TGuild(m_MyGuild).IsMember(sName) then begin
      TGuild(m_MyGuild).dwGuildGold := TGuild(m_MyGuild).dwGuildGold - nGold;
      //      SendDefMessage(SM_ALLOTGUILDGOLD, nGold, 0, 0, 0, sName);
      Inc(Hum.m_nGuildGold, nGold);
      Hum.GuildGoldChanged;
      SendGuildTowerRes;
      SysMsg('你成功分配了' + IntToStr(nGold) + '行会公共银两给' + sName + '。', c_Red, t_Hint);
      Hum.SysMsg(m_sCharName + '分配给你' + IntToStr(nGold) + '行会公共银两。', c_Red, t_Hint);
    end else
      SysMsg(sName + '已经不是本行会成员,无法分配行会银两!', c_Red, t_Hint);
end else
    SysMsg(sName + '已经不在线了,无法分配行会银两!', c_Red, t_Hint);
end;

procedure TPlayObject.ClientAskForGuildOfficial(nRankNo: Integer; sData: string);
var
sOfficialName                         : string;
Official                              : TPlayObject;
nTowerGrade                           : Integer;
begin
if (not (nRankNo in )) or (sData = '') then Exit;
if m_MyGuild = nil then Exit;
nTowerGrade := TGuild(m_MyGuild).btTowerGrade;
nTowerGrade := _MIN(10, nTowerGrade);
if (nTowerGrade <= 0) or (nGuildOfficialCount = 0) or (TGuild(m_MyGuild).GetRankMemberCount(nRankNo) >= nGuildOfficialCount) then begin
    SysMsg('当前职位尚未设立,无法任命该职位!', c_Red, t_Hint);
    Exit;
end;
if (TGuild(m_MyGuild).GetChiefName <> m_sCharName) then begin
    SysMsg('你不是行会会长,没有权限执行此操作!', c_Red, t_Hint);
    Exit;
end;
sData := GetValidStr3(sData, sOfficialName, ['/']);
if (sOfficialName <> '') then Official := UserEngine.GetPlayObject(sOfficialName);
if (sData <> '') then begin
    TGuild(m_MyGuild).GetOfficial(99, g_Config.sGuildMemberRank, sData);                            //撤职查办
end;
if (Official <> nil) then begin
    if (Official = Self) then begin
      SysMsg('不可以任命自己!', c_Red, t_Hint);
      Exit;
    end;
    if (Official.m_btRaceServer <> RC_PLAYOBJECT) or (Official.m_boPneuma) then begin
      SysMsg('任命失败!!!', c_Red, t_Hint);
      Exit;
    end;
    if Official.m_MyGuild = m_MyGuild then begin
      if Official.m_nGuildGold >= nGuildOfficialPrice then begin
      Official.SendDefMessage(SM_QUESTGUILDOFFICIAL, 50, nRankNo, LoWord(Integer(Official)), HiWord(Integer(Official)), m_sCharName);
      m_GuildOfficial := nRankNo;
      end else
      SysMsg(sOfficialName + '行会银两不足' + IntToStr(nGuildOfficialPrice) + '个,无法任命该职位!', c_Red, t_Hint);
    end else
      SysMsg(sOfficialName + '非本行会成员,无法任命该职位!', c_Red, t_Hint);
end else
    SysMsg(sOfficialName + '不在线,无法任命该职位!', c_Red, t_Hint);
end;

procedure TPlayObject.ClientCallTiger();
const
sTigerName                            : string = '啸天虎';
sDragonName                           : array of string = ('金甲龙王', '紫衫龙王', '碧铠龙王');
var
StdItem                               : pTStdItem;
dwNowWolTime                        : DWORD;
i, nReCallTime                        : Integer;
sName                                 : string;
begin
if m_boGhost or m_boDeath or m_boPneuma then Exit;
if m_btJob = 3 then Exit;                                                                         //妖士是没有虎王盾的

if (m_TorDDM.Tiger.DB.Dragon > 0) then sName := '龙' else sName := '虎';

if m_PEnvir.m_MapFlag.boNOTIGER then begin
    SysMsg(Format('本地图禁止释放%s王。', ), c_Red, t_Hint);
    Exit;
end;

//召唤虎王
if m_Tiger = nil then begin
    StdItem := nil;
    if (m_UseItems.wIndex > 0) then begin
      StdItem := UserEngine.GetStdItem(m_UseItems.wIndex);
    end;

    if (m_TorDDM.Tiger.DB.Dragon = 0) and ((StdItem = nil) or (not StdItem.Shape in )) then begin
      SysMsg('只有佩戴虎王盾才能放出虎王。', c_Red, t_Hint);
      Exit;
    end;

    if (m_TorDDM.Tiger.DB.Dragon > 0) and ((StdItem = nil) or (not StdItem.Shape in )) then begin
      SysMsg('只有佩戴龙王盾才能放出龙王。', c_Red, t_Hint);
      Exit;
    end;

    if (m_TorDDM.Tiger.DB.level <= 0) then begin
      SysMsg(Format('%s王等级小于1级,不能召出%s王。', ), c_Red, t_Hint);
      Exit;
    end;

    if (m_TorDDM.Tiger.Abil.MaxHP <= 0) then begin
      SysMsg(Format('%s王HP为0,不能召出%s王。', ), c_Red, t_Hint);
      Exit;
    end;

    dwNowWolTime := DateTimeToWolTIme(Now);
    case m_TorDDM.Tiger.DB.level of
      0..30: nReCallTime := 1200;
      31..50: nReCallTime := 900;
      51..80: nReCallTime := 600;
    else nReCallTime := 300;
    end;

    //重置虎灵值
    if (m_TorDDM.Tiger.DB.ReCallTick > dwNowWolTime) then m_TorDDM.Tiger.DB.ReCallTick := 0;

    if (dwNowWolTime < (m_TorDDM.Tiger.DB.ReCallTick + nReCallTime)) then begin
      SysMsg(Format('你当前的%s灵值未满,你还需等待%d秒才可释放出%s王。', ), c_Red, t_Hint);
      Exit;
    end;
    if (m_TorDDM.Tiger.DB.Dragon > 0) then begin
      if m_btJob in then sName := sDragonName;
    end else
      sName := sTigerName;

    m_Tiger := TAnimalObject(MakeSlave(sName, m_TorDDM.Tiger.DB.level, m_TorDDM.Tiger.DB.level, 100, 24 * 60 * 60, -1));
    if m_Tiger <> nil then begin
      m_Tiger.m_btTigerDragon := m_TorDDM.Tiger.DB.Dragon + 1;
      if (m_TorDDM.Tiger.DB.Dragon > 0) then
      m_Tiger.m_btJob := m_btJob
      else
      m_Tiger.m_btJob := 0;
      RecalcTigerAbility;
      m_Tiger.m_WAbil.dwHP := m_Tiger.m_WAbil.dwMaxHP;
      m_Tiger.HealthSpellChanged();
      if m_UseItems.sExName <> '' then begin
      m_Tiger.m_sCharName := m_UseItems.sExName;
      m_Tiger.RefShowName;
      end;
      if m_TorDDM.Tiger.DB.Dragon > 0 then
      m_sScriptParam := '1'
      else
      m_sScriptParam := '0';
      ExecuteScript(g_FunctionNPC, '@ReleaseTiger');
    end;
    m_TorDDM.Tiger.DB.ReCallTick := dwNowWolTime;
    SendDefMessage(CM_CALLTIGER, dwNowWolTime, 1, 0, 0, '');
end;
end;

//取消交易

procedure TPlayObject.ClientCancelDeal;
begin
DealCancel();
end;

{玉净瓶俘获心魔}

procedure TPlayObject.ClientCatchEvil(EvilObject: TBaseObject; nMakeIndex:
Integer);
var
UserItem                              : pTUserItem;
begin
if not m_boCanUseItem then Exit;
if (not m_boDeath) and (not m_boGhost) then begin
    if m_PEnvir.IsValidObject(m_nCurrX, m_nCurrY, 1, EvilObject) then begin
      if (EvilObject.m_btRaceServer = RC_EVIL) and (EvilObject.m_btRaceImg in
      ) and (EvilObject.m_boDeath) and (not EvilObject.m_boGhost) then begin
      GetUserItemByMakeIndex(nMakeIndex, UserItem);
      if UserItem = nil then Exit;
      if UserItem.Dura > 0 then begin
          if (UserItem.Evil.MakeIndex = 0) and (UserItem.Evil.sName = '') then begin
            m_sScriptParam := IntToStr(UserItem.MakeIndex);
            m_sScriptParam := IntToStr(EvilObject.m_btAmbitLevel);
            m_sScriptParam := IntToStr(EvilObject.m_btJob);
            m_sScriptParam := EvilObject.m_sFilterCharName;
            m_sScriptParam := EvilObject.m_sCharName;
            m_sScriptParam := IntToStr(Integer(EvilObject));
            ExecuteScript(g_FunctionNPC, '@封印心魔');
          end else
            SysMsg('玉净瓶的魔力有限,无法用来俘获第二个心魔', c_Pink, t_Hint);
      end else begin
          SendDelItems(UserItem);
          DelBagItem(UserItem.MakeIndex, UserEngine.GetStdItemName(UserItem.wIndex));
          SysMsg('玉净瓶已经破碎!!!', c_Red, t_Hint);
      end;
      end;
    end;
end;
end;

//改变交易价格

procedure TPlayObject.ClientChangeDealGold(nGold, nGameGold: Integer);                              //004DDB04
var
bo09                                  : Boolean;
begin
//禁止取回放入交易栏内的金币
if (nGold > 0) and (m_nDealGolds > 0) and g_Config.boCanNotGetBackDeal then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0,
      g_sDealItemsDenyGetBackMsg);
    SendDefMessage(SM_DEALDELITEM_FAIL, 0, 0, 0, 0, '');
    Exit;
end;
if (nGameGold > 0) and (m_nDealGameGolds > 0) and g_Config.boCanNotGetBackDeal then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0,
      g_sDealItemsDenyGetBackMsg);
    SendDefMessage(SM_DEALDELITEM_FAIL, 0, 0, 0, 1, '');
    Exit;
end;
//金币
if (nGold < 0) then begin
    SendDefMessage(SM_DEALCHGGOLD_FAIL, m_nDealGolds, LoWord(m_nGold),
      HiWord(m_nGold), 0, '');
    Exit;
end;
//元宝
if (nGameGold < 0) then begin
    SendDefMessage(SM_DEALCHGGOLD_FAIL, m_nDealGameGolds, LoWord(m_nGameGold),
      HiWord(m_nGameGold), 1, '');
    Exit;
end;
//检查交易金额,不能小于原来的金额
if (nGold > 0) and (nGold < m_nDealGolds) then begin
    SendDefMessage(SM_DEALCHGGOLD_FAIL, m_nDealGolds, LoWord(m_nGold),
      HiWord(m_nGold), 0, '');
    Exit;
end;
if (nGameGold > 0) and (nGameGold < m_nDealGameGolds) then begin
    SendDefMessage(SM_DEALCHGGOLD_FAIL, m_nDealGameGolds, LoWord(m_nGameGold),
      HiWord(m_nGameGold), 1, '');
    Exit;
end;

//2013 金币大小不做检测了 Cloud
//检查交易金额大小限制
//if (nGameGold > 0) and (nGameGold > 2000) then begin
//    SendDefMessage(SM_DEALCHGGOLD_FAIL, m_nDealGameGolds, LoWord(m_nGameGold),
//      HiWord(m_nGameGold), 1, '');
//    Exit;
//end;

bo09 := False;
if (m_DealCreat <> nil) {and (GetPoseCreate = m_DealCreat)} then begin
    if not m_DealCreat.m_boDealOK then begin
      if ((m_nGold + m_nDealGolds) >= nGold) and ((m_nGameGold +
      m_nDealGameGolds) >= nGameGold) then begin
      //改变当前交易的金额
      if nGold > 0 then begin
          IncGold(m_nDealGolds - nGold);
          m_nDealGolds := nGold;
      end;
      if nGameGold > 0 then begin
          m_nGameGold := (m_nGameGold + m_nDealGameGolds) - nGameGold;
          m_nDealGameGolds := nGameGold;
      end;
      //确认金币或元宝
      if nGold > 0 then begin
          SendDefMessage(SM_DEALCHGGOLD_OK, m_nDealGolds, LoWord(m_nGold),
            HiWord(m_nGold), 0, '');
          TPlayObject(m_DealCreat).SendDefMessage(SM_DEALREMOTECHGGOLD,
            m_nDealGolds, 0, 0, 0, '');
      end else begin
          SendDefMessage(SM_DEALCHGGOLD_OK, m_nDealGameGolds,
            LoWord(m_nGameGold), HiWord(m_nGameGold), 1, '');
          TPlayObject(m_DealCreat).SendDefMessage(SM_DEALREMOTECHGGOLD,
            m_nDealGameGolds, 0, 0, 1, '');
      end;
      m_DealCreat.m_DealLastTick := GetTickCount();
      bo09 := True;
      m_DealLastTick := GetTickCount();
      end;                                                                                          //004DDC50
    end;
end;
if not bo09 then begin
    if nGold > 0 then
      SendDefMessage(SM_DEALCHGGOLD_FAIL, m_nDealGolds, LoWord(m_nGold),
      HiWord(m_nGold), 0, '')
    else
      SendDefMessage(SM_DEALCHGGOLD_FAIL, m_nDealGameGolds, LoWord(m_nGameGold),
      HiWord(m_nGameGold), 1, '');
end;
end;

//CM_TURN

function TPlayObject.ClientChangeDir(wIdent: word; nX, nY, nDir: Integer; var
dwDelayTime: LongWord): Boolean;                                                                  //4CAEB8
var
dwCheckTime                           : LongWord;
begin
Result := False;
if not CheckCanOperate(cRun) then Exit;

if not CheckActionStatus(wIdent, dwDelayTime) then begin
    m_boFilterAction := False;
    Exit;
end;
m_boFilterAction := True;
dwCheckTime := GetTickCount - m_dwTurnTick;
if dwCheckTime < g_Config.dwTurnIntervalTime then begin
    dwDelayTime := g_Config.dwTurnIntervalTime - dwCheckTime;
    Exit;
end;

if (nX = m_nCurrX) and (nY = m_nCurrY) then begin
    m_btDirection := nDir;
    if Walk(RM_TURN) then begin
      m_dwTurnTick := GetTickCount();
      Result := True;
    end;
end;
end;

//修改技能快捷键

procedure TPlayObject.ClientChangeMagicKey(nSkillIdx, nKey: Integer);                               //004DB9A4
var
i                                     : Integer;
UserMagic                           : pTUserMagic;
begin
//不允许设置快捷键的技能
if nSkillIdx in [SKILL_DRAGONROAR, SKILL_SWALLOWED, SKILL_RUSHTHUNDER,
   { SKILL_DRAGONPOWER, SKILL_DRAGONSHIELD, }SKILL_BLADEAREA..SKILL_127] then Exit;

for i := 0 to m_MagicList.Count - 1 do begin
    UserMagic := m_MagicList.Items;
    if UserMagic.GetMagIdx = nSkillIdx then begin
      UserMagic.btKey := nKey;
      Break;
    end;
end;
end;

//命令CM_CLICKNPC的处理

procedure TPlayObject.ClientClickNPC(NPC: Integer);                                                 //004DBA10
var
NormNpc                               : TNormNpc;
PlayObject                            : TBaseObject;
i                                     : Integer;
VisibleBaseObject                     : pTVisibleBaseObject;
s                                     : string;
begin
if m_boPneuma then Exit;                                                                        //元神不可以点击NPC

if not m_boCanDeal then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, g_sCanotTryDealMsg);
    Exit;
end;
if m_boDeath or m_boGhost then Exit;

//发送活动日志
if NPC = -5 then begin
    s := '';
    for i := 0 to UserEngine.m_Huodong.Count - 1 do
      s := s + UserEngine.m_Huodong;
    SendDefMessage(SM_MERCHANTSAY, Integer(g_FunctionNPC), 64, 0, 1, s);
    Exit;
end;

if m_ClickNPC = TObject(NPC) then
    NormNpc := TNormNpc(m_ClickNPC)
else begin
    NormNpc := UserEngine.FindMerchant(TObject(NPC));
    if NormNpc = nil then
      NormNpc := UserEngine.FindNPC(TObject(NPC));
    m_ClickNPC := NormNpc;
end;

if NormNpc <> nil then begin                                                                      {摆摊时不允许点NPC}
    if ((m_wShopItemCount = 0) or NormNpc.m_boDoShop) and
      IsEnvir(NormNpc.m_PEnvir) and (abs(NormNpc.m_nCurrX - m_nCurrX) <= 15) and (abs(NormNpc.m_nCurrY - m_nCurrY) <= 15) then begin
      NormNpc.Click(Self);
    end;
end else begin                                                                                    //2005/10/05增加:摆摊功能,当点击正在摆摊的玩家时,接收到的也是这个消息
    try
      PlayObject := nil;
      for i := 0 to m_VisibleActors.Count - 1 do begin
      VisibleBaseObject := m_VisibleActors.Items;
      if VisibleBaseObject.BaseObject = TObject(NPC) then begin
          PlayObject := TBaseObject(VisibleBaseObject.BaseObject);
          Break;
      end;
      end;
      if PlayObject <> nil then begin
      if (PlayObject = m_PackPet) or ((PlayObject.m_PEnvir = m_PEnvir) and
          (abs(PlayObject.m_nCurrX - m_nCurrX) <= 15) and
          (abs(PlayObject.m_nCurrY - m_nCurrY) <= 15)) then begin
          PlayObject.SendShopItems(Self, 1);
      end;
      end;
    except

    end;
end;
end;

//创建队伍

procedure TPlayObject.ClientCreateGroup(sHumName: string);                                          //004DCCB4
var
PlayObject                            : TPlayObject;
begin
PlayObject := UserEngine.GetPlayObject(sHumName);
if m_GroupOwner <> nil then begin
    SendDefMessage(SM_CREATEGROUP_FAIL, -1, 0, 0, 0, '');
    Exit;
end;
if (PlayObject = nil) or (PlayObject = Self) or PlayObject.m_boDeath or
    PlayObject.m_boGhost then begin
    SendDefMessage(SM_CREATEGROUP_FAIL, -2, 0, 0, 0, '');
    Exit;
end;
if (PlayObject.m_GroupOwner <> nil) then begin
    SendDefMessage(SM_CREATEGROUP_FAIL, -3, 0, 0, 0, '');
    Exit;
end;
if (PlayObject.m_boPneuma) then begin
    SendDefMessage(SM_CREATEGROUP_FAIL, -2, 0, 0, 0, '');
    Exit;
end;
if (not PlayObject.m_boAllowGroup) then begin
    SendDefMessage(SM_CREATEGROUP_FAIL, -4, 0, 0, 0, '');
    Exit;
end;
if (PlayObject.m_PEnvir <> m_PEnvir) then begin                                                   //增加控制:必须在同一地图才可以组队
    SendDefMessage(SM_CREATEGROUP_FAIL, -2, 0, 0, 0, '');
    Exit;
end;

FillChar(m_sGroupCommon, SizeOf(m_sGroupCommon), #0);                                             //清空队伍变量
m_GroupMembers.Clear;
m_GroupMembers.AddObject(m_sCharName, Self);
m_GroupMembers.AddObject(sHumName, PlayObject);
JoinGroup(Self);
PlayObject.JoinGroup(Self);
m_boAllowGroup := True;
SendDefMessage(SM_CREATEGROUP_OK, 0, 0, 0, 0, '');
SendGroupMembers();
end;

//创建第二元神

procedure TPlayObject.ClientCreateSoul(nParm1, nParm2, nParm3: Integer);
begin
if m_boGhost or m_boDeath then Exit;
if Assigned(m_VersionManage) then
try
    m_VersionManage.OnClientCreateSoul(Self, nParm1, nParm2, nParm3);
except
    MainOutMessage(Format('TPlayObject::OnClientCreateSoul SoftVersionDate:%d', ));
end;
end;

//交易完成

procedure TPlayObject.ClientDealEnd;
var
i, j                                  : Integer;
bo11                                  : Boolean;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
PlayObject                            : TPlayObject;
begin
if m_DealCreat = nil then Exit;
if ((GetTickCount - m_DealLastTick) < g_Config.dwDealOKTime {1000}) or
    ((GetTickCount - m_DealCreat.m_DealLastTick) < g_Config.dwDealOKTime {1000}) then begin
    SysMsg(g_sDealOKTooFast, c_Red, t_Hint);
    DealCancel();
    Exit;
end;
m_boDealOK := True;
m_DealLastTick := GetTickCount;

if m_DealCreat.m_boDealOK then begin
    bo11 := True;
    if (m_nBagSize - m_ItemList.Count) < m_DealCreat.m_DealItemList.Count then begin
      bo11 := False;                                                                              //包裹空间不足
      SysMsg(g_sYourBagSizeTooSmall, c_Red, t_Hint);
    end else if ((m_nGoldMax - m_nGold) < m_DealCreat.m_nDealGolds) then begin
      SysMsg(g_sYourGoldLargeThenLimit, c_Red, t_Hint);
      bo11 := False;                                                                              //金币超过限制
    end else if ((m_nGameGoldMax - m_nGameGold) < m_DealCreat.m_nDealGameGolds) then begin
      SysMsg(g_sYourGameGoldLargeThenLimit, c_Red, t_Hint);
      bo11 := False;                                                                              //元宝超过限制
    end else if (m_DealCreat.m_nBagSize - m_DealCreat.m_ItemList.Count) <
      m_DealItemList.Count then begin
      SysMsg(g_sDealHumanBagSizeTooSmall, c_Red, t_Hint);
      bo11 := False;                                                                              //包裹空间不足
    end else if ((m_DealCreat.m_nGoldMax - m_DealCreat.m_nGold) < m_nDealGolds) then begin
      SysMsg(g_sDealHumanGoldLargeThenLimit, c_Red, t_Hint);
      bo11 := False;                                                                              //金币超过限制
    end else if ((m_DealCreat.m_nGameGoldMax - m_DealCreat.m_nGameGold) <
      m_nDealGameGolds) then begin
      SysMsg(g_sDealHumanGameGoldLargeThenLimit, c_Red, t_Hint);
      bo11 := False;                                                                              //元宝超过限制
    end;

    if bo11 then begin
      for i := 0 to 27 do m_sDealParam := '';                                                    //清空变量
      for i := 0 to m_DealItemList.Count - 1 do begin
      UserItem := m_DealItemList.Items;
      m_DealCreat.AddItemToBag(UserItem);
      TPlayObject(m_DealCreat).SendAddItem(UserItem);
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      m_sDealParam := IntToStr(UserItem.MakeIndex);
      if StdItem <> nil then begin
          if not IsCheapStuff(StdItem.StdMode) then begin

            if StdItem.boGameLog = 1 then
            AddGameDataLog('8' + #9 +
                m_sMapName + #9 +
                IntToStr(m_nCurrX) + #9 +
                IntToStr(m_nCurrY) + #9 +
                m_sCharName + #9 +
                StdItem.Name + #9 +
                IntToStr(UserItem.MakeIndex) + #9 +
                '1' + #9 +
                m_DealCreat.m_sCharName);
          end;
      end;
      end;
      if m_nDealGolds > 0 then begin
      m_sDealParam := IntToStr(m_nDealGolds);
      m_DealCreat.IncGold(m_nDealGolds);
      m_DealCreat.GoldChanged();
      if g_boGameLogGold then
          AddGameDataLog('14' + #9 +
            m_sMapName + #9 +
            IntToStr(m_nCurrX) + #9 +
            IntToStr(m_nCurrY) + #9 +
            m_sCharName + #9 +
            sSTRING_GOLDNAME + #9 +
            IntToStr(m_nGold) + #9 +
            '1' + #9 +
            m_DealCreat.m_sCharName);
      end;
      if m_nDealGameGolds > 0 then begin
      m_sDealParam := IntToStr(m_nDealGolds);
      Inc(m_DealCreat.m_nGameGold, m_nDealGameGolds);
      m_DealCreat.GameGoldChanged();

      if g_boGameLogGameGold then
          AddGameDataLog('17' + #9 +
            m_sMapName + #9 +
            IntToStr(m_nCurrX) + #9 +
            IntToStr(m_nCurrY) + #9 +
            m_sCharName + #9 +
            sSTRING_GAMEGOLDNAME + #9 +
            IntToStr(m_nGameGold) + #9 +
            '2' + #9 +
            m_sCharName);
      end;

      for i := 0 to m_DealCreat.m_DealItemList.Count - 1 do begin
      UserItem := m_DealCreat.m_DealItemList.Items;
      AddItemToBag(UserItem);
      TPlayObject(Self).SendAddItem(UserItem);
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      m_sDealParam := IntToStr(UserItem.MakeIndex);
      if StdItem <> nil then begin
          if not IsCheapStuff(StdItem.StdMode) then begin

            if StdItem.boGameLog = 1 then
            AddGameDataLog('8' + #9 +
                m_DealCreat.m_sMapName + #9 +
                IntToStr(m_DealCreat.m_nCurrX) + #9 +
                IntToStr(m_DealCreat.m_nCurrY) + #9 +
                m_DealCreat.m_sCharName + #9 +
                StdItem.Name + #9 +
                IntToStr(UserItem.MakeIndex) + #9 +
                '1' + #9 +
                m_sCharName);
          end;
      end;
      end;
      if m_DealCreat.m_nDealGolds > 0 then begin
      m_sDealParam := IntToStr(m_DealCreat.m_nDealGolds);
      IncGold(m_DealCreat.m_nDealGolds);
      GoldChanged();

      if g_boGameLogGold then
          AddGameDataLog('14' + #9 +
            m_DealCreat.m_sMapName + #9 +
            IntToStr(m_DealCreat.m_nCurrX) + #9 +
            IntToStr(m_DealCreat.m_nCurrY) + #9 +
            m_DealCreat.m_sCharName + #9 +
            sSTRING_GOLDNAME + #9 +
            IntToStr(m_DealCreat.m_nGold) + #9 +
            '1' + #9 +
            m_sCharName);
      end;

      if m_DealCreat.m_nDealGameGolds > 0 then begin
      m_sDealParam := IntToStr(m_DealCreat.m_nDealGameGolds);
      Inc(m_nGameGold, m_DealCreat.m_nDealGameGolds);
      GameGoldChanged();

      if g_boGameLogGameGold then
          AddGameDataLog('17' + #9 +
            m_sMapName + #9 +
            IntToStr(m_nCurrX) + #9 +
            IntToStr(m_nCurrY) + #9 +
            m_sCharName + #9 +
            sSTRING_GAMEGOLDNAME + #9 +
            IntToStr(m_nGameGold) + #9 +
            '2' + #9 +
            m_DealCreat.m_sCharName);
      end;

      PlayObject := TPlayObject(m_DealCreat);


      m_sScriptParam := PlayObject.m_sCharName;
      ExecuteScript(g_ManageNPC, '@_游戏_交易触发');


      PlayObject.SendDefMessage(SM_DEALSUCCESS, 0, 0, 0, 0, '');
      PlayObject.SysMsg(g_sDealSuccessMsg {'交易成功...'}, c_Green, t_Hint);
      PlayObject.m_DealCreat := nil;
      PlayObject.m_boDealing := False;
      PlayObject.m_DealItemList.Clear;
      PlayObject.m_nDealGolds := 0;
      PlayObject.m_nDealGameGolds := 0;
      PlayObject.m_boDealOK := False;
      UserEngine.SaveHumanRcd(Self);
      UserEngine.SaveHumanRcd(TPlayObject(m_DealCreat));
      m_dwSaveRcdTick := GetTickCount;
      TPlayObject(m_DealCreat).m_dwSaveRcdTick := GetTickCount;

      SendDefMessage(SM_DEALSUCCESS, 0, 0, 0, 0, '');
      SysMsg(g_sDealSuccessMsg {'交易成功...'}, c_Green, t_Hint);
      m_DealCreat := nil;
      m_boDealing := False;
      m_DealItemList.Clear;
      m_nDealGolds := 0;
      m_nDealGameGolds := 0;
      m_boDealOK := False;
    end else begin
      DealCancel();
    end;
end else begin
    SysMsg(g_sYouDealOKMsg {'你已经确认交易了'}, c_Green, t_Hint);
    m_DealCreat.SysMsg(g_sPoseDealOKMsg {'对方已经确认交易了'},
      c_Green, t_Hint);
end;
end;

//尝试交易

procedure TPlayObject.ClientDealTry(sHumName: string);
var
BaseObject                            : TBaseObject;
begin
if g_Config.boDisableDeal then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0,
      g_sDisableDealItemsMsg);
    Exit;
end;
if m_boDealing then Exit;

if GetTickCount - m_DealLastTick < g_Config.dwTryDealTime {3000} then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0,
      g_sPleaseTryDealLaterMsg);
    Exit;
end;

//摆摊状态下不允许交易。
if not m_boCanDeal or (m_wShopItemCount > 0) then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0,
      g_sCanotTryDealMsg);
    Exit;
end;

if m_boPneuma then begin
    SysMsg('元神分身也想玩交易?没门!', c_Red, t_Hint);
    Exit;
end;

//非和平攻击模式下不允许交易。
if (m_btAttatckMode <> HAM_PEACE) then begin
    SysMsg(g_sCanotTryDealMsg2, c_Red, t_Hint);
    Exit;
end;

if m_boArrow then begin
    SysMsg('现在不能交易', c_Green, t_Hint);
    Exit;
end;

BaseObject := GetPoseCreate();

if BaseObject = nil then BaseObject := UserEngine.GetPlayObject(sHumName);

if (BaseObject <> nil) and (BaseObject <> Self) then begin
    if (not BaseObject.m_boDealing) then begin
      if (BaseObject.m_btRaceServer = RC_PLAYOBJECT) then begin
      //检查对方是否元神
      if BaseObject.m_boPneuma then begin
          SysMsg('不可以和元神分身交易', c_Red, t_Hint);
          Exit;
      end;

      //检查对方是否是和平攻击模式
      if (BaseObject.m_btAttatckMode <> HAM_PEACE) then begin
          SysMsg(g_sCanotTryDealMsg3, c_Red, t_Hint);
          Exit;
      end;

      if BaseObject.m_boArrow then begin
          SysMsg('对方现在不能交易', c_Green, t_Hint);
          Exit;
      end;

      if (BaseObject.m_boAllowDeal and TPlayObject(BaseObject).m_boCanDeal) then begin
          BaseObject.SysMsg(m_sCharName + g_sOpenedDealMsg, c_Green, t_Hint);
          SysMsg(BaseObject.m_sCharName + g_sOpenedDealMsg, c_Green, t_Hint);
          TPlayObject(Self).OpenDealDlg(BaseObject);
          TPlayObject(BaseObject).OpenDealDlg(Self);
      end else begin                                                                              //004DD1CC
          SysMsg(g_sPoseDisableDealMsg {'对方禁止进入交易'}, c_Red, t_Hint);
      end;
      end;
    end else begin                                                                                  //004DD1E0
      SendDefMessage(SM_DEALTRY_FAIL, 0, 0, 0, 0, '');
    end;
end else begin                                                                                    //004DD1F9
    SendDefMessage(SM_DEALTRY_FAIL, 0, 0, 0, 0, '');
end;
end;

//删除要交易的物品

procedure TPlayObject.ClientDelDealItem(nItemIdx: Integer; sItemName: string);
var
i                                     : Integer;
bo11                                  : Boolean;
UserItem                              : pTUserItem;
sName                                 : string;
begin
//如果不允许取回物品,则失败
if g_Config.boCanNotGetBackDeal then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0,
      g_sDealItemsDenyGetBackMsg);
    SendDefMessage(SM_DEALDELITEM_FAIL, 0, 0, 0, 0, '');
    Exit;
end;

if (m_DealCreat = nil) or (not m_boDealing) then Exit;

bo11 := False;
if not m_DealCreat.m_boDealOK then begin
    for i := m_DealItemList.Count - 1 downto 0 do begin
      UserItem := m_DealItemList.Items;
      if UserItem.MakeIndex = nItemIdx then begin

      //取自定义物品名称
      sName := '';
      ItemUnit.GetCustomItemName(UserItem, sName);

      if (CompareText(sItemName, sName) = 0) then begin
          m_ItemList.Add(UserItem);
          TPlayObject(Self).SendDelDealItem(UserItem);
          m_DealItemList.Delete(i);
          bo11 := True;
          Break;
      end;
      end;
    end;
end;
if not bo11 then
    SendDefMessage(SM_DEALDELITEM_FAIL, 0, 0, 0, 0, '');
end;

//删除好友

procedure TPlayObject.ClientDelFriend(FriendName: string);
var
i                                     : Integer;
human                                 : TPlayObject;
begin
//检查要删除的人是否在我的好友名单中
DelFromFriendList(FriendName);
//对方从名单中删除我
human := UserEngine.GetPlayObject(FriendName);
if (human <> nil) and (not human.m_boDeath) and (not human.m_boGhost) then begin
    human.DelFromFriendList(m_sCharName);
end else begin                                                                                    //不在线,则自己来删除对方的好友

end;
m_sScriptParam := FriendName;
ExecuteScript(g_ManageNPC, '@人脉_删除好友');
end;

//删除队伍成员

procedure TPlayObject.ClientDelGroupMember(sHumName: string);                                       //004DCFB8
var
PlayObject                            : TPlayObject;
begin
PlayObject := UserEngine.GetPlayObject(sHumName);
if m_GroupOwner <> Self then begin
    SendDefMessage(SM_GROUPDELMEM_FAIL, -1, 0, 0, 0, '');
    Exit;
end;
if PlayObject = nil then begin
    SendDefMessage(SM_GROUPDELMEM_FAIL, -2, 0, 0, 0, '');
    Exit;
end;
if not IsGroupMember(PlayObject) then begin
    SendDefMessage(SM_GROUPDELMEM_FAIL, -3, 0, 0, 0, '');
    Exit;
end;
DelMember(PlayObject);
SendDefMessage(SM_GROUPDELMEM_OK, 0, 0, 0, 0, sHumName);

PlayObject.ExecuteScript(g_FunctionNPC, '@_退出队伍');
end;

//摆摊

procedure TPlayObject.ClientDoShop(shopItemCount: word; sMsg: string);
var
RetCode                               : Integer;
DoShopResult                        : TDoShopResult;
i, j, ii                              : Integer;
UserShop                              : TUserShop;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
boFind                              : Boolean;
sName                                 : string;
Castle                              : TUserCastle;
BaseObjectList                        : TList;
BaseObject                            : TBaseObject;
resourcestring
sHint1                              = '骑宠状态不能摆摊。';
sHint2                              = '此地图禁止摆摊。';
sHint3                              = '正在攻城的区域禁止摆摊。';
sHint4                              = '你正在进行抢宝活动,禁止摆摊。';
sHint5                              = '周围没有空的位置,无法摆下你的摊位。';
sHint6                              = '摆摊物品价格定义错误,请勿使用非法外挂!';
sHint7                              = '金币交易价格定义超过允许的范围。';
sHint8                              = '元宝交易价格定义超过允许的范围。';
sHint9                              = '此物品开启后不允许交易,但时间到后可丢弃。';
sHint10                               = '你要出售的物品并不存在。';
sHint11                               = ' 不允许交易。';
begin
if not m_boCanDeal then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, g_sCanotTryDealMsg);
    Exit;
end;

if m_boRideOn then begin
    SysMsg(sHint1, c_Red, t_Hint);
    Exit;
end;

if m_PEnvir.m_MapFlag.boNoDoShop then begin
    SysMsg(sHint2, c_Red, t_Hint);
    Exit;
end;

Castle := g_CastleManager.InCastleWarArea(Self);
//城堡正在战斗
if (Castle <> nil) and Castle.m_boUnderWar then begin
    SysMsg(sHint3, c_Red, t_Hint);
    Exit;
end;

if m_boArrow then begin
    SysMsg(sHint4, c_Red, t_Hint);
    Exit;
end;

BaseObjectList := TList.Create;
try
    GetMapBaseObjects(m_PEnvir, m_nCurrX, m_nCurrY, 2, BaseObjectList);
    for i := 0 to BaseObjectList.Count - 1 do begin
      BaseObject := TBaseObject(BaseObjectList.Items);
      if (BaseObject.m_btRaceServer = RC_NPC) then begin
      SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, '你离NPC太近了,不能摆摊。');
      Exit;
      end;
    end;
finally
    BaseObjectList.free;
end;

//检查前后左右有没有空位置
if (m_wShopItemCount = 0) and (shopItemCount > 0) then begin                                    //开始摆摊的时候才需要判断
    if (m_nCurrX > 0) and (m_nCurrX < m_PEnvir.m_nWidth) and
      (m_nCurrY > 0) and (m_nCurrY < m_PEnvir.m_nHeight) and
      m_PEnvir.CanWalk(m_nCurrX, m_nCurrY - 1, True) and
      m_PEnvir.CanWalk(m_nCurrX + 1, m_nCurrY - 1, True) and
      m_PEnvir.CanWalk(m_nCurrX + 1, m_nCurrY, True) and
      m_PEnvir.CanWalk(m_nCurrX + 1, m_nCurrY + 1, True) and
      m_PEnvir.CanWalk(m_nCurrX, m_nCurrY + 1, True) and
      m_PEnvir.CanWalk(m_nCurrX - 1, m_nCurrY + 1, True) and
      m_PEnvir.CanWalk(m_nCurrX - 1, m_nCurrY, True) and
      m_PEnvir.CanWalk(m_nCurrX - 1, m_nCurrY - 1, True) then
    else begin
      SysMsg(sHint5, c_Red, t_Hint);
      Exit;
    end;
end;

m_wShopItemCount := _MIN(15, shopItemCount);
if m_wShopItemCount = 0 then begin
    RetCode := $FF;
end else begin                                                                                    //判断能否摆摊
    RetCode := 0;
end;

FillChar(m_Shop, SizeOf(TShop), #0);
if (RetCode = 0) and (m_wShopItemCount > 0) and (sMsg <> '') then begin                           //取摊位名字和物品
    DeCodeBuffer(sMsg, @m_Shop, SizeOf(TShop));
end;
//检测摊位名称
if CheckFilterWords(m_Shop.ShopName) or AnsiContainsText(m_Shop.ShopName, '\') then begin
    m_wShopItemCount := 0;
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, '输入内容含有非法字符!');
    Exit;
end;
for i := 0 to m_wShopItemCount - 1 do begin
    if m_Shop.ShopItems.MakeIndex <> 0 then begin
      if not (m_Shop.ShopItems.PayType in ) then begin
      SysMsg(sHint6, c_Red, t_Hint);
      m_wShopItemCount := 0;
      Exit;
      end;                                                                                          //150 000 000 //2000
      if (m_Shop.ShopItems.PayType = 0) and ((m_Shop.ShopItems.Price < 1)
      or (m_Shop.ShopItems.Price > 150000000)) then begin
      SysMsg(sHint7, c_Red, t_Hint);
      m_wShopItemCount := 0;
      Exit;
      end;
      if (m_Shop.ShopItems.PayType = 1) and ((m_Shop.ShopItems.Price < 1)
      or (m_Shop.ShopItems.Price > 10000000)) then begin
      SysMsg(sHint8, c_Red, t_Hint);
      m_wShopItemCount := 0;
      Exit;
      end;

      //检查物品合法性
      boFind := False;
      for j := 0 to m_ItemList.Count - 1 do begin
      UserItem := pTUserItem(m_ItemList);
      if UserItem.MakeIndex = m_Shop.ShopItems.MakeIndex then begin
          StdItem := UserEngine.GetStdItem(UserItem.wIndex);
          if StdItem = nil then Break;

          sName := '';
          ItemUnit.GetCustomItemName(UserItem, sName);

          {物品控制-禁止摆摊物品}
          if CheckSPCode(StdItem.SPCode, SP_DISABLEDOSHOP) or
            ((UserItem.btItemExt and EX_BIND) = EX_BIND) then begin
            SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, sName + sHint11);
            m_wShopItemCount := 0;
            Exit;
          end;

          {魂佑灵兽禁止交易}
          if (StdItem.StdMode = 49) and (StdItem.Shape = 51) and (UserItem.btItemExt >= 2) then begin
            SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, '魂佑灵兽禁止交易');
            m_wShopItemCount := 0;
            Exit;
          end;

          {已放出宠物禁止出售}
          if IsDownPetItem(UserItem.MakeIndex) then begin
            SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, sName + sHint11);
            m_wShopItemCount := 0;
            Exit;
          end;

          boFind := True;
          Break;
      end;
      end;
      if not boFind then begin
      SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, sHint10);
      m_wShopItemCount := 0;
      Exit;
      end;
    end;
end;

for i := m_wShopItemCount to 14 do begin
    m_Shop.ShopItems.MakeIndex := 0;
    m_Shop.ShopItems.Price := 0;
    m_Shop.ShopItems.PayType := 0;
end;

DoShopResult.ShopType := m_wShopKind;
DoShopResult.RetCode := RetCode;
DoShopResult.FlagType := m_btShopBanner;
DoShopResult.FlagColor := m_nBannerColor;
if (RetCode = 0) and ((m_btDirection mod 2) = 0) then
    m_btDirection := m_btDirection + 1;
m_defMsg := MakeDefaultMsg(SM_DOSHOP, Integer(Self), m_nCurrX, m_nCurrY,
    m_btDirection);
SendSocket(@m_defMsg, EnCodeBuffer(@DoShopResult, SizeOf(TDoShopResult)));

UserShop.DoShopResult.ShopType := m_wShopKind;
UserShop.DoShopResult.RetCode := RetCode;
UserShop.DoShopResult.FlagType := m_btShopBanner;
UserShop.DoShopResult.FlagColor := m_nBannerColor;
UserShop.GoodsCount := 0;
UserShop.ShopName := m_Shop.ShopName;

//发送操作结果和商店名称
SendRefMsg(RM_DOSHOP, m_btDirection, MakeLong(m_nCurrX, m_nCurrY), RetCode, 0,
    EnCodeBuffer(@UserShop, 62));

if (not m_boPneuma) then begin
    m_sScriptParam := '0';
    ExecuteScript(g_FunctionNPC, '@开始摆摊');
end;
end;

function TPlayObject.ClientDropGold(nGold: Integer): Boolean;                                       //004C5BB0
begin
Result := False;
//安全区是否允许扔金币
if g_Config.boInSafeDisableDrop and InSafeZone then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0,
      g_sCanotDropInSafeZoneMsg);
    Exit;
end;

//扔金币数量的控制
if g_Config.boControlDropItem and (nGold < g_Config.nCanDropGold) then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0,
      g_sCanotDropGoldMsg);
    Exit;
end;

//本人物是否允许扔金币
if not m_boCanDrop or (m_wShopItemCount > 0) then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0,
      g_sCanotDropItemMsg);
    Exit;
end;
//扔的金币数是否大于已有金币数
if nGold > m_nGold then Exit;

DecGold(nGold);
if not DropGoldDown(nGold, False, nil, Self) then IncGold(nGold);
GoldChanged();

if g_Config.boStartMapEvent then begin
    StartMapEventOfDropItem(sSTRING_BINDGOLDNAME);
end;
Result := True;
end;

//检测是否放出的宠物

function TPlayObject.IsDownPetItem(nMakeIndex: Integer): Boolean;
var
i                                     : Integer;
begin
Result := False;
for i := 0 to 5 do begin
    if nMakeIndex = m_PetInfo.nMakeIndex then begin
      Result := True;
      Break;
    end;
end;
end;

//扔其他物品

function TPlayObject.ClientDropItem(sItemName: string; nItemIdx: Integer): Boolean;
resourcestring
sExceptionMsg                         = ' TPlayObject::ClientDropItem Code=%d';
var
i, ii                                 : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
sName                                 : string;
FireBurnEff                           : word;                                                   //烟花效果
nCheckCode                            : Integer;
begin
Result := False;
nCheckCode := 0;
FireBurnEff := 0;
try
    if (GetTickCount - m_DealLastTick) > 3000 then begin
      nCheckCode := 1;
      for i := m_ItemList.Count - 1 downto 0 do begin
      UserItem := m_ItemList.Items;
      if (UserItem <> nil) and (UserItem.MakeIndex = nItemIdx) then begin
          StdItem := UserEngine.GetStdItem(UserItem.wIndex);
          if StdItem = nil then Continue;
          nCheckCode := 2;

          sName := '';
          ItemUnit.GetCustomItemName(UserItem, sName);

          nCheckCode := 3;
          if (CompareText(sItemName, sName) = 0) then begin
            //烟花
            nCheckCode := 4;
            if (StdItem.StdMode = 52) then
            FireBurnEff := MakeWord(StdItem.Shape, StdItem.AniCount);
            nCheckCode := 5;
            //兽粮
            if (StdItem.StdMode = 49) and (StdItem.Shape = 52) then begin
            nCheckCode := 6;
            if (m_Pet <> nil) and (abs(m_nCurrX - m_Pet.m_nCurrX) <= 2) and (abs(m_nCurrY - m_Pet.m_nCurrY) <= 2) then begin
                nCheckCode := 7;
                if PetStoreAddExp(m_PetInfo.nMakeIndex, StdItem.DuraMax, LoWord(StdItem.AC), False) then begin
                  nCheckCode := 8;
                  Dispose(UserItem);
                  m_ItemList.Delete(i);
                  Result := True;
                  m_Pet.SendRefMsg(RM_HIT, m_Pet.m_btDirection, m_Pet.m_nCurrX, m_Pet.m_nCurrY, 0, '');
                  Break;
                end;
                nCheckCode := 9;
            end else begin
                SysMsg('你的身边没有可喂食的宠物,不能喂食。', c_Red, t_Hint);
                Break;
            end;
            end;
            nCheckCode := 10;
            //烟花类
            if FireBurnEff > 0 then begin
            nCheckCode := 11;
            SendRefMsg(RM_FIREBURN, m_btDirection, MakeLong(m_nCurrX, m_nCurrY), 0, 0, EnCodeBuffer(@FireBurnEff, SizeOf(word)));
            nCheckCode := 12;
            Dispose(UserItem);
            m_ItemList.Delete(i);
            Result := True;
            Break;
            end;
            nCheckCode := 13;
            //安全区是否允许扔物品
            if g_Config.boInSafeDisableDrop and InSafeZone then begin
            if g_Config.boShowScriptActionMsg then
                SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, g_sCanotDropInSafeZoneMsg)
            else
                SysMsg(g_sCanotDropInSafeZoneMsg, c_Pink, t_Hint);
            Break;
            end;
            nCheckCode := 14;
            //本人物是否允许扔物品
            if not m_boCanDrop then begin
            SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, g_sCanotDropItemMsg);
            Break;
            end;
            nCheckCode := 15;
            //物品控制-禁止丢弃
            if CheckSPCode(StdItem.SPCode, SP_DISABLEDROP) or
            ((UserItem.btItemExt and EX_BIND) = EX_BIND) then begin
            Break;
            end;

            {魂佑灵兽禁止丢弃}
            if (StdItem.StdMode = 49) and (StdItem.Shape = 51) and (UserItem.btItemExt >= 2) then begin
            SysMsg('魂佑灵兽石不允许丢弃!', c_Red, t_Hint);
            Break;
            end;

            {已放出豹禁止丢弃}
            if IsDownPetItem(UserItem.MakeIndex) then begin
            SysMsg('已经放出灵兽的' + sName + '不能丢弃!', c_Red, t_Hint);
            Break;
            end;

            nCheckCode := 16;
            if g_Config.boControlDropItem and (StdItem.Price < g_Config.nCanDropPrice) then begin
            Dispose(UserItem);
            m_ItemList.Delete(i);
            Result := True;
            Break;
            end;
            nCheckCode := 17;
            if DropItemDown(UserItem, 3, False, nil, Self) then begin
            Dispose(UserItem);
            m_ItemList.Delete(i);
            Result := True;
            Break;
            end;
          end;
      end;
      end;
      nCheckCode := 18;
      if Result then begin
      WeightChanged();
      //丢物品触发脚本
      if (m_btRaceServer = RC_PLAYOBJECT) and (g_FunctionNPC <> nil) and (not m_boPneuma) then begin
          ExecuteScript(g_FunctionNPC, '@DropItem' + IntToStr(StdItem.AniCount));
      end;
      nCheckCode := 19;
      if g_Config.boStartMapEvent then begin
          StartMapEventOfDropItem(StdItem.Name);
      end;
      end;
    end;
except
    MainOutMessage(Format(sExceptionMsg, ));
end;
end;

procedure TPlayObject.ClientEnlargeTreasureBox();
begin
if (m_TreasureBoxItem = nil) or (m_TreasureBoxItem.DuraMax >= 20) then Exit;
if (m_Abil.wNimBusPoint < 10) then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, '你的灵力不足10点,无法扩充灵犀宝盒');
    Exit;
end;
Dec(m_Abil.wNimBusPoint, 10);
RecalcAbilitys();
SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
m_TreasureBoxItem.DuraMax := m_TreasureBoxItem.DuraMax + 2;
ClientQueryTreasureBoxItems(False);
SendDefMessage(SM_INFORMATION, 0, 0, 0, 0,
    Format('你的灵犀宝盒格子扩充成功,您现在拥有<color=green %d>个格子', ));
end;

{神龙献宝}

procedure TPlayObject.ClientErnie(nOpCode: word);
var
nLineCount                            : Integer;
NPC                                 : TNormNpc;
begin
if m_boGhost or m_boDeath then Exit;
case LoByte(nOpCode) of
    0: begin                                                                                        //宝石类停止

      end;
    1: begin                                                                                        //宝石类开始

      end;
    2: begin

      end;
    3: begin                                                                                        //弹出摇奖机,神龙在此刻觉醒
      //sGiftName := '强化火球四重';
      //SendDefMessage(34972, 0, 1, 0, 0, '今日神龙宝藏:' + sGiftName);
      end;
    4: begin                                                                                        //神龙献宝开始
      nLineCount := HiByte(nOpCode);
      NPC := UserEngine.FindMerchant(m_SMELTNPC);
      if (NPC = nil) then
          NPC := UserEngine.FindNPC(m_SMELTNPC);
      if (NPC <> nil) then begin
          m_sScriptParam := IntToStr(nLineCount);
          NPC.GotoLable(Self, '@StartErnie', False);
      end;
      end;
    5: begin                                                                                        //神龙献宝停下
      if (m_nRandomGiveStep = 1) then begin
          m_nRandomGiveStep := 0;
          NPC := UserEngine.FindMerchant(m_SMELTNPC);
          if (NPC = nil) then
            NPC := UserEngine.FindNPC(m_SMELTNPC);
          if (NPC <> nil) then begin
            NPC.GotoLable(Self, '@EndErnie', False);
          end;
      end;
      end;
end;
end;

{心魔控制}

procedure TPlayObject.ClientEvilOp(nOpCode: Integer; nEvilMonID: Integer;
nMakeIndex: Integer);
var
i, nCount                           : Integer;
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
mon, BaseObject                     : TBaseObject;
begin
mon := nil;
for i := 0 to m_SlaveList.Count - 1 do begin
    if TBaseObject(m_SlaveList).m_btRaceServer = RC_EVIL then begin
      mon := TBaseObject(m_SlaveList);
      Break;
    end;
end;
if mon = nil then Exit;

{检查物品}
if nMakeIndex > 0 then begin
    GetUserItemByMakeIndex(nMakeIndex, UserItem);
    if (UserItem <> nil) then
      StdItem := UserEngine.GetStdItem(UserItem.wIndex)
    else
      StdItem := nil;
    if (UserItem = nil) or (StdItem = nil) then Exit;
end;

case nOpCode of
    4: begin                                                                                        //心魔绝杀
      if (m_wStatusTimeArr > 0) or
          ((m_wStatusTimeArr > 0) and not g_Config.ClientConf.boParalyCanHit) then Exit; //被麻痹不能使用
      if (GetTickCount - m_dwEvilUniQueSkillTick) < 10 * 1000 then begin
          SysMsg('你控制的心魔已经处在强力攻击状态!', c_Red, t_Hint);
          Exit;
      end;
      if m_nEvilFollowerPower < g_Config.nEvilUniQueSkillDecPower * 1000 then begin
          SysMsg('镇魔力不足,无法发动强力攻击!', c_Red, t_Hint);
          Exit;
      end;
      if (GetTickCount - m_dwEvilUniQueSkillTick) <
          g_Config.nUseEvilUniQueSkillTick * 1000 then begin
          SysMsg('心魔绝杀技需间隔' +
            IntToStr(g_Config.nUseEvilUniQueSkillTick) + '秒才能使用一次', c_Red, t_Hint);
          Exit;
      end;
      for i := 0 to m_VisibleActors.Count - 1 do begin
          BaseObject :=
            TBaseObject(pTVisibleBaseObject(m_VisibleActors.Items).BaseObject);
          if BaseObject.m_boDeath or BaseObject.m_boGhost then Continue;
          if (abs(m_nCurrX - BaseObject.m_nCurrX) < 15) and (abs(m_nCurrY -
            BaseObject.m_nCurrY) < 15) then begin
            if IsProperTarget(BaseObject) then begin
            BaseObject.MakePosion(POISON_DONTMOVE, g_Config.nEvilUniQueSkillDontMoveTime, 0);
            BaseObject.SetLastHiter(Self);
            end;
          end;
      end;
      {心魔绝杀}
      ClearEvilFollower(0);
      m_dwEvilUniQueSkillTick := GetTickCount;
      Dec(m_nEvilFollowerPower, g_Config.nEvilUniQueSkillDecPower * 1000);
      SendDefMessage(CM_RECALLEVIL, Integer(Self), 260,
          LoWord(m_nEvilFollowerPower), HiWord(m_nEvilFollowerPower), '');
      end;
    5: begin                                                                                        //点面板上的“镇”字,有物品ID无心魔ID
      if m_nEvilFollowerPower >= m_nEvilFollowerPowerMax then begin                               //镇魔力量已经很强了,无需再增加
          SysMsg('镇魔力量已经很强了,无需再增加', c_Red, t_Hint);
          Exit;
      end;
      m_nEvilFollowerPower := _MIN(m_nEvilFollowerPowerMax,
          m_nEvilFollowerPower + StdItem.AC * 1000);
      if UserItem.Dura <= 1 then begin
          SendDelItems(UserItem);
          DelBagItem(UserItem.MakeIndex, StdItem.Name);
          WeightChanged;
      end else begin
          Dec(UserItem.Dura);
          SendUpdateItem(UserItem);
      end;
      SendDefMessage(34968, Integer(Self), 3, LoWord(m_nEvilFollowerPower),
          HiWord(m_nEvilFollowerPower), '');
      ClearEvilFollower(4);
      end;
    6: begin                                                                                        //解除,就是释放这个心魔宝宝
      nCount := 0;
      for i := m_SlaveList.Count - 1 downto 0 do begin
          if TBaseObject(m_SlaveList).m_btRaceServer = RC_EVIL then begin
            Inc(nCount);
            if nEvilMonID = Integer(m_SlaveList) then begin
            SysMsg(Format('你的宠物(%s)叛变了', ).m_sFilterCharName]), c_Pink, t_Hint);
            TBaseObject(m_SlaveList).m_Master := nil;
            TBaseObject(m_SlaveList).m_boSuperMan := False;
            TBaseObject(m_SlaveList).m_btNameColor := $F9;
            TBaseObject(m_SlaveList).RefNameColor;
            TBaseObject(m_SlaveList).RefShowName;
            TBaseObject(m_SlaveList).HealthSpellChanged;
            m_SlaveList.Delete(i);
            Dec(nCount);
            end;
          end;
      end;
      if nCount = 0 then begin
          SendDefMessage(CM_RECALLEVIL, 0, 1, 0, 0, '');
          m_nEvilFollowerPower := 0;
      end;
      SendDefMessage(34968, Integer(Self), 3, LoWord(m_nEvilFollowerPower),
          HiWord(m_nEvilFollowerPower), '');
      ClientQueryEvilFollower();
      end;
end;
end;

procedure TPlayObject.ClientEvoluTion(wParam: word; nMainMakeIndex,
nAuxMakeIndex, nMakeIndex: Integer);
var
UserItem                              : pTUserItem;
begin
if (not m_boDeath) and (not m_boGhost) and (not m_boPneuma) then begin
    if (GetUserItemByMakeIndex(nMainMakeIndex, UserItem) < 0) or
      (GetUserItemByMakeIndex(nAuxMakeIndex, UserItem) < 0) then Exit;
    if (nMakeIndex > 0) and (GetUserItemByMakeIndex(nMakeIndex, UserItem) < 0) then nMakeIndex := 0;
    if nMakeIndex < 0 then nMakeIndex := 0;
    m_sScriptParam := IntToStr(wParam);                                                          //封元印
    m_sScriptParam := IntToStr(nMainMakeIndex);                                                //主灵兽
    m_sScriptParam := IntToStr(nAuxMakeIndex);                                                   //副灵兽
    m_sScriptParam := IntToStr(nMakeIndex);
    ExecuteScript(g_FunctionNPC, '@灵兽幻化');
end;
end;

//灵兽繁衍

procedure TPlayObject.ClientPetMakeBaby(nMaleMakeIndex, nFemaleMakeIndex: Integer);
var
UserItem                              : pTUserItem;
begin
if (not m_boDeath) and (not m_boGhost) and (not m_boPneuma) then begin
    if (GetUserItemByMakeIndex(nMaleMakeIndex, UserItem) < 0) or (GetUserItemByMakeIndex(nFemaleMakeIndex, UserItem) < 0) then Exit;

    m_sScriptParam := IntToStr(nMaleMakeIndex);                                                //雄灵兽
    m_sScriptParam := IntToStr(nFemaleMakeIndex);                                                //雌灵兽
    ExecuteScript(g_FunctionNPC, '@繁衍灵兽');
end;
end;

//五行令旗

procedure TPlayObject.ClientFelementOrderFlag(nMakeIndex, nMon: Integer);
var
i                                     : Integer;
mon                                 : TBaseObject;
Targe                                 : TBaseObject;
UserItem                              : pTUserItem;
boEatOK                               : Boolean;
begin
boEatOK := False;
Targe := nil;
if GetUserItemByMakeIndex(nMakeIndex, UserItem) > -1 then begin
    if nMon > 0 then Targe := TBaseObject(nMon);
    if (nMon > 0) and (Targe <> nil) and (not Targe.m_boDeath) and
      (not Targe.m_boGhost) and (Targe.m_btRaceServer = RC_MISSION) and
      (Targe.m_boMission) then begin
      if UserItem.Dura > 0 then Dec(UserItem.Dura);
      if (UserItem.Dura <= 0) then begin
      DelBagItem(nMakeIndex, '');
      boEatOK := True;
      end else begin
      SendUpdateItem(UserItem);
      end;
      //指定攻击目标
      for i := 0 to m_SlaveList.Count - 1 do begin
      mon := m_SlaveList;
      if not (mon.m_btRaceServer in ) then Continue;
      mon.m_FirstTargetCret := Targe;
      mon.SetTargetCreat(Targe);
      end;
      SendDefMessage(3046, m_btDirection, LoWord(nMon), HiWord(nMon), 1, '');
      SysMsg(Format('使用五行令旗成功,将<%s>指定为首要攻击目标!', ), c_Red, t_Hint);
    end;
end;
if not boEatOK then SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
end;

procedure TPlayObject.ClientGemItems(NPC: Integer; nType: Integer; nItemCount:
Integer; nState: Integer; sData: string);
var
buf                                 : array of Integer;
i, j                                  : Integer;
nCode, nRate                        : Integer;
ANpc                                  : TNormNpc;
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
GemItems                              : array of pTUserItem;
GemStdItems                           : array of pTStdItem;
sMsg, sLable, DestItemName            : string;
sLableOK                              : string;
begin
for i := 0 to 9 do begin
    m_sScriptParam := '';
    GemItems := nil;
    GemStdItems := nil;
end;
sLable := '';
sLableOK := '';
FillChar(buf, SizeOf(buf), #0);
DeCodeBuffer(sData, @buf, SizeOf(Integer) * nItemCount);

if m_btPermissionGM > 6 then begin
    SysMsg(Format('当前指令编号为:%d', ), c_Red, t_Hint);
    SysMsg(Format('当前指令状态为:%d', ), c_Red, t_Hint);
    SysMsg(Format('当前NPC编号为:%d', ), c_Blue, t_Hint);
end;

if nType in then begin
    if NPC = Integer(Self) then
      ANpc := TNormNpc(m_SMELTNPC)
    else
      ANpc := UserEngine.FindMerchant(TObject(NPC));
end else begin
    ANpc := UserEngine.FindMerchant(TObject(NPC));
end;
if ANpc = nil then ANpc := UserEngine.FindNPC(TObject(NPC));

if ANpc = nil then Exit;

{函数入口初始}
nCode := 0;
for i := 0 to nItemCount - 1 do begin
    GemItems := nil;
    for j := 0 to m_ItemList.Count - 1 do begin
      UserItem := m_ItemList;
      if UserItem.MakeIndex = buf then begin
      GemItems := UserItem;
      GemStdItems := UserEngine.GetStdItem(UserItem.wIndex);
      Break;
      end;
    end;
end;

{函数标签初始}
case nType of
    0: sLable := '@@gemcondense';                                                                   //宝石凝练
    1: sLable := '@@gemcompound';                                                                   //宝石合成
    2: sLable := '@@weaponcompound';                                                                //武器铸造
    3: sLable := '@@supercompound';                                                               //装备合成
    4: sLable := '';
    5: sLable := '@@commoncodense';                                                               //熔炼宝箱
    6: sLable := '';
    7: begin                                                                                        //黑暗升级
      if (GemStdItems <> nil) then begin
          case GemStdItems.StdMode of
            5, 6: sLable := '@@equiplevel';
            10, 11, 15, 58, 81: sLable := '@@defitemlevel';
          else sLable := '@@jewitemlevel';
          end;
      end;
      end;
    8: begin
      sLable := '@@fushi';
      if (nCode = 0) and (nState > 255) then begin
          m_sScriptParam2 := IntToStr(nState div 256);
          if (nState mod 256 = 0) then nState := 0 else nState := 1;
      end;
      end;
    9: sLable := '@@hayifu';
    10: sLable := '@@spriterefine';
    11: sLable := '@@upgradeyuanshi';
    12: sLable := '@@HEJINGPO';
    13: sLable := '@@HELONGLING';
    14: sLable := '@@gemxianguan';
end;
sLableOK := sLable + 'OK';

{函数触发开始}
if (nCode = 0) then begin
    m_sScriptParam := IntToStr(nItemCount);
    for i := 0 to nItemCount - 1 do begin
      m_sScriptParam := IntToStr(GemItems.MakeIndex);
      StdItem := UserEngine.GetStdItem(GemItems.wIndex);
      if StdItem <> nil then begin
      if (StdItem.StdMode = 44) and (StdItem.Shape = 4) then
          m_sScriptParam := IntToStr(GemItems.MakeIndex);
      end;
{$IF USESDK = DEBUG}
      MainOutMessage('物品' + IntToStr(i) + ':' + IntToStr(GemItems.MakeIndex));
{$IFEND}
    end;
    if (nState = 1) then begin
      if (IsEnvir(ANpc.m_PEnvir) and (abs(ANpc.m_nCurrX - m_nCurrX) < 15) and (abs(ANpc.m_nCurrY - m_nCurrY) < 15)) or (ANpc.m_boIsHide) then begin
      if (sLable <> '') then ANpc.GotoLable(Self, sLable, False);
      end;
    end else begin
      if (sLableOK <> '') then ANpc.GotoLable(Self, sLableOK, False);
    end;
end;
end;

//接收Ident 993 Param 1 P1 0 P2 2318 P3 16 Msg ;zfxf@ruvfE数据部分是放上的物品MakeIndex

procedure TPlayObject.ClientGemSmelt(nState: Integer; RedBaoshi, BlueBaoshi,
GreenBaoshi: Integer; sItems: string);
var
ItemMakeIndexs                        : array of Integer;
i, ItemCount                        : Integer;
begin
FillChar(ItemMakeIndexs, SizeOf(Integer) * 15, 0);
ItemCount := Round(Length(sItems) * 3 / 4) div 4;
if ItemCount > 0 then
    DeCodeBuffer(sItems, @ItemMakeIndexs, ItemCount * 4);
for i := 0 to 19 do
    m_sScriptParam := '';
m_sScriptParam := IntToStr(RedBaoshi);
m_sScriptParam := IntToStr(BlueBaoshi);
m_sScriptParam := IntToStr(GreenBaoshi);
m_sScriptParam := IntToStr(ItemCount - 1);
for i := 0 to ItemCount - 1 do
    m_sScriptParam := IntToStr(ItemMakeIndexs);
if m_SMELTNPC <> nil then
    TNormNpc(m_SMELTNPC).GotoLable(Self, '@@gemsmelt', False);
end;

//CM_BUTCH 挖肉

function TPlayObject.ClientGetButchItem(BaseObject: TBaseObject; nX, nY:
Integer; btDir: byte; var dwDelayTime: LongWord): Boolean;                                        //004DB7E0
var
N10, n14                              : Integer;
dwCheckTime                           : LongWord;
begin
Result := False;
if (m_wShopItemCount > 0) then Exit;
dwDelayTime := 0;

if (not g_Config.boDisableM2SpeedCtrl) then begin
    dwCheckTime := GetTickCount - m_dwTurnTick;
    if dwCheckTime < g_Config.dwTurnIntervalTime then begin
      dwDelayTime := g_Config.dwTurnIntervalTime - dwCheckTime;
      Exit;
    end;
    m_dwTurnTick := GetTickCount;
end;

if (abs(nX - m_nCurrX) <= 2) and (abs(nY - m_nCurrY) <= 2) then begin
    if m_PEnvir.IsValidObject(nX, nY, 2, BaseObject) then begin
      if BaseObject.m_boDeath and ((not BaseObject.m_boSkeleton) or ((BaseObject.m_btRaceServer = RC_EVIL) and (BaseObject.m_btRaceImg = 253))) and (BaseObject.m_boAnimal) then begin
      N10 := Random(16) + 5;
      n14 := Random(100);
      Dec(BaseObject.m_nBodyLeathery, N10);
      Dec(BaseObject.m_nMeatQuality, n14);
      if (BaseObject.m_btRaceServer = RC_EVIL) and (BaseObject.m_btRaceImg = 253) then begin      //夺宝心魔
          m_sScriptParam := BaseObject.m_sOriginalName;
          m_sScriptParam := BaseObject.m_sCharName;
          if BaseObject.m_boSkeleton then
            m_sScriptParam := '1'
          else
            m_sScriptParam := '0';                                                               //0:没挖过,1:挖过
          m_sScriptParam := IntToStr(BaseObject.m_nBodyLeathery);
          //尸体坚韧度
          ExecuteScript(g_FunctionNPC, '@弑魔掘宝');
      end;
      if BaseObject.m_nMeatQuality < 0 then BaseObject.m_nMeatQuality := 0;
      if BaseObject.m_nBodyLeathery <= 0 then begin
          BaseObject.m_boSkeleton := True;
          if (BaseObject.m_btRaceServer in ) then begin
            BaseObject.ApplyMeatQuality();                                                          //计算肉的品质
            BaseObject.SendRefMsg(RM_SKELETON, BaseObject.m_btDirection,
            BaseObject.m_nCurrX, BaseObject.m_nCurrY, 0, '');
          end;
          if not TakeBagItems(BaseObject) then begin
            SysMsg(sYouFoundNothing {未发现任何物品!!!}, c_Red, t_Hint);
          end;
          BaseObject.m_nBodyLeathery := 50;
      end;
      m_dwDeathTick := GetTickCount();
      end;

    end;
    m_btDirection := btDir;
end;
SendRefMsg(RM_BUTCH, m_btDirection, m_nCurrX, m_nCurrY, 0, '');
Result := True;
end;

//取小地图信息

procedure TPlayObject.ClientGetMinMap;
var
nMinMap                               : Integer;
begin
nMinMap := m_PEnvir.MinMap;
if nMinMap > 0 then begin
    SendDefMessage(SM_READMINIMAP_OK, 0, nMinMap, 0, 0, '');
end else begin
    SendDefMessage(SM_READMINIMAP_FAIL, 0, 0, 0, 0, '');
end;

end;

//CM_GROUPMODE

procedure TPlayObject.ClientGropuClose;                                                             //004C3C10
begin
if m_GroupOwner = nil then begin
    m_boAllowGroup := False;
    Exit;
end;
if m_GroupOwner <> Self then begin
    m_GroupOwner.DelMember(Self);
    m_boAllowGroup := False;
end else begin
    SysMsg('如果你想退出,使用编组功能(删除按钮)', c_Red, t_Hint);
end;
end;

procedure TPlayObject.ClientGuildAddMember(sHumName: string);                                       //004DEDB4
var
nC                                    : Integer;
PlayObject                            : TPlayObject;
Castle                              : TUserCastle;
begin
nC := 1;                                                                                          //'你没有权利使用这个命令。'
if IsGuildMaster then begin
    PlayObject := UserEngine.GetPlayObject(sHumName);
    if PlayObject <> nil then begin
      if not TGuild(m_MyGuild).IsFull then begin
      if PlayObject.m_boAllowGuild then begin
          if not TGuild(m_MyGuild).IsMember(sHumName) then begin
            if (PlayObject.m_MyGuild = nil) and (TGuild(m_MyGuild).m_RankList.Count < 400) then begin
            TGuild(m_MyGuild).AddMember(PlayObject);
            UserEngine.SendServerGroupMsg(SS_207, g_Config.nServerNumber, TGuild(m_MyGuild).sGuildName);
            PlayObject.m_MyGuild := m_MyGuild;
            PlayObject.m_sGuildRankName := TGuild(m_MyGuild).GetRankName(PlayObject, PlayObject.m_nGuildRankNo);
            PlayObject.RefShowName();
            PlayObject.SysMsg('你已加入行会: ' + TGuild(m_MyGuild).sGuildName + ' 当前封号为: ' + PlayObject.m_sGuildRankName, c_Green, t_Hint);
            //脚本入口函数
            PlayObject.m_sScriptParam := TGuild(m_MyGuild).sGuildName;
            PlayObject.m_sScriptParam := PlayObject.m_sGuildRankName;
            Castle := g_CastleManager.IsCastleMember(PlayObject);
            PlayObject.m_nGuildGold := 0;
            PlayObject.GuildGoldChanged();
            if Castle <> nil then begin
                PlayObject.m_sScriptParam := Castle.m_sName;
                PlayObject.ExecuteScript(g_ManageNPC, '@ADDTOCASTLEGUILD');
            end else
                PlayObject.ExecuteScript(g_ManageNPC, '@ADDTOGUILD');
            nC := 0;
            end else
            nC := 4;                                                                              //'对方已经加入其他行会。'
          end else
            nC := 3;                                                                              //'对方已经加入我们的行会。'
      end else begin
          nC := 5;                                                                                  //'对方不允许加入行会。'
          PlayObject.SysMsg('你拒绝加入行会。 [允许命令为 @' + g_GameCommand.LETGUILD.sCmd + ']', c_Red, t_Hint);
      end;
      end else begin
      nC := 1;
      PlayObject.SysMsg('你所要加入的行会成员已经达到上限!', c_Red, t_Hint);
      end;
    end else nC := 2;                                                                               //'想加入进来的成员应该来面对掌门人。'
end else
    nC := 1;
if nC = 0 then begin
    SendDefMessage(SM_GUILDADDMEMBER_OK, 0, 0, 0, 0, '');
end else begin
    SendDefMessage(SM_GUILDADDMEMBER_FAIL, nC, 0, 0, 0, '');
end;
end;

procedure TPlayObject.ClientGuildAlly;                                                            //004DF3AC
var
N8                                    : Integer;
BaseObjectC                           : TBaseObject;
resourcestring
sExceptionMsg                         = ' TPlayObject::ClientGuildAlly';
begin
try
    N8 := -1;
    BaseObjectC := GetPoseCreate();
    if (BaseObjectC <> nil) and
      (BaseObjectC.m_MyGuild <> nil) and
      (BaseObjectC.m_btRaceServer = RC_PLAYOBJECT) and
      (BaseObjectC.GetPoseCreate = Self) then begin
      if TGuild(BaseObjectC.m_MyGuild).m_boEnableAuthAlly then begin
      if BaseObjectC.IsGuildMaster and IsGuildMaster then begin
          if TGuild(m_MyGuild).IsNotWarGuild(TGuild(BaseObjectC.m_MyGuild)) and
            TGuild(BaseObjectC.m_MyGuild).IsNotWarGuild(TGuild(m_MyGuild)) then begin

            TGuild(m_MyGuild).AllyGuild(TGuild(BaseObjectC.m_MyGuild));
            TGuild(BaseObjectC.m_MyGuild).AllyGuild(TGuild(m_MyGuild));

            TGuild(m_MyGuild).SendGuildMsg(TGuild(BaseObjectC.m_MyGuild).sGuildName + '行会已经和您的行会联盟成功。');
            TGuild(BaseObjectC.m_MyGuild).SendGuildMsg(TGuild(m_MyGuild).sGuildName + '行会已经和您的行会联盟成功。');
            TGuild(m_MyGuild).RefMemberName;
            TGuild(BaseObjectC.m_MyGuild).RefMemberName;
            UserEngine.SendServerGroupMsg(SS_207, g_Config.nServerNumber,
            TGuild(m_MyGuild).sGuildName);
            UserEngine.SendServerGroupMsg(SS_207, g_Config.nServerNumber,
            TGuild(BaseObjectC.m_MyGuild).sGuildName);
            N8 := 0;
          end else N8 := -2;
      end else N8 := -3;
      end else N8 := -4;                                                                            //004DF57C
    end;
    if N8 = 0 then begin
      SendDefMessage(SM_GUILDMAKEALLY_OK, 0, 0, 0, 0, '');
    end else begin
      SendDefMessage(SM_GUILDMAKEALLY_FAIL, N8, 0, 0, 0, '');
    end;
except
    on E: Exception do begin
      MainOutMessage(sExceptionMsg);
      MainOutMessage(E.Message);
    end;
end;
end;

procedure TPlayObject.ClientGuildBreakAlly(sGuildName: string);                                     //004DF604
var
N10                                 : Integer;
Guild                                 : TGuild;
begin
N10 := -1;
if not IsGuildMaster() then Exit;
Guild := g_GuildManager.FindGuild(sGuildName);
if Guild <> nil then begin
    if TGuild(m_MyGuild).IsAllyGuild(Guild) then begin
      TGuild(m_MyGuild).DelAllyGuild(Guild);
      Guild.DelAllyGuild(TGuild(m_MyGuild));
      TGuild(m_MyGuild).SendGuildMsg(Guild.sGuildName + ' 行会与您的行会解除联盟成功!!!');
      Guild.SendGuildMsg(TGuild(m_MyGuild).sGuildName + ' 行会解除了与您行会的联盟!!!');
      TGuild(m_MyGuild).RefMemberName();
      Guild.RefMemberName();
      UserEngine.SendServerGroupMsg(SS_207, g_Config.nServerNumber, TGuild(m_MyGuild).sGuildName);
      UserEngine.SendServerGroupMsg(SS_207, g_Config.nServerNumber, Guild.sGuildName);
      N10 := 0;
    end else N10 := -2;
end else N10 := -3;                                                                               //004DF750
if N10 = 0 then begin
    SendDefMessage(SM_GUILDBREAKALLY_OK, 0, 0, 0, 0, '');
end else begin
    SendDefMessage(SM_GUILDMAKEALLY_FAIL, 0, 0, 0, 0, '');
end;
end;

procedure TPlayObject.ClientGuildDelMember(sHumName: string);                                       //004DEFB8
var
nC                                    : Integer;
s14                                 : string;
PlayObject                            : TPlayObject;
Castle                              : TUserCastle;
begin
nC := 1;
if (m_MyGuild <> nil) and IsGuildMaster then begin
    if TGuild(m_MyGuild).IsMember(sHumName) then begin
      if g_GuildManager.MemberOfClan(sHumName) = nil then begin
      if m_sCharName <> sHumName then begin
          if TGuild(m_MyGuild).DelMember(sHumName) then begin
            nC := 0;
          end else
            nC := 4;
      end else begin
          nC := 3;
          s14 := TGuild(m_MyGuild).sGuildName;
          if TGuild(m_MyGuild).CancelGuld(sHumName) then begin
            SysMsg('行会' + s14 + '已被取消!!!', c_Red, t_Hint);
            nC := 0;
          end
      end;
      end else
      nC := 2;
    end else
      SysMsg('你无权删除宗族成员。', c_Red, t_Hint);
end;

if nC = 0 then begin
    SendDefMessage(SM_GUILDDELMEMBER_OK, 0, 0, 0, 0, '');
end else begin
    SendDefMessage(SM_GUILDDELMEMBER_FAIL, nC, 0, 0, 0, '');
end;
end;

procedure TPlayObject.ClientGuildHome;                                                            //004DEBDC
begin
ClientOpenGuildDlg();
end;

procedure TPlayObject.ClientGuildMemberList;                                                      //004DEBF0
var
GuildRank                           : pTGuildRank;
i, ii                                 : Integer;
sSENDMSG, sName, sAmbit               : string;
PlayObject                            : TPlayObject;
begin
if m_MyGuild = nil then Exit;
for i := 0 to TGuild(m_MyGuild).m_RankList.Count - 1 do begin
    if i >= 50 then Break;
    GuildRank := TGuild(m_MyGuild).m_RankList.Items;
    sSENDMSG := sSENDMSG + '#' + IntToStr(GuildRank.nRankNo) + '/*' + GuildRank.sRankName + '/';
    for ii := 0 to GuildRank.MemberList.Count - 1 do begin
      if ii >= 200 then Break;
      if Length(sSENDMSG) > 5000 then Break;
      sName := GuildRank.MemberList.Keys;
      PlayObject := UserEngine.GetPlayObject(sName);
      if PlayObject <> nil then begin
      if PlayObject.m_btAmbitKind > 2 then begin
          if (PlayObject.m_btAmbitKind mod 2) <> 0 then
            sAmbit := '1'
          else
            sAmbit := '2';
      end else
          sAmbit := '0';
      sSENDMSG := sSENDMSG + '1' + sAmbit + sName + '/';
      end else
      sSENDMSG := sSENDMSG + '00' + sName + '/';
    end;
end;
m_defMsg := MakeDefaultMsg(SM_GUILDMEMBERLIST, 0, 0, 0, 0);
SendSocket(@m_defMsg, EnCodeString(sSENDMSG));
end;

procedure TPlayObject.ClientGuildOfficial(nCode, nRankNo: Integer; sChiefName: string);
var
ChiefPlayer                           : TPlayObject;
nPermission                           : Integer;
begin
if (not (nRankNo in )) or (sChiefName = '') then Exit;
if m_MyGuild = nil then Exit;
ChiefPlayer := UserEngine.GetPlayObject(sChiefName);                                              //行会会长
if (ChiefPlayer <> nil) then begin
    if nCode = 1 then begin
      if m_nGuildGold >= nGuildOfficialPrice then begin
      TGuild(m_MyGuild).GetOfficial(nRankNo, sGuildOfficial, m_sCharName);               //任命职位
      Dec(m_nGuildGold, nGuildOfficialPrice);
      GuildGoldChanged;
      if g_boGameLogGuildGold then begin
          AddGameDataLog(Format(g_sGameLogMsg, [LOG_GUILDGOLD,
            m_sMapName,
            m_nCurrX,
            m_nCurrY,
            m_sCharName,
            '行会银两',
            nGuildOfficialPrice,
            '-',
            '官职任命']));
      end;
      end else
      SysMsg('行会银两不足' + IntToStr(nGuildOfficialPrice) + '个,无法任命该职位!', c_Red, t_Hint);
      SysMsg('恭喜你获得了新的行会职位!', c_Green, t_Hint);
      ChiefPlayer.SysMsg(m_sCharName + '被任命为' + sGuildOfficial, c_Red, t_Hint);
    end else begin
      ChiefPlayer.SysMsg(m_sCharName + '拒绝被任命为' + sGuildOfficial, c_Red, t_Hint);
    end;
end;
end;

procedure TPlayObject.ClientGuildUpdateNotice(sNotict: string);
var
SC                                    : string;
begin
if (m_MyGuild = nil) or (m_nGuildRankNo <> 1) then Exit;
TGuild(m_MyGuild).NoticeList.Clear;
while (sNotict <> '') do begin
    sNotict := GetValidStr3(sNotict, SC, [#$D]);
    TGuild(m_MyGuild).NoticeList.Add(SC);
end;
TGuild(m_MyGuild).UpdateGuildFile;
UserEngine.SendServerGroupMsg(SS_207, g_Config.nServerNumber,
    TGuild(m_MyGuild).sGuildName);
ClientOpenGuildDlg();
end;

procedure TPlayObject.ClientGuildUpdateRankInfo(sRankInfo: string);
var
nC                                    : Integer;
begin
if (m_MyGuild = nil) or (m_nGuildRankNo <> 1) then Exit;

nC := TGuild(m_MyGuild).UpdateRankNew(sRankInfo);
if nC = 0 then begin
    UserEngine.SendServerGroupMsg(SS_207, g_Config.nServerNumber, TGuild(m_MyGuild).sGuildName);
    ClientGuildMemberList();
end else begin
    if nC <= -2 then begin
      SendDefMessage(SM_GUILDRANKUPDATE_FAIL, nC, 0, 0, 0, '');
    end;
end;

end;

//检测是否允许指定动作

function TPlayObject.CheckCanOperate(Action: TClientAction; nKey: Integer = 0): Boolean;
begin
Result := False;

if m_boGodCallBoss and m_boSuperMan then m_boSuperMan := False;
//if m_boInMagicCast then begin
//    m_boInMagicCast := False;
//    SendRefMsg(RM_MAGICFIREFAIL, 0, 0, 0, 0, '');
//end;

if m_boDeath or m_boGhost then Exit;

{ if nKey = SKILL_186 then begin
    if (m_wStatusTimeArr = 0) then
      Result := True;
    Exit;
end; }

if (m_wStatusTimeArr > 0) or (m_wStatusTimeArr <> 0) or (m_wStatusTimeArr <> 0) then Exit;

case Action of
    cHit: begin
      if ((m_wStatusTimeArr <> 0) and not g_Config.ClientConf.boParalyCanHit) then Exit;
      end;
    cRun: begin
      if (m_wStatusTimeArr <> 0) or (m_wStatusTimeArr <> 0) or ((m_wStatusTimeArr <> 0) and not g_Config.ClientConf.boParalyCanRun) then Exit;
      end;
    cWalk: begin
      if (m_wStatusTimeArr <> 0) or (m_wStatusTimeArr <> 0) or ((m_wStatusTimeArr <> 0) and not g_Config.ClientConf.boParalyCanWalk) then Exit;
      end;
    cDigUp: begin
      if (m_wStatusTimeArr <> 0) or (m_wStatusTimeArr <> 0) or ((m_wStatusTimeArr <> 0) and not g_Config.ClientConf.boParalyCanHit) then Exit;
      end;
    cTurn: begin
      if (m_wStatusTimeArr <> 0) or (m_wStatusTimeArr <> 0) or ((m_wStatusTimeArr <> 0) and not g_Config.ClientConf.boParalyCanRun) then Exit;
      end;
    cMagHit: begin
      if (m_wStatusTimeArr <> 0) or ((m_wStatusTimeArr <> 0) and not g_Config.ClientConf.boParalyCanSpell) then Exit;
      end;
end;

Result := True;
end;

//物理攻击命令的处理,包括
// CM_HIT、CM_HEAVYHIT、CM_BIGHIT、CM_POWERHIT、CM_LONGHIT、CM_WIDEHIT
// CM_FIREHIT、CM_CRSHIT、CM_TWNHIT、CM_42HIT、CM_42HIT、CM_3026
// 3014 普通攻击
// 3018 功杀
// 3019 刺杀
// 3024 半月
// 3025 烈火

function TPlayObject.ClientHitXY(wIdent: word; nX, nY, nDir, nMagicID: Integer;
boLateDelivery: Boolean; var dwDelayTime: LongWord): Boolean;                                     //004CB7F8
var
n14, n18                              : Integer;
StdItem                               : pTStdItem;
dwAttackTime, dwCheckTime             : LongWord;
nPinjunTime                           : Integer;
AttackTarget                        : TBaseObject;
{$IF CATEXCEPTION = TRYEXCEPTION}
nCheckCode                            : Integer;
{$IFEND}
resourcestring
sExceptionMsg                         = ' TPlayObject::ClientHitXY Code=%d';
sHint1                              = '摆摊或变身模式下禁止攻击';
sHint2                              = '骑马禁止攻击';
sHint3                              = '死亡或被麻痹禁止攻击';
sHint4                              = '5次攻击超速!限制:%d,当前:%d';
sHint5                              = '攻击忙复位!!!';
sHint6                              = '攻击不忙!!!';
begin
Result := False;
dwDelayTime := 0;
{$IF CATEXCEPTION = TRYEXCEPTION}
nCheckCode := 0;
{$IFEND}
if not m_boCanHit or m_boCatapultAttackMode then Exit;
{$IF CATEXCEPTION = TRYEXCEPTION}
try
{$IFEND}
    if m_boPneuma and m_PEnvir.m_MapFlag.boNoPneuma then Exit;                                    //元神在不允许释放的地图,禁止攻击
    if (m_wShopItemCount > 0) then begin
      if g_Config.boOldClientShowHiLevel then SysMsg(sHint1, c_Blue, t_Hint);
      Exit;
    end;
    if (m_wBianshenAppr > 0) and (m_boAttackMode = False) then begin
      if g_Config.boOldClientShowHiLevel then SysMsg(sHint1, c_Blue, t_Hint);                     //2016.06.22 支持ChangeAppr变身支持攻击
      Exit;
    end;
    if (m_boRideOn and not m_boRideFightOn) then begin
      if g_Config.boOldClientShowHiLevel then SysMsg(sHint2, c_Blue, t_Hint);
      Exit;                                                                                       //骑马不允许攻击
    end;
    if not CheckCanOperate(cHit) then begin
      if g_Config.boOldClientShowHiLevel then SysMsg(sHint3, c_Blue, t_Hint);
      Exit;
    end;

    //10指令时间控制
    if (not g_Config.boDisableM2SpeedCtrl) then begin
      if m_nHitCount = 0 then m_FirstHitTick := GetTickCount;
      Inc(m_nHitCount);
      if m_nHitCount >= 6 then begin
      nPinjunTime := (GetTickCount - m_FirstHitTick) div 5;
      m_FirstHitTick := GetTickCount;
      m_nHitCount := 0;
      if nPinjunTime < g_Config.n10HitTIme then begin
          if m_boTestSpeedMode then
            SysMsg(Format(sHint4, ), c_Red, t_Hint);
          Exit;
      end;
      end;

{$IF CATEXCEPTION = TRYEXCEPTION}
      nCheckCode := 1;
{$IFEND}
      if (not boLateDelivery) then begin
      if not CheckActionStatus(wIdent, dwDelayTime) then begin
          m_boFilterAction := False;
          Exit;
      end;
      m_boFilterAction := True;
      dwAttackTime := _Max(0, Integer(g_Config.dwHitIntervalTime) - m_nHitSpeed * g_Config.ClientConf.btItemSpeed); //防止负数出错
      dwCheckTime := GetTickCount - m_dwAttackTick;
      if dwCheckTime < dwAttackTime then begin
          if m_dwWalkTick = 0 then
            Inc(m_dwAttackCount);
          dwDelayTime := dwAttackTime - dwCheckTime;
          if dwDelayTime > g_Config.dwDropOverSpeed then begin
            if m_dwAttackCount >= 4 then begin
            m_dwAttackTick := GetTickCount();
            m_dwAttackCount := 0;
            dwDelayTime := g_Config.dwDropOverSpeed;
            if m_boTestSpeedMode then
                SysMsg(sHint5 + IntToStr(dwDelayTime), c_Red, t_Hint);
            end else m_dwAttackCount := 0;
            Exit;
          end else begin
            if m_boTestSpeedMode then
            SysMsg(sHint6 + IntToStr(dwDelayTime), c_Red, t_Hint);
            Exit;
          end;
      end;
      end;
    end;

{$IF CATEXCEPTION = TRYEXCEPTION}
    nCheckCode := 2;
{$IFEND}

    CheckProwlMagic();                                                                              //检测是否有潜行

    if (nX = m_nCurrX) and (nY = m_nCurrY) or (wIdent = CM_HIT) then begin
      Result := True;
      m_dwAttackTick := GetTickCount();
      if (wIdent = CM_HEAVYHIT) and (m_UseItems.Dura > 0) then begin                      //挖矿
      if g_Config.boStartMapEvent then begin
          if m_btRaceServer = RC_PLAYOBJECT then StartMapEventOfMine();
      end;

      if GetFrontPosition(n14, n18) and not m_PEnvir.CanWalk(n14, n18, False) then begin
          StdItem := UserEngine.GetStdItem(m_UseItems.wIndex);
          if (StdItem <> nil) and (StdItem.Shape = 19) then begin
            if PileStones(n14, n18) then SendSocket(nil, sSTATUS_DIG);

            Dec(m_nHealthTick, 30);
            Dec(m_nSpellTick, 50);
            m_nSpellTick := _Max(0, m_nSpellTick);
            Dec(m_nPerHealth, 2);
            Dec(m_nPerSpell, 2);
            Exit;
          end;
      end
      end else if (wIdent = CM_HIT) and (m_UseItems.Dura > 0) then begin
{$IF CATEXCEPTION = TRYEXCEPTION}
      nCheckCode := 3;
{$IFEND}
      AttackTarget := GetPoseCreate();
      if (AttackTarget <> nil) and not AttackTarget.m_boDeath and not AttackTarget.m_boGhost and (AttackTarget.m_wAppr in ) then begin
          StdItem := UserEngine.GetStdItem(m_UseItems.wIndex);
          if (StdItem <> nil) and (StdItem.Shape = 39) then begin
            if (m_Horse = nil) and (Random(10) = 0) and
            ((AttackTarget.m_wAppr <> 152) or (IsGuildMaster)) then begin                         //抓马成功,其中雪龙只有行会掌门才能抓
            HorseName := FilterShowName(AttackTarget.m_sCharName);
            m_Horse := MakeSlave(HorseName, 0, 0, 100, 24 * 60 * 60, -1);
            if m_Horse <> nil then begin
                m_btHorseType := AttackTarget.m_wAppr - 150;

                if m_PEnvir.MoveToMovingObject(m_Horse.m_nCurrX, m_Horse.m_nCurrY, m_Horse, AttackTarget.m_nCurrX, AttackTarget.m_nCurrY, True) > 0 then begin
                  m_Horse.m_nCurrX := AttackTarget.m_nCurrX;
                  m_Horse.m_nCurrY := AttackTarget.m_nCurrY;
                  m_Horse.m_btDirection := AttackTarget.m_btDirection;
                end;
                m_Horse.TurnTo(m_btDirection);
                SendDefMessage(34977, m_Horse.m_wAppr, 612, 1, 0, '');
                SendRefMsg(RM_SITDOWN, m_btDirection, MakeLong(m_nCurrX, m_nCurrY), GetFeatureToLong(Self), 0, '');
                AttackTarget.MakeGhost;
                ExecuteScript(g_FunctionNPC, '@抓马成功');
            end;
            Exit;
            end;
            Exit;
          end;
      end;
      end;
{$IF CATEXCEPTION = TRYEXCEPTION}
      nCheckCode := 4;
{$IFEND}

      if wIdent = CM_HIT then AttackDir(nil, 0, nDir);                                              //普通攻击0
      if wIdent = CM_HEAVYHIT then AttackDir(nil, 1, nDir);                                       //普通攻击1 挖矿
      if wIdent = CM_BIGHIT then AttackDir(nil, 2, nDir);                                           //普通攻击2
      if wIdent = CM_POWERHIT then AttackDir(nil, 3, nDir);                                       //攻杀剑法
      if wIdent = CM_LONGHIT then AttackDir(nil, 4, nDir);                                          //刺杀剑术
      if wIdent = CM_WIDEHIT then AttackDir(nil, 5, nDir);                                          //半月弯刀
      if wIdent = CM_FIREHIT then AttackDir(nil, 7, nDir);                                          //烈火剑法
      if wIdent = CM_CRSHIT then AttackDir(nil, 8, nDir);
      if wIdent = CM_TWNHIT then AttackDir(nil, 9, nDir);
      //      if wIdent = CM_42HIT then AttackDir(nil, 10, nDir);
{$IF CATEXCEPTION = TRYEXCEPTION}
      nCheckCode := 5;
{$IFEND}
      if wIdent = CM_3026 then begin                                                                //战士新技能的攻击包处理:血影刀法\抱月刀\ 残影刀法   破击剑法、破盾斩
      case nMagicID of
          SKILL_59: AttackDir(nil, 12, nDir);                                                       //破击剑法
          SKILL_60: AttackDir(nil, 13, nDir);                                                       //破盾斩
          SKILL_43: AttackDir(nil, 14, nDir);                                                       //抱月刀
          SKILL_44: AttackDir(nil, 15, nDir);                                                       //雷霆剑
          SKILL_40: AttackDir(nil, 16, nDir);                                                       //残影刀法
          SKILL_41: AttackDir(nil, 17, nDir);                                                       //血影刀法
          SKILL_88: AttackDir(nil, 18, nDir);                                                       //强化攻杀
      end;
      end;

{$IF CATEXCEPTION = TRYEXCEPTION}
      nCheckCode := 6;
{$IFEND}
      if (m_MagicSkills <> nil) and (m_UseItems.Dura > 0) then begin
      Dec(m_btAttackSkillCount);
      if m_btAttackSkillPointCount = m_btAttackSkillCount then begin
          m_boPowerHit := True;
          SendSocket(nil, '+PWR');
      end;

      //出刀几率
      if m_btAttackSkillCount <= 0 then begin
          if g_Config.boUseXMLMagicSkill then begin
            //if (m_MagicSkills <> nil) then
            //m_btAttackSkillCount := g_MagicSkill.btLv.btLevel].btVal
            //else
            m_btAttackSkillCount := g_MagicSkill.btLv.btLevel].btVal;
          end else begin
            //if (m_MagicSkills <> nil) then
            //m_btAttackSkillCount := 10 - _MIN(m_MagicSkills.btLevel, 3)
            //else
            m_btAttackSkillCount := 8 - _MIN(m_MagicSkills.btLevel, 3);
          end;
          m_btAttackSkillPointCount := Random(m_btAttackSkillCount);
      end;
      end else if (m_MagicSkills <> nil) and (m_UseItems.Dura > 0) then begin
      Dec(m_btAttackSkillCount);
      if m_btAttackSkillPointCount = m_btAttackSkillCount then begin
          m_boPowerHit := True;
          SendSocket(nil, '+VIS');
      end;

      if m_btAttackSkillCount <= 0 then begin
          if g_Config.boUseXMLMagicSkill then
            m_btAttackSkillCount := g_MagicSkill.btLv.btLevel].btVal
          else
            m_btAttackSkillCount := 8 - _MIN(m_MagicSkills.btLevel, 3);

          m_btAttackSkillPointCount := Random(m_btAttackSkillCount);
      end;
      end else if (m_MagicSkills <> nil) and (m_UseItems.Dura > 0) then begin
      Dec(m_btAttackSkillCount);
      if m_btAttackSkillPointCount = m_btAttackSkillCount then begin
          m_boPowerHit := True;
          SendSocket(nil, '+SHAD');
      end;

      if m_btAttackSkillCount <= 0 then begin
          if g_Config.boUseXMLMagicSkill then
            m_btAttackSkillCount := g_MagicSkill.btLv.btLevel].btVal
          else
            m_btAttackSkillCount := 8 - _MIN(m_MagicSkills.btLevel, 3);

          m_btAttackSkillPointCount := Random(m_btAttackSkillCount);
      end;
      end;

{$IF CATEXCEPTION = TRYEXCEPTION}
      nCheckCode := 7;
{$IFEND}
      Dec(m_nHealthTick, 30);
      Dec(m_nSpellTick, 100);
      m_nSpellTick := _Max(0, m_nSpellTick);
      Dec(m_nPerHealth, 2);
      Dec(m_nPerSpell, 2);
    end;
{$IF CATEXCEPTION = TRYEXCEPTION}
except
    on E: Exception do begin
      MainOutMessage(Format(sExceptionMsg, ));
      MainOutMessage(E.Message);
    end;
end;
{$IFEND}
end;

//骑马(CM_HORSERUN 命令的处理)
(*
function TPlayObject.ClientHorseRunXY(wIdent: word; nX, nY: Integer;
boLateDelivery: Boolean; var dwDelayTime: LongWord): Boolean;
var
n14                              : Integer;
dwCheckTime                      : LongWord;
resourcestring
sHint1                           = '马跑步忙复位!!!';
sHint2                           = '马跑步忙!!!';
begin
Result := False;
dwDelayTime := 0;
Exit;
if not m_boCanRun or (m_wShopItemCount > 0) then Exit;

if not CheckCanOperate(cHorseRun) then Exit;

if (not g_Config.boDisableM2SpeedCtrl) and (not boLateDelivery) then begin
    if not CheckActionStatus(wIdent, dwDelayTime) then begin
      m_boFilterAction := False;
      Exit;
    end;
    m_boFilterAction := True;
    dwCheckTime := GetTickCount - m_dwMoveTick;
    if dwCheckTime < g_Config.dwRunIntervalTime then begin
      Inc(m_dwMoveCount);
      dwDelayTime := g_Config.dwRunIntervalTime - dwCheckTime;
      if dwDelayTime > g_Config.dwDropOverSpeed then begin
      if m_dwMoveCount >= 4 then begin
          m_dwMoveTick := GetTickCount();
          m_dwMoveCount := 0;
          dwDelayTime := g_Config.dwDropOverSpeed;
          if m_boTestSpeedMode then
            SysMsg(sHint1 + IntToStr(dwDelayTime), c_Red, t_Hint);
      end else m_dwMoveCount := 0;
      Exit;
      end else begin
      if m_boTestSpeedMode then
          SysMsg(sHint2 + IntToStr(dwDelayTime), c_Red, t_Hint);
      Exit;
      end;
    end;
end;

m_dwMoveTick := GetTickCount();
m_boMoveSuccess := False;
{$IF USESDK = DEBUG}
SysMsg(Format('当前X:%d 当前Y:%d 目标X:%d 目标Y:%d', ), c_Green, t_Hint);
{$IFEND}
n14 := GetNextDirection(m_nCurrX, m_nCurrY, nX, nY);
if HorseRunTo(n14, False) then begin
    if m_boTransparent and (m_boHideMode) then
      m_wStatusTimeArr := 1;                                                   //004CB212
    if m_boMoveSuccess or ((m_nCurrX = nX) and (m_nCurrY = nY)) then
      Result := True;
    Dec(m_nHealthTick, 60);
    Dec(m_nSpellTick, 10);
    m_nSpellTick := _Max(0, m_nSpellTick);
    Dec(m_nPerHealth);
    Dec(m_nPerSpell);
end else begin
    m_dwMoveCount := 0;
    m_dwMoveCountA := 0;
end;
end;
*)

procedure TPlayObject.ClientInjectPowerToTreasureBox(nPoint: Integer);
var
tm, tm2                               : DWORD;
d                                     : TDateTime;
n                                     : Integer;
begin
if (nPoint <= 0) or (m_TreasureBoxItem = nil) then Exit;
if (m_Abil.wNimBusPoint < nPoint) then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, Format('你的灵力不足%d点,无法为灵犀宝盒注入灵力', ));
    Exit;
end;
Dec(m_Abil.wNimBusPoint, nPoint);
RecalcAbilitys();
SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
tm := MakeLong(MakeWord(m_TreasureBoxItem.btValue, m_TreasureBoxItem.btValue), MakeWord(m_TreasureBoxItem.btValue, m_TreasureBoxItem.btValue));
tm2 := DateTimeToWolTimeEx(Now);
if (tm2 > tm) then tm := tm2;
n := Round(7 * nPoint / m_TreasureBoxItem.DuraMax);
d := AddDateTimeOfDay(WolTimeToDateTime(tm), n + 1);
tm := DateTimeToWolTimeEx(d);                                                                     //到期时间
Move(tm, m_TreasureBoxItem.btValue, 4);
ClientQueryTreasureBoxItems(False);
SendDefMessage(SM_INFORMATION, 0, 0, 0, 0,
    Format('你已经为宝盒注入%d点灵力\(当前灵力可维持宝盒到%s)', ));
end;

procedure TPlayObject.ClientInput(nParam1: Integer; Data: string);
var
NPC                                 : TNormNpc;
s18, sLable                           : string;
nCheckCode                            : Integer;
begin
nCheckCode := 0;
try
    if m_boDeath or m_boGhost then Exit;

    if Length(Data) > 500 then Exit;
    nCheckCode := 1;
    if m_nQueryValIdx in then begin
      if m_btQueryValType = 1 then                                                                  //整数型数据保存到M变量中
      m_nMval := Str_ToInt(Data, 0)
      else begin                                                                                    //字符型变量保存到S变量中
      if CheckFilterWords(Data) then begin
          SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, '输入内容含有非法字符!');
          Exit;
      end;
      m_dyStrVal := Data;
      end;
    end else begin
      m_sQueryData := Data;
    end;

    if m_sNextLabel = '' then Exit;
    nCheckCode := 2;
    NPC := UserEngine.FindMerchant(m_QUERYNPC);
    if NPC = nil then
      NPC := UserEngine.FindNPC(m_QUERYNPC);

    if NPC = nil then Exit;
    nCheckCode := 3;
    if (IsEnvir(NPC.m_PEnvir) and
      (abs(NPC.m_nCurrX - m_nCurrX) < 15) and
      (abs(NPC.m_nCurrY - m_nCurrY) < 15)) or (NPC.m_boIsHide) then begin
      nCheckCode := 4;
      if CompareText(m_sNextLabel, sBUILDGUILDNOW) = 0 then begin                                 //建立行会
      nCheckCode := 5;
      if NPC is TGuildOfficial then
          TGuildOfficial(NPC).ReQuestBuildGuild(Self, Data);
      end else if CompareText(m_sNextLabel, sSCL_GUILDWAR) = 0 then begin                           //行会战争
      nCheckCode := 6;
      if NPC is TGuildOfficial then
          TGuildOfficial(NPC).ReQuestGuildWar(Self, Data);
      end else if CompareText(m_sNextLabel, sWITHDRAWAL) = 0 then begin                           //取回金币
      nCheckCode := 7;
      if NPC.m_Castle = nil then begin
          SysMsg('NPC不属于城堡!!!', c_Red, t_Hint);
          Exit;
      end;
      case TUserCastle(NPC.m_Castle).WithDrawalGolds(Self, Str_ToInt(Data, 0))
          of
          -4: s18 := '输入的金币数不正确!!!';
          -3: s18 := '您无法携带更多的东西了。';
          -2: s18 := '该城内没有这么多金币.';
          -1: s18 := '只有行会 ' + TUserCastle(NPC.m_Castle).m_sOwnGuild + ' 的掌门人才能使用!!!';
          1: begin
            s18 := '取回金币成功!';
            NPC.GotoLable(Self, sMAIN, False);
            end;
      end;
      SendMsg(NPC, RM_MENU_OK, 0, Integer(NPC), 0, 0, s18);
      end else if CompareText(m_sNextLabel, sRECEIPTS) = 0 then begin                               //存放金币
      nCheckCode := 8;
      if NPC.m_Castle = nil then begin
          SysMsg('NPC不属于城堡!!!', c_Red, t_Hint);
          Exit;
      end;
      case TUserCastle(NPC.m_Castle).ReceiptGolds(Self, Str_ToInt(Data, 0)) of
          -4: s18 := '输入的金币数不正确!!!';
          -3: s18 := '你已经达到在城内存放货物的限制了。';
          -2: s18 := '你没有那么多金币.';
          -1: s18 := '只有行会 ' + TUserCastle(NPC.m_Castle).m_sOwnGuild + ' 的掌门人才能使用!!!';
          1: begin
            s18 := '存放金币成功!';
            NPC.GotoLable(Self, sMAIN, False);
            end;
      end;
      SendMsg(NPC, RM_MENU_OK, 0, Integer(NPC), 0, 0, s18);
      end else begin
      nCheckCode := 9;
      sLable := m_sNextLabel;
      m_sNextLabel := '';
      NPC.GotoLable(Self, sLable, False);                                                         //其他标签
      end;
    end;
except
    on E: Exception do begin
      MainOutMessage(Format('TPlayObject.ClientInput:: nParam1: %d; Data: %s; Lable: %s Code: %d', ));
      MainOutMessage(E.Message);
    end;
end;
end;

//炼药

procedure TPlayObject.ClientMakeDrugItem(NPC: TObject; nItemName: string);
//004DCAF8
var
Merchant                              : TMerchant;
begin
Merchant := UserEngine.FindMerchant(NPC);
if (Merchant = nil) or (not Merchant.m_boMakeDrug) then Exit;
if (IsEnvir(Merchant.m_PEnvir) and
    (abs(Merchant.m_nCurrX - m_nCurrX) < 15) and
    (abs(Merchant.m_nCurrY - m_nCurrY) < 15)) then
    Merchant.ClientMakeDrugItem(Self, nItemName);
end;

//CM_MERCHANTDLGSELECT 选择标签

procedure TPlayObject.ClientMerchantDlgSelect(nParam1: Integer; sMsg: string; nType: Integer);
var
NPC                                 : TNormNpc;
begin
if m_boDeath or m_boGhost then Exit;

//if nParam1 = 0 then begin
//    ExecuteScript(g_FunctionNPC, sMsg);
//    Exit;
//end;

    //通灵塔NPC
case nParam1 of
    -6:
      begin
{$IF USESDK = DEBUG}
      MainOutMessage('通灵塔跳转:' + sMsg);
{$IFEND}
      if (g_GuildTowerNPC <> nil) and (sMsg <> '') then g_GuildTowerNPC.UserSelect(Self, Trim(sMsg));
      Exit;
      end;
    -7:
      begin
{$IF USESDK = DEBUG}
      MainOutMessage('商城活动领奖:' + sMsg);
{$IFEND}
   // GetScriptLabel('@VIP每日福利', false);
      if (g_WolShopNPC <> nil) and (sMsg <> '') then ExecuteScript(g_WolShopNPC, '@_商城_活动领奖');
      Exit;
      end;
    -12:
      begin
{$IF USESDK = DEBUG}
      MainOutMessage('时光倒流VIP每日福利:' + sMsg);
{$IFEND}
   // GetScriptLabel('@VIP每日福利', false);
      if (g_ManageNPC <> nil) and (sMsg <> '') then ExecuteScript(g_ManageNPC, '@_VIP_每日福利');
      Exit;
      end;
    -13:
      begin
{$IF USESDK = DEBUG}
      MainOutMessage('时光倒流VIP神行千里:' + sMsg);
{$IFEND}
   // GetScriptLabel('@VIP神行千里', false);
      if (g_ManageNPC <> nil) and (sMsg <> '') then ExecuteScript(g_ManageNPC, '@_VIP_神行千里');
      Exit;
      end;
    -14:
      begin
{$IF USESDK = DEBUG}
      MainOutMessage('时光倒流VIP神龙之魂:' + sMsg);
{$IFEND}
   // GetScriptLabel('@VIP神龙之魂', false);
      if (g_ManageNPC <> nil) and (sMsg <> '') then ExecuteScript(g_ManageNPC, '@_VIP_神龙之魂');
      Exit;
      end;
    -15:
      begin
{$IF USESDK = DEBUG}
      MainOutMessage('未知:' + sMsg);
{$IFEND}
    //GetScriptLabel('@未知', false);
      if (g_FunctionNPC <> nil) and (sMsg <> '') then ExecuteScript(g_FunctionNPC, '@未知');
      Exit;
      end;
    -16:
      begin
{$IF USESDK = DEBUG}
      MainOutMessage('战斗力:' + sMsg);
{$IFEND}
      m_BattleVal.BattleVal := m_BattleVal.nMinVal + m_BattleVal.nMinVal +
          m_BattleVal.nMinVal + m_BattleVal.nMinVal + m_BattleVal.nMinVal;
      SendDefMessage(SM_BATTLEVAL, Integer(Self), m_BattleVal.BattleVal, 0, 0,
          EnCodeBuffer(@m_BattleVal, SizeOf(TBattleData)), True);
      if (g_ManageNPC <> nil) and (sMsg <> '') then
      begin
          if nType > 0 then
            ExecuteScript(g_ManageNPC, '@_战斗力_HOME')
          else
            g_ManageNPC.UserSelect(self, sMsg);
      end;
      Exit;
      end;
else
    begin
{$IF USESDK = DEBUG}
      MainOutMessage('Code: ' + inttostr(nParam1) + '其他NPC跳转:' + sMsg);
{$IFEND}
    end;

end;

NPC := UserEngine.FindMerchant(TObject(nParam1));
if NPC = nil then NPC := UserEngine.FindNPC(TObject(nParam1));
if NPC = nil then Exit;
if (IsEnvir(NPC.m_PEnvir) and
    (abs(NPC.m_nCurrX - m_nCurrX) < 15) and
    (abs(NPC.m_nCurrY - m_nCurrY) < 15)) or (NPC.m_boIsHide) then
    NPC.UserSelect(Self, Trim(sMsg));
end;

//计算商品价格

procedure TPlayObject.ClientMerchantQuerySellPrice(nParam1, nMakeIndex: Integer;
sMsg: string);
var
i                                     : Integer;
UserItem                              : pTUserItem;
UserItem18                            : pTUserItem;
Merchant                              : TMerchant;
sName                                 : string;
begin
UserItem18 := nil;
for i := 0 to m_ItemList.Count - 1 do begin
    UserItem := m_ItemList.Items;
    if UserItem.MakeIndex = nMakeIndex then begin
      //取自定义物品名称
      sName := '';
      ItemUnit.GetCustomItemName(UserItem, sName);

      if (CompareText(sMsg, sName) = 0) then begin
      UserItem18 := UserItem;
      Break;
      end;
    end;
end;
if UserItem18 = nil then begin
    SendDefMessage(618, nMakeIndex, 1, 0, 0, '');
    Exit;
end;
Merchant := UserEngine.FindMerchant(TObject(nParam1));
if Merchant = nil then Exit;
if (IsEnvir(Merchant.m_PEnvir) and
    (Merchant.m_boSell) and
    (abs(Merchant.m_nCurrX - m_nCurrX) < 15) and
    (abs(Merchant.m_nCurrY - m_nCurrY) < 15)) then
    Merchant.ClientQuerySellPrice(Self, UserItem18);
end;

procedure TPlayObject.ClientNamedStore(nParam1: Integer; nMakeIndex: Integer);
var
NPC                                 : TNormNpc;
i, j                                  : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
retMsg, sLable                        : string;
tm                                    : DWORD;
label
return;
begin
retMsg := '';
if m_boDeath or m_boGhost then goto return;
NPC := UserEngine.FindMerchant(TObject(nParam1));
if NPC = nil then NPC := UserEngine.FindNPC(TObject(nParam1));
if (NPC = nil) and not (m_nSpotDlgMode in ) then
    Exit;
sLable := m_sNextLabel;
m_sNextLabel := '';
if (m_nSpotDlgMode in ) or
    ((IsEnvir(NPC.m_PEnvir) and
    (abs(NPC.m_nCurrX - m_nCurrX) < 15) and
    (abs(NPC.m_nCurrY - m_nCurrY) < 15)) or (NPC.m_boIsHide)) then begin
    for i := m_ItemList.Count - 1 downto 0 do begin
      UserItem := pTUserItem(m_ItemList.Items);
      if UserItem.MakeIndex = nMakeIndex then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if (StdItem = nil) then goto return;
      if (m_nSpotDlgMode = 0) and (StdItem.StdMode = 3) and ((StdItem.Shape = 15) or ((StdItem.Shape = 17) and ((StdItem.Looks = 729) or (StdItem.Looks = 942)))) then begin //记录回城点
          for j := 0 to 11 do
            UserItem.btValue := 0;
          UserItem.btValue := LoByte(m_nStoreX);
          UserItem.btValue := HiByte(m_nStoreX);
          UserItem.btValue := LoByte(m_nStoreY);
          UserItem.btValue := HiByte(m_nStoreY);
          for j := 1 to _MIN(11, Length(m_sStoreName)) do
            UserItem.btValue := byte(m_sStoreName);
          //更新物品
          SendUpdateItem(UserItem);
          if (sLable <> '') then
            NPC.GotoLable(Self, sLable, False);
      end else if (m_nSpotDlgMode = 1) and (StdItem.StdMode = 45) and
          (StdItem.AniCount in ) then begin                                                   //宝石仓库
          //检查宝石仓库容量
          if m_wGemCount >= 200 then begin
            retMsg := '仓库中已经有200颗这种宝石了,无法放下更多的宝石!';
            goto return;
          end;
          Inc(m_wGemCount);

          SendDefMessage(SM_STORAGE_OK, 0, 0, 0, 0, '');                                          //0419
          if StdItem.boGameLog = 1 then
            AddGameDataLog('1' + #9 +
            m_sMapName + #9 +
            IntToStr(m_nCurrX) + #9 +
            IntToStr(m_nCurrY) + #9 +
            m_sCharName + #9 +
            StdItem.Name + #9 +
            IntToStr(UserItem.MakeIndex) + #9 +
            '1' + #9 +
            '0');

          if (sLable <> '') and (NPC <> nil) then
            NPC.GotoLable(Self, sLable, False);

          Dispose(UserItem);
          m_ItemList.Delete(i);
          WeightChanged();

      end else if (m_nSpotDlgMode = 3) and (StdItem.StdMode = 33) and (StdItem.Shape = 0) then begin //绑马牌
          if m_btSetHorseType > 0 then begin
            if UserItem.btValue <> 0 then begin
            retMsg := '你提供的马牌不是空的马牌。';
            Break;
            end;
          end else if UserItem.btValue = 0 then begin
            retMsg := '你提供的马牌是空的马牌,不需要清空。';
            Break;
          end;
          for j := 0 to 12 do
            UserItem.btValue := 0;
          UserItem.btValue := m_btSetHorseType;
          if m_btSetHorseType > 0 then
            for j := 1 to Length(m_sHorseName) do
            UserItem.btValue := byte(m_sHorseName);
          UserItem.Dura := UserItem.DuraMax;
          SendUpdateItem(UserItem);
          if (sLable <> '') and (NPC <> nil) then
            NPC.GotoLable(Self, sLable, False);
      end else if (m_nSpotDlgMode = 4) and (StdItem.StdMode = 33) and (StdItem.Shape = 0) then begin //修理马牌
          if UserItem.btValue = 0 then begin
            retMsg := '你提供的马牌是空马牌。';
            Break;
          end;
          UserItem.Dura := UserItem.DuraMax;
          SendUpdateItem(UserItem);
          if (sLable <> '') then
            NPC.GotoLable(Self, sLable, False);
      end else if (m_nSpotDlgMode = 6) then begin                                                 //任意物品 ,触发当前NPC中的[@物品名称]脚本标签
          try
            m_sStoreName := StdItem.Name;                                                         //保存物品名字
            m_nStoreMakeIndex := nMakeIndex;
            m_sScriptParam := StdItem.Name;
            m_sScriptParam := IntToStr(nMakeIndex);
            if not NPC.GotoLable(Self, '@' + StdItem.Name, False) then
            if sLable <> '' then begin
                m_sNextLabel := sLable;
                NPC.GotoLable(Self, sLable, False);
            end;
          except
          end;
      end else
          retMsg := '你提供的物品不正确。';
      sLable := '';
      Break;
      end;
    end;
end;
return:
SendMsg(nil, $9590, 1, $FF, 0, 0, retMsg);
end;

procedure TPlayObject.ClientOpenDoor(nX, nY: Integer);                                              //004DABD4
var
Door                                  : pTDoorInfo;
Castle                              : TUserCastle;
begin
Door := m_PEnvir.GetDoor(nX, nY);
if Door = nil then Exit;
Castle := g_CastleManager.IsCastleEnvir(m_PEnvir);
if (Castle = nil) or
    (Castle.m_DoorStatus <> Door.Status) or
    (m_btRaceServer <> RC_PLAYOBJECT) or
    Castle.CheckInPalace(m_nCurrX, m_nCurrY, Self) then begin
    UserEngine.OpenDoor(m_PEnvir, nX, nY);
end;
end;

//行会

procedure TPlayObject.ClientOpenGuildDlg;                                                         //004DE8E0
var
i                                     : Integer;
SC                                    : string;
begin

if m_MyGuild <> nil then begin
    SC := TGuild(m_MyGuild).sGuildName + #13 + ' ' + #13;
    if m_nGuildRankNo = 1 then begin
      SC := SC + '1' + #13;
    end else begin
      SC := SC + '0' + #13;
    end;
    SC := SC + '<Notice>' + #13;
    for i := 0 to TGuild(m_MyGuild).NoticeList.Count - 1 do begin
      if Length(SC) > 5000 then Break;
      SC := SC + TGuild(m_MyGuild).NoticeList.Strings + #13;
    end;                                                                                          // for
    SC := SC + '<KillGuilds>' + #13;
    for i := 0 to TGuild(m_MyGuild).m_GuildWarList.Count - 1 do begin
      if Length(SC) > 5000 then Break;
      SC := SC + TGuild(m_MyGuild).m_GuildWarList.Keys + #13;
    end;                                                                                          // for
    SC := SC + '<AllyGuilds>' + #13;
    for i := 0 to TGuild(m_MyGuild).m_GuildAllList.Count - 1 do begin
      if Length(SC) > 5000 then Break;
      SC := SC + TGuild(m_MyGuild).m_GuildAllList.Keys + #13;
    end;                                                                                          // for
    m_defMsg := MakeDefaultMsg(SM_OPENGUILDDLG, 0, 0, 0, 1);
    SendSocket(@m_defMsg, EnCodeString(SC));
end else begin
    SendDefMessage(SM_OPENGUILDDLG_FAIL, 0, 0, 0, 0, '');
end;
end;

procedure TPlayObject.ClientOpenHuanjing(nItemIdx: Integer; nOpCode: Integer; nCount: Integer);
var
i, j                                  : Integer;
Huanjing, UserItem                  : pTUserItem;
StdItem                               : pTStdItem;
tm                                    : DWORD;
boFind                              : Boolean;
begin
{点领取剩余奖励: Ident 34980 Param 0 P1 1073750150 P2 6 P3 0 Msg
   点注入10点:   Ident 34980 Param 0 P1 1073750150 P2 4 P3 10 Msg
   镶嵌蓝宝:nItemIdx: 1073750152(蓝宝ID); sItemName: ;nPackIdx: 1073750150(幻镜ID) }
//找到幻镜:
if (m_nHuanjingIdx <> 0) and (m_nHuanjingIdx <> nItemIdx) then Exit;
Huanjing := nil;
for i := 0 to m_ItemList.Count - 1 do begin
    if pTUserItem(m_ItemList).MakeIndex = nItemIdx then begin
      Huanjing := pTUserItem(m_ItemList);
      Break;
    end;
end;
if Huanjing = nil then Exit;

case nOpCode of
    1: begin                                                                                        //双击打开
      if Huanjing.Dura > 0 then begin
          SendDefMessage(34980, nItemIdx, 513, 300, 3000, '');
          SendDefMessage(34980, nItemIdx, 769, 300, 3000, '');
          Exit;
      end else begin
          SendDefMessage(34980, nItemIdx, 513, 300, 3000, '');
          Exit;
      end;
      end;
    4: begin                                                                                        //注入灵力
      j := 0;
      for i := m_ItemList.Count - 1 downto 0 do begin
          UserItem := pTUserItem(m_ItemList);
          StdItem := UserEngine.GetStdItem(UserItem.wIndex);
          if (StdItem <> nil) and (StdItem.StdMode = 3) and (StdItem.Shape in ) then begin
            if StdItem.Shape = 202 then begin
            Dec(nCount);
            SendDelItems(UserItem);
            Dispose(UserItem);
            m_ItemList.Delete(i);
            WeightChanged;
            Inc(j);
            end else begin
            if UserItem.Dura >= nCount then begin                                                 //持久大于等于 数值
                Dec(UserItem.Dura, nCount);
                Inc(j, nCount);
                Dec(nCount, nCount);
            end else begin
                Inc(j, UserItem.Dura);
                Dec(nCount, UserItem.Dura);                                                         //增加点数
                UserItem.Dura := 0;
            end;
            if UserItem.Dura <= 0 then begin
                SendDelItems(UserItem);
                Dispose(UserItem);
                m_ItemList.Delete(i);
                WeightChanged;
            end else
                SendUpdateItem(UserItem);
            end;
            if nCount <= 0 then Break;
          end;
      end;

      Inc(Huanjing.Dura, j);
      if Huanjing.btValue = 0 then begin                                                       //开启时间,也就是最后领奖时间
          tm := DateTimeToWolTIme(Now);
          Huanjing.btValue := LoByte(LoWord(tm));
          Huanjing.btValue := HiByte(LoWord(tm));
          Huanjing.btValue := LoByte(HiWord(tm));
          Huanjing.btValue := HiByte(HiWord(tm));
      end;

      m_nHuanjingIdx := nItemIdx;
      m_dwHuanjingTick := GetTickCount;
      SendUpdateItem(Huanjing);
      SendDefMessage(34980, nItemIdx, 769, 300, 3000, '');
      SysMsg('你已成功为天关幻镜注入了' + IntToStr(j) + '个灵符的灵力', c_Red, t_Hint);
      if nCount = 0 then begin
          SysMsg('灵符的灵力使幻镜映射出无穷的宝藏,但如果灵力耗尽幻镜就会立刻碎裂', c_Red, t_Hint);
      end;
      end;
    6: begin
      if (Huanjing.Dura = 0) or ((Huanjing.btValue = 1) and
          (Huanjing.btValue = 1)) then begin                                                   //破碎后还可以领一次
          SysMsg('天关幻镜中没有累积的奖励可以领取', c_Red, t_Hint);
          Exit;
      end;
      //检查时间间隔
      tm := MakeLong(MakeWord(Huanjing.btValue, Huanjing.btValue),
          MakeWord(Huanjing.btValue, Huanjing.btValue));
      if tm + g_Config.nHuanjingGetGift <= DateTimeToWolTIme(Now) then begin
          if g_FunctionNPC <> nil then begin
            if tm = 0 then
            m_sScriptParam := '1'
            else
            m_sScriptParam := IntToStr((DateTimeToWolTIme(Now) - tm + 1) div
                g_Config.nHuanjingGetGift);
            m_sScriptParam := IntToStr(Huanjing.Dura);                                           //幻境灵力
            m_sScriptParam := IntToStr(Huanjing.btValue);
            //幻境状态 0正常 1破碎
            m_sScriptParam := m_PEnvir.m_sMapName;                                             //地图名
            m_sScriptParam := IntToStr(Huanjing.btValue);
            //幻境镶嵌宝石类型1 2 3 表示   0普通幻境
            m_sScriptParam := IntToStr(Huanjing.MakeIndex);                                    //幻境ID
            ExecuteScript(g_FunctionNPC, '@天关幻镜奖励');
            tm := DateTimeToWolTIme(Now);
            Huanjing.btValue := LoByte(LoWord(tm));
            Huanjing.btValue := HiByte(LoWord(tm));
            Huanjing.btValue := LoByte(HiWord(tm));
            Huanjing.btValue := HiByte(HiWord(tm));
            if (Huanjing.btValue = 1) and (Huanjing.btValue = 0) then
            Huanjing.btValue := 1;
          end;
      end else begin
          SysMsg('无法连续领取天关幻镜中奖励,请过会再来领取', c_Red, t_Hint);
{$IF USESDK = DEBUG}
          SysMsg('上次时间:' + IntToStr(tm) + ',当前时间:' + IntToStr(DateTimeToWolTIme(Now)), c_Red, t_Hint);
{$IFEND}
      end;
      end;
    260: begin
      if m_nGameGold >= nCount then begin
          Inc(Huanjing.Dura, nCount);
          if Huanjing.btValue = 0 then begin                                                   //开启时间,也就是最后领奖时间
            tm := DateTimeToWolTIme(Now);
            Huanjing.btValue := LoByte(LoWord(tm));
            Huanjing.btValue := HiByte(LoWord(tm));
            Huanjing.btValue := LoByte(HiWord(tm));
            Huanjing.btValue := HiByte(HiWord(tm));
          end;
          SendUpdateItem(Huanjing);
          //SendDefMessage(34980, nItemIdx, 513, 300, 3000, '');
          SendDefMessage(34980, nItemIdx, 769, 300, 3000, '');
          SysMsg('你已成功为天关幻镜注入了' + IntToStr(nCount) + '个灵符的灵力', c_Red, t_Hint);
          SysMsg('灵符的灵力使幻镜映射出无穷的宝藏,但如果灵力耗尽幻镜就会立刻碎裂', c_Red, t_Hint);
          Dec(m_nGameGold, nCount);                                                               //元宝减少
          Inc(m_nGamePoint, nCount);                                                                //积分增加
          GameGoldChanged;
          m_nHuanjingIdx := nItemIdx;
          m_dwHuanjingTick := GetTickCount;
      end;
      end;
end;
end;

function TPlayObject.ClientOpPneumaBagItem(sData: string): Boolean;
var
OpInfo                              : TPneumaItem;
UserItem                              : pTUserItem;
i, ii                                 : Integer;
StdItem                               : pTStdItem;
resourcestring
sHint1                              = '宝盒物品不能给元神分身';
sHint2                              = '该物品不能放入元神分身的包裹';
sHint3                              = '元神分身包裹里的东西太多或者负重不够';
sHint4                              = '玩家包裹里的东西太多或者负重不够';
begin
Result := False;
if sData = '' then Exit;
if m_boGhost or m_boDeath then Exit;
if (m_PneumaObject = nil) or m_PneumaObject.m_boGhost or
    m_PneumaObject.m_boDeath then Exit;

DeCodeBuffer(sData, @OpInfo, SizeOf(TPneumaItem));
if Integer(m_PneumaObject) <> OpInfo.nChrID then Exit;

if (OpInfo.btFlag = 1) then begin                                                               //移动物品到元神包裹
    for i := m_ItemList.Count - 1 downto 0 do begin
      UserItem := m_ItemList.Items;
      if (UserItem <> nil) and (UserItem.MakeIndex = OpInfo.nMakeIndex) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem = nil then Break;
      {物品控制-禁止放入元神包裹}
      if CheckSPCode(StdItem.SPCode, SP_DISABLEINPNEUMABAG) then begin
          SysMsg(sHint2, c_Red, t_Hint);
          Break;
      end;

      {已放出豹禁止放入元神包裹}
      if IsDownPetItem(UserItem.MakeIndex) then begin
          Break;
      end;

      if TPlayObject(m_PneumaObject).IsEnoughBag and
          TPlayObject(m_PneumaObject).IsAddWeightAvailable(UserEngine.GetStdItemWeight(UserItem.wIndex)) then begin
          m_ItemList.Delete(i);
          SendDelItems(UserItem);
          m_PneumaObject.m_ItemList.Add(UserItem);
          TPlayObject(m_PneumaObject).SendAddItem(UserItem);
          Result := True;
          WeightChanged();
          TPlayObject(m_PneumaObject).WeightChanged;
      end else begin
          SysMsg(sHint3, c_Red, t_Hint);
      end;
      Break;
      end;
    end;
end else if (OpInfo.btFlag = 0) then begin                                                      //元神包裹中的物品移动到人物
    for i := m_PneumaObject.m_ItemList.Count - 1 downto 0 do begin
      UserItem := m_PneumaObject.m_ItemList.Items;
      if (UserItem <> nil) and (UserItem.MakeIndex = OpInfo.nMakeIndex) then begin
      if IsEnoughBag and
          IsAddWeightAvailable(UserEngine.GetStdItemWeight(UserItem.wIndex)) then begin
          m_PneumaObject.m_ItemList.Delete(i);
          TPlayObject(m_PneumaObject).SendDelItems(UserItem);
          m_ItemList.Add(UserItem);
          SendAddItem(UserItem);
          Result := True;
          WeightChanged();
          TPlayObject(m_PneumaObject).WeightChanged;
      end else begin
          SysMsg(sHint4, c_Red, t_Hint);
      end;
      Break;
      end;
    end;
end;

if Result then
    OpInfo.btOpCode := 1
else
    OpInfo.btOpCode := 0;
m_defMsg := MakeDefaultMsg(SM_9608, Integer(Self), 0, 0, 0);
SendSocket(@m_defMsg, EnCodeBuffer(@OpInfo, SizeOf(TPneumaItem)));

//UserEngine.SaveHumanRcd(Self);
//UserEngine.SaveHumanRcd(TPlayObject(m_PneumaObject));
end;

function TPlayObject.ClientOpPneumaGold(sData: string): Boolean;
var
OpInfo                              : TPneumaItem;
resourcestring
sHint1                              = '你没有这么多钱';
sHint2                              = '你的分身没有这么多钱';
begin
Result := False;
if sData = '' then Exit;
if m_boGhost or m_boDeath then Exit;
if (m_PneumaObject = nil) or m_PneumaObject.m_boGhost or
    m_PneumaObject.m_boDeath then Exit;

DeCodeBuffer(sData, @OpInfo, SizeOf(TPneumaItem));
if (Integer(m_PneumaObject) <> OpInfo.nChrID) or (OpInfo.nMakeIndex <= 0) then
    Exit;

if (OpInfo.btFlag = 1) then begin                                                               //移动金币到元神包裹
    if OpInfo.nMakeIndex <= m_nGold then begin
      if TPlayObject(m_PneumaObject).IncGold(OpInfo.nMakeIndex) then begin
      TPlayObject(m_PneumaObject).GoldChanged;
      DecGold(OpInfo.nMakeIndex);
      GoldChanged;
      Result := True;
      end else
      TPlayObject(m_PneumaObject).SysMsg(g_sYourGoldLargeThenLimit, c_Red, t_Hint);
    end else
      SysMsg(sHint1, c_Red, t_Hint);
end else if (OpInfo.btFlag = 0) then begin                                                      //元神包裹中的金币移动到人物
    if OpInfo.nMakeIndex <= TPlayObject(m_PneumaObject).m_nGold then begin
      if IncGold(OpInfo.nMakeIndex) then begin
      GoldChanged;
      TPlayObject(m_PneumaObject).DecGold(OpInfo.nMakeIndex);
      TPlayObject(m_PneumaObject).GoldChanged;
      Result := True;
      end else
      SysMsg(g_sYourGoldLargeThenLimit, c_Red, t_Hint);
    end else
      SysMsg(sHint2, c_Red, t_Hint);
end;
end;

procedure TPlayObject.ClientPersonalSet(Parm1, Parm2, Parm3: Word; sMsg: string);
var
StyleConfig                           : TConfigStyle;
resourcestring
sHint                                 = '1分钟内只能设置一次';
sOK                                 = '设置成功';
begin
if GetTickCount < m_dwLastPersonalSetTick + 60 * 1000 then begin
    SysMsg(sHint, c_Red, t_Hint);
end else begin
    m_dwLastPersonalSetTick := GetTickCount;
    DeCodeBuffer(sMsg, @StyleConfig, SizeOf(TConfigStyle));
    m_sTmpRank := StyleConfig.chTempRank;
    m_sPersonalSign := StyleConfig.chStyleName;                                                   //UserEngine.m_PersonSignIni.WriteString(m_sCharName, 'Sign', m_sPersonalSign);
    //参数3是几个选择项
    m_wPersonalCode := Parm1;

    SysMsg(sOK, c_Green, t_Hint);
    SendDefMessage(SM_PERSONALSIGN, Integer(Self), 1, 0, m_wPersonalCode, m_sPersonalSign);
    SendDefMessage(SM_PERSONALSIGN, Integer(Self), 3, 1, 0, '');
    if m_sTmpRank <> '' then SendDefMessage(SM_PERSONALSIGN, Integer(Self), 2, 0, 0, m_sTmpRank);
    RefShowName;
    FeatureChanged;
    m_sScriptParam := m_sTmpRank;
    ExecuteScript(g_ManageNpc, '@封号_个性设置');
end;
end;

//凤凰探宝

procedure TPlayObject.ClientPhoenixSearch(nPetItem, nParm2: Integer);
var
tm, tm1                               : LongWord;
UserItem                              : pTUserItem;
begin
GetUserItemByMakeIndex(nPetItem, UserItem);
if UserItem = nil then Exit;

m_sScriptParam := IntToStr(nPetItem);
case nParm2 of
    0: begin                                                                                        //探宝
      if (m_Pet = nil) then Exit;
      if m_PetInfo.nMakeIndex <> nPetItem then Exit;
      m_Pet.SendRefMsg(RM_510, 1, 0, 108, 0, '');                                                 //凤凰消失

      m_PetInfo := m_PetInfo;
      PetHide(m_PetInfo.nMakeIndex);

      SendPetInfo($09);
      //记录探宝的时间
      tm := DateTimeToWolTIme(Now);
      UserItem.btItemExt := LoByte(LoWord(tm));
      UserItem.btItemExt := HiByte(LoWord(tm));
      UserItem.btItemExt := LoByte(HiWord(tm));
      UserItem.btItemExt := HiByte(HiWord(tm));
      ExecuteScript(g_ManageNPC, '@凤凰探宝');
      end;
    1: begin                                                                                        //召唤   - 计算探宝的时间
      //检查时间间隔
      tm := MakeLong(MakeWord(UserItem.btItemExt, UserItem.btItemExt), MakeWord(UserItem.btItemExt, UserItem.btItemExt));
      tm1 := MakeLong(MakeWord(UserItem.btValue, UserItem.btValue), MakeWord(UserItem.btValue, UserItem.btValue));
      tm1 := tm1 + 86400 * 4;                                                                     //饥饿
      tm := _MIN(DateTimeToWolTIme(Now), tm1) - tm;                                             //取最小的时间间隔
      UserItem.btItemExt := LoByte(LoWord(tm));
      UserItem.btItemExt := HiByte(LoWord(tm));
      UserItem.btItemExt := LoByte(HiWord(tm));
      UserItem.btItemExt := HiByte(HiWord(tm));
      //刷新石头状态
      m_defMsg := MakeDefaultMsg(34977, 0, 100, 0, 0);
      SendSocket(@m_defMsg, EnCodeBuffer(@nPetItem, 4));
      m_PetInfo.nMakeIndex := 0;
      m_PetInfo.wLevel := 0;
      m_PetInfo.btType := 0;
      m_PetInfo.btReLive := 0;
      end;
    2: begin                                                                                        //领宝
      //检查时间间隔
      tm := MakeLong(MakeWord(UserItem.btItemExt, UserItem.btItemExt), MakeWord(UserItem.btItemExt, UserItem.btItemExt));
      if tm + g_Config.nPhoenixGetGift <= DateTimeToWolTIme(Now) then begin
          if g_ManageNPC <> nil then begin
            //获取探宝时间秒数
            tm := MakeLong(MakeWord(UserItem.btItemExt, UserItem.btItemExt), MakeWord(UserItem.btItemExt, UserItem.btItemExt));
            m_sScriptParam := IntToStr(tm div 60);                                             //返回分钟
            ExecuteScript(g_ManageNPC, '@凤凰领宝');
            tm := DateTimeToWolTIme(Now);
            UserItem.btItemExt := LoByte(LoWord(tm));
            UserItem.btItemExt := HiByte(LoWord(tm));
            UserItem.btItemExt := LoByte(HiWord(tm));
            UserItem.btItemExt := HiByte(HiWord(tm));
          end;
      end else begin
          SysMsg('无法连续领取凤凰探宝的奖励,请过会再来领取', c_Red, t_Hint);
{$IF USESDK = DEBUG}
          SysMsg('上次时间:' + IntToStr(tm) + ',当前时间:' + IntToStr(DateTimeToWolTIme(Now)), c_Red, t_Hint);
{$IFEND}
      end;
      end;
end;
end;

function TPlayObject.ClientPickUpItem(nX, nY, nType: Integer): Boolean;
//捡物品

function IsSelf(BaseObject: TBaseObject): Boolean;
begin
    Result := (BaseObject = nil) or (Self = BaseObject) or (BaseObject.m_Master = Self) or (BaseObject.m_PneumaObject = Self);
end;

function IsOfGroup(BaseObject: TBaseObject): Boolean;
var
    i                                 : Integer;
    GroupMember, ItemOfCreat            : TBaseObject;
begin
    Result := False;
    //如果是元神
    if (m_btRaceServer = RC_PLAYOBJECT) and m_boPneuma and (m_PneumaObject <> nil) then begin
      m_GroupOwner := m_PneumaObject.m_GroupOwner;
    end;

    ItemOfCreat := BaseObject;
    if (BaseObject <> nil) and (BaseObject.m_btRaceServer = RC_PLAYOBJECT) and (BaseObject.m_boPneuma) and (BaseObject.m_PneumaObject <> nil) then begin
      ItemOfCreat := BaseObject.m_PneumaObject;
    end;

    if m_GroupOwner = nil then Exit;
    for i := 0 to m_GroupOwner.m_GroupMembers.Count - 1 do begin
      GroupMember := TBaseObject(m_GroupOwner.m_GroupMembers.Objects);
      if GroupMember = ItemOfCreat then begin
      Result := True;
      Break;
      end;
    end;
end;
var
UserItem                              : pTUserItem;
MapItem                               : pTMapItem;
StdItem                               : pTStdItem;
resourcestring
sHint1                              = '上古神魔的力量慢慢弱去,你的身体恢复正常。';
sHint2                              = '来自上古的神魔赐予了你一股神奇的力量';
sHint3                              = '你获得了秒杀的神力';
sHint4                              = '被激发的神魔秒杀结界,将帮助你杀怪物时的攻击力大增';
sHint5                              = '神力将持续%d分钟……';
sHint6                              = '你获得了重击的神力';
sHint7                              = '被激发的神魔重击结界,将帮助你有机会秒杀怪物';
sHint8                              = '你获得了神御的神力';
sHint9                              = '被激发的神魔防御结界,将帮助你抵御怪物的攻击';
sHint10                               = '你获得了神佑的神力';
sHint11                               = '神魔的眷顾可能让你在%d分钟内获得双倍的经验';
sHint12                               = '进入炼狱更有可能获得三倍……';
begin
Result := False;
if m_boPneuma and (m_boPneumaEffMode) then Exit;                                                //灵珠状态不能拾取物品
if m_boDealing or (m_wShopItemCount > 0) then Exit;

MapItem := m_PEnvir.GetItem(nX, nY);
if MapItem = nil then Exit;

//物品在2分钟之内不允许其他人捡
if (GetTickCount - MapItem.dwCanPickUpTick) > g_Config.dwFloorItemCanPickUpTime {2 * 60 * 1000} then begin
    MapItem.OfBaseObject := nil;
end;

//宝物在冻结状态下不能拾取,请耐心等待冻结时间消失
if (MapItem.OfBaseObject = g_FunctionNPC) then begin
    if (m_btRaceServer = RC_PLAYOBJECT) then
      SysMsg(g_sCanPickUpItemByFreeze {'宝物在冻结状态下不能拾取,请耐心等待冻结时间消失!'}, c_Red, t_Hint);
    Exit;
end;

//检查物品的主人
if not IsSelf(TBaseObject(MapItem.OfBaseObject)) and not IsOfGroup(TBaseObject(MapItem.OfBaseObject)) then begin
    if (m_btRaceServer = RC_PLAYOBJECT) then
      SysMsg(g_sCanotPickUpItem {'在一定时间以内无法捡起此物品!!!'}, c_Red, t_Hint);
    Exit;
end;

//脚本参数入口
m_sScriptParam := IntToStr(MapItem.UserItem.MakeIndex);
m_sScriptParam := MapItem.Name;
m_sScriptParam := IntToStr(MapItem.btDropBaseRace);
m_sScriptParam := MapItem.sDropBaseNams;
m_sScriptParam := IntToStr(nType);                                                            //是否豹子拾取
//捡金币
if CompareText(MapItem.Name, sSTRING_GOLDNAME) = 0 then begin
    if m_PEnvir.DeleteFromMap(nX, nY, OS_ITEMOBJECT, TObject(MapItem)) = 1 then begin
      if IncGold(MapItem.Count) then begin
      SendRefMsg(RM_ITEMHIDE, 0, Integer(MapItem), nX, nY, '');                                 //物品消失
      if g_boGameLogGold then
          AddGameDataLog('4' + #9 +
            m_sMapName + #9 +
            IntToStr(nX) + #9 +
            IntToStr(nY) + #9 +
            m_sCharName + #9 +
            sSTRING_GOLDNAME + #9 +
            IntToStr(MapItem.Count) + #9 +
            '1' + #9 +
            '0');
      GoldChanged;
      Dispose(MapItem);
      end else
      m_PEnvir.AddToMap(nX, nY, OS_ITEMOBJECT, TObject(MapItem));
    end;
    if g_Config.boStartMapEvent and (m_btRaceServer = RC_PLAYOBJECT) then begin
      StartMapEventOfPickUpItem(sSTRING_GOLDNAME);
    end;
    Exit;
end;
//绑定金币
if CompareText(MapItem.Name, sSTRING_BINDGOLDNAME) = 0 then begin
    if m_PEnvir.DeleteFromMap(nX, nY, OS_ITEMOBJECT, TObject(MapItem)) = 1 then begin
      if IncBindGold(MapItem.Count) then begin
      SendRefMsg(RM_ITEMHIDE, 0, Integer(MapItem), nX, nY, '');                                 //物品消失
      if g_boGameLogGold then
          AddGameDataLog('4' + #9 +
            m_sMapName + #9 +
            IntToStr(nX) + #9 +
            IntToStr(nY) + #9 +
            m_sCharName + #9 +
            sSTRING_BINDGOLDNAME + #9 +
            IntToStr(MapItem.Count) + #9 +
            '1' + #9 +
            '0');
      GoldChanged(1);
      Dispose(MapItem);
      end else
      m_PEnvir.AddToMap(nX, nY, OS_ITEMOBJECT, TObject(MapItem));
    end;
    if g_Config.boStartMapEvent and (m_btRaceServer = RC_PLAYOBJECT) then begin
      StartMapEventOfPickUpItem(sSTRING_BINDGOLDNAME);
    end;
    Exit;
end;

//捡到附身物品
StdItem := UserEngine.GetStdItem(MapItem.UserItem.wIndex);
if (StdItem <> nil) then begin
    if (StdItem.StdMode = 57) and (m_btRaceServer = RC_PLAYOBJECT) and (nType = 0) then begin
      if m_PEnvir.DeleteFromMap(nX, nY, OS_ITEMOBJECT, TObject(MapItem)) = 1 then begin
      if m_wFushen > 0 then
          SysMsg(sHint1, c_Red, t_Hint);
      m_wFushen := StdItem.Shape;
      m_dwFushenTime := StdItem.AniCount * 60000;
      m_dwFushenTick := GetTickCount;
      m_nMagicStatus := GetMagicStatus();
      Status2Changed();
      SysMsg(sHint2, c_Red, t_Hint);
      case StdItem.Shape of
          1: begin
            SysMsg(sHint3, c_Red, t_Hint);
            SysMsg(sHint4, c_Red, t_Hint);
            SysMsg(Format(sHint5, ), c_Red, t_Hint);
            end;
          2: begin
            SysMsg(sHint6, c_Red, t_Hint);
            SysMsg(sHint7, c_Red, t_Hint);
            SysMsg(Format(sHint5, ), c_Red, t_Hint);
            end;
          3: begin
            SysMsg(sHint8, c_Red, t_Hint);
            SysMsg(sHint9, c_Red, t_Hint);
            SysMsg(Format(sHint5, ), c_Red, t_Hint);
            end;
          4: begin
            SysMsg(sHint10, c_Red, t_Hint);
            SysMsg(Format(sHint11, ), c_Red, t_Hint);
            SysMsg(sHint12, c_Red, t_Hint);
            end;
      end;
      SendMsg(Self, RM_ITEMHIDE, 0, Integer(MapItem), nX, nY, '');
      Dispose(MapItem);
      Result := True;
      end;

      if g_Config.boStartMapEvent then begin
      StartMapEventOfPickUpItem(StdItem.Name);
      end;
      Exit;
    end;

    //禁止包裹重复
    if CheckSPCode(StdItem.SPCode, SP_DISABLEDUPLICATE) then begin
      if GetUserItemByIdx(MapItem.UserItem.wIndex, UserItem) <> -1 then begin
      if (m_btRaceServer = RC_PLAYOBJECT) then
          SysMsg(Format(g_sCanPickUpItemDuplicate {'你只能同时拥有一个%s'}, ), c_Red, t_Hint);
      Exit;
      end;
    end;

    if m_boPneuma and CheckSPCode(StdItem.SPCode, SP_DISABLEINPNEUMABAG) then Exit;               //禁止元神捡取

    if (nType = 1) and CheckSPCode(StdItem.SPCode, SP_DISABLEINPETBAG) then Exit;                   //禁止宠物捡取
    if (nType = 1) and (m_PetInfo.btType < 6) and (m_PetInfo.wLevel < 2) then Exit;         //1级丛林豹不允许捡物品

    //龙凤绣球-禁止已婚或者女性捡取
    if ((StdItem.StdMode = 50) and (StdItem.Looks = 513)) and
      ((m_sDearName <> '') or (m_btGender = 1)) then Exit;

    //宝盒系统控制-骑马禁止捡取宝盒
    if m_boRideOn and CheckSPCode(StdItem.Reserved, RE_TREASURE) then begin
      Exit;
    end;
    //不是金币或附身,则放到包裹里
    if IsEnoughBag then begin
      if m_PEnvir.DeleteFromMap(nX, nY, OS_ITEMOBJECT, TObject(MapItem)) = 1 then begin
      New(UserItem);
      UserItem^ := MapItem.UserItem;
      if IsAddWeightAvailable(UserEngine.GetStdItemWeight(UserItem.wIndex)) then begin
          SendMsg(Self, RM_ITEMHIDE, 0, Integer(MapItem), nX, nY, '');
          //物品消失
          AddItemToBag(UserItem);

          if StdItem.boGameLog = 1 then
            AddGameDataLog('4' + #9 +
            m_sMapName + #9 +
            IntToStr(nX) + #9 +
            IntToStr(nY) + #9 +
            m_sCharName + #9 +
            StdItem.Name + #9 +
            IntToStr(UserItem.MakeIndex) + #9 +
            '1' + #9 +
            '0');
          Dispose(MapItem);

          if m_btRaceServer = RC_PLAYOBJECT then begin
            SendAddItem(UserItem);

            //捡取触发
            if (g_FunctionNPC <> nil) then begin
            ExecuteScript(g_FunctionNPC, '@拾取物品');
            end;

            if (g_FunctionNPC <> nil) and (not m_boPneuma) then begin
            ExecuteScript(g_FunctionNPC, '@PickUpItem' + IntToStr(StdItem.AniCount));
            end;

            if g_Config.boStartMapEvent then begin
            StartMapEventOfPickUpItem(StdItem.Name);
            end;
          end;
          Result := True;
      end else begin
          Result := False;
          Dispose(UserItem);
          m_PEnvir.AddToMap(nX, nY, OS_ITEMOBJECT, TObject(MapItem));
      end;
      end;
    end;
end;

if not Result then SysMsg(g_sBagIsFullOrWearWeightNot, c_Red, t_Hint);
end;

procedure TPlayObject.ClientQueryBaoshi;
var
i                                     : Integer;
ItemCount                           : array of Integer;
sItemName                           : string;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
begin
ItemCount := m_wGemCount;
ItemCount := m_wGemCount;
ItemCount := m_wGemCount;
m_SMELTNPC := m_ClickNPC;                                                                         //记录当前NPC
SendDefMessage(SM_BAOSHI, Integer(Self), MakeWord(ItemCount, ItemCount), ItemCount, 0, '');
end;

procedure TPlayObject.ClientQueryEvilFollower;
var
i, nCount                           : Integer;
Slave                                 : TBaseObject;
EvilData                              : TEvilData;
begin
nCount := 0;
FillChar(EvilData, SizeOf(TEvilData), #0);
EvilData.dw1 := m_nEvilFollowerPowerMax;
EvilData.dw2 := 3500;
for i := 0 to m_SlaveList.Count - 1 do begin
    if nCount > 4 then Break;
    Slave := TBaseObject(m_SlaveList);
    if Slave.m_boDeath or Slave.m_boGhost or (Slave.m_btRaceServer <> RC_EVIL) then Continue;
    EvilData.Evil.dwEvilID := Integer(Slave);
    EvilData.Evil.btLevel := Slave.m_wSlaveExpLevel;
    case Slave.m_btAmbitLevel of
      0: EvilData.Evil.btAmbit := 0;
      1..3: EvilData.Evil.btAmbit := 1;
      4..6: EvilData.Evil.btAmbit := 2;
      7..9: EvilData.Evil.btAmbit := 3;
      10: EvilData.Evil.btAmbit := 4;
    end;
    EvilData.Evil.btJob := Slave.m_btJob;
    Inc(nCount);
end;
m_defMsg := MakeDefaultMsg(CM_RECALLEVIL, 0, MakeWord(1, nCount),
    m_nEvilFollowerPower, 0);
SendSocket(@m_defMsg, EnCodeBuffer(@EvilData, SizeOf(TEvilData)));
end;

procedure TPlayObject.ClientQueryMapLotusInfo();
var
i                                     : Integer;
pLotusInfo                            : pTLotusInfo;
begin
g_LotusInfoList.Lock;
try
    for i := 0 to g_LotusInfoList.Count - 1 do begin
      pLotusInfo := g_LotusInfoList.Items;
      if (CompareText(pLotusInfo^.sMapName, m_sMapName) = 0) then begin
      SendDefMessage(SM_LOTUSINFO,
          MakeWord(pLotusInfo^.btType, pLotusInfo^.btStatus),
          pLotusInfo^.nX,
          pLotusInfo^.nY,
          0,
          pLotusInfo^.sChrName + '/' + pLotusInfo^.sMapName);
      end;
    end;
finally
    g_LotusInfoList.UnLock;
end;
end;

procedure TPlayObject.ClientQueryRepairCost(nParam1, nInt: Integer; nRepairType:
Integer; sMsg: string);
var
i                                     : Integer;
UserItem                              : pTUserItem;
UserItemA                           : pTUserItem;
Merchant                              : TMerchant;
sName, sTmp                           : string;
StdItem                               : pTStdItem;
sSendMsg                              : string;
begin
UserItemA := nil;
for i := 0 to m_ItemList.Count - 1 do begin
    UserItem := m_ItemList.Items;
    if (UserItem.MakeIndex = nInt) then begin
      {取自定义物品名称}
      sName := '';
      ItemUnit.GetCustomItemName(UserItem, sName);

      if (CompareText(sMsg, sName) = 0) then begin
      UserItemA := UserItem;
      Break;
      end;
    end;
end;
if UserItemA = nil then begin
    SendDefMessage(618, nInt, 1, 0, 0, '');
    Exit;
end;
if nParam1 <= 1 then begin
    StdItem := UserEngine.GetStdItem(UserItemA.wIndex);
    if (StdItem.StdMode in ) and
      (nRepairType = 3) and (UserItemA.btItemExt = 4) then
    begin
      sSendMsg := Format('您的%s已经破碎了,运用%d点五色晶石的力量就可将其修复如新,您愿意修复吗?', );
      m_sNextLabel := Format('Fracture:%d', );
      SendDefMessage(SM_MENU_OKCANCEL, Integer(Self), 0, 0, 1, sSendMsg);
    end;
end;
Merchant := UserEngine.FindMerchant(TObject(nParam1));
if (Merchant <> nil) and
    (IsEnvir(Merchant.m_PEnvir) and
    (abs(Merchant.m_nCurrX - m_nCurrX) < 15) and
    (abs(Merchant.m_nCurrY - m_nCurrY) < 15)) then
    Merchant.ClientQueryRepairCost(Self, UserItemA, nRepairType);
end;

//查看宝宝列表

procedure TPlayObject.ClientQuerySlaverState;
var
i                                     : Integer;
SlaveInfo                           : TViewSlaveInfo;
SlaveInfoList                         : array of TViewSlaveInfo;
Slave                                 : TBaseObject;
s1C                                 : string;
SlaveCount                            : Integer;
sName                                 : string;
begin
SlaveCount := 0;
for i := 0 to m_SlaveList.Count - 1 do begin
    if SlaveCount > 4 then Break;
    Slave := TBaseObject(m_SlaveList);
    if Slave.m_boDeath or Slave.m_boGhost or (Slave = m_Horse) or Slave.m_boIsPet or
      Slave.m_boGodCallBoss or Slave.m_boScapeGoat or (Slave.m_nSlaveType = -2) then Continue;

    FillChar(SlaveInfo, SizeOf(TViewSlaveInfo), 0);
    SlaveInfo.level := Slave.m_wSlaveExpLevel;
    StrPLCopy(SlaveInfo.Name, Slave.m_sFilterCharName, 14);
    if (Slave.m_btRaceServer = RC_EVIL) then begin
      SlaveInfo.HP := m_nEvilFollowerPower div 500;
      SlaveInfo.MaxHP := m_nEvilFollowerPowerMax div 500;
    end else begin
      SlaveInfo.HP := Slave.m_WAbil.dwHP;
      SlaveInfo.MaxHP := Slave.m_WAbil.dwMaxHP;
    end;
    SlaveInfo.DC := MakeLong(loword(Slave.m_WAbil.DC), hiword(Slave.m_WAbil.DC));
    SlaveInfo.AC := hiword(Slave.m_WAbil.AC);
    SlaveInfo.MAC := hiword(Slave.m_WAbil.MAC);
    SlaveInfo.C := '/';
    SlaveInfoList := SlaveInfo;

    Inc(SlaveCount);
end;

if SlaveCount > 0 then begin
    s1C := EnCodeBuffer(@SlaveInfoList, SizeOf(TViewSlaveInfo) * SlaveCount);
    m_defMsg := MakeDefaultMsg(SM_QUERYSLAVER, 0, 0, 0, 0);
    SendSocket(@m_defMsg, s1C);
end;
end;

procedure TPlayObject.ClientQueryTreasureBoxItems(const boSend: Boolean = True);
begin
if Assigned(m_VersionManage) then
try
    m_VersionManage.OnQueryTreasureBoxItems(Self, boSend);
except
    MainOutMessage(Format('TPlayObject::OnQueryTreasureBoxItems SoftVersionDate:%d', ));
end;
end;

//查询用户名

procedure TPlayObject.ClientQueryUserName(Target: TBaseObject; X, Y: Integer);
var
uname                                 : string;
TagColor                              : Integer;
Def                                 : TDefaultMessage;
i                                     : Integer;
begin
if CretInNearXY(Target, X, Y) then begin
    TagColor := GetCharColor(Target);
    Def := MakeDefaultMsg(SM_USERNAME, Integer(Target), TagColor, 0, 0);
    uname := Target.GetShowName;
    SendSocket(@Def, EnCodeString(uname));
end else begin
    Def := MakeDefaultMsg(SM_GHOST, Integer(Target), X, Y, 0);
    i := 0;
    SendSocket(@Def, EnCodeBuffer(@i, SizeOf(Integer)));
end;
end;
//召唤封元守卫

procedure TPlayObject.ClientReCallGuarder(nMakeIndex, nX, nY: Integer);
var
i                                     : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
boEatOK                               : Boolean;
begin
boEatOK := False;
if GetUserItemByMakeIndex(nMakeIndex, UserItem) >= 0 then begin
    StdItem := UserEngine.GetStdItem(UserItem.wIndex);
    if (StdItem <> nil) then begin
      if (StdItem.StdMode = 49) and (StdItem.Shape = 55) then begin
      //封元神力不足
      if (m_btFengYuanPoint < 2) then begin
          SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
          SendDefMessage(3046, 0, 0, 0, 11, '');
          SysMsg('封印神力不足,无法召唤此怪物,请在下轮防守时再召唤', c_Red, t_Hint);
          Exit;
      end;

      if (StdItem.Looks = 5050) then begin
          if ((nX = 19) and (nY = 28)) or ((nX = 23) and (nY = 32)) or
            ((nX = 27) and (nY = 36)) or ((nX = 31) and (nY = 40)) or
            ((nX = 27) and (nY = 44)) or ((nX = 23) and (nY = 48)) then
            boEatOK := True
          else
            SendDefMessage(3046, 0, 0, 0, 10, '');
      end else
          boEatOK := True;

      if boEatOK then begin
          m_sScriptParam := IntToStr(nMakeIndex);
          m_sScriptParam := IntToStr(nX);
          m_sScriptParam := IntToStr(nY);
          boEatOK := ExecuteScript(g_ManageNPC, '@释放封元印');
      end;

      if boEatOK then
          SendDefMessage(3046, 0, nX, nY, 6, '')
      else
          SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
      end;
    end;
end;
end;

procedure TPlayObject.ClientReCallTiger();
var
i                                     : Integer;
begin
if m_boGhost or m_boDeath then Exit;
if (m_Tiger <> nil) then begin
    //删除宠物
    for i := m_SlaveList.Count - 1 downto 0 do begin
      if m_SlaveList = m_Tiger then begin
      m_SlaveList.Delete(i);
      Break;
      end;
    end;
    if (m_Tiger <> nil) and (not m_Tiger.m_boDeath) and (not m_Tiger.m_boGhost) then
      m_Tiger.KickException;
    m_Tiger := nil;
end;
SendDefMessage(CM_CALLTIGER, 0, 2, 0, 0, '');
end;

//合成魂骨

procedure TPlayObject.ClientEntopticSmelt(nState: Integer; sData: string);
var
buf                                 : array of Integer;
i, j                                  : Integer;
nCode                                 : Integer;
ANpc                                  : TNormNpc;
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
pUserItems                            : array of pTUserItem;
pStdItems                           : array of pTStdItem;
sMsg, sLable                        : string;
sLableOK                              : string;
begin
for i := 0 to 5 do begin
    m_sScriptParam := '';
    pUserItems := nil;
    pStdItems := nil;
    buf := 0;
end;
sLable := '';
sLableOK := '';

if m_ClickNPC = nil then Exit;
ANpc := TNormNpc(m_ClickNPC);
DeCodeBuffer(sData, @buf, SizeOf(Integer) * 6);
nCode := 0;
for i := 0 to 5 do begin
    for j := 0 to m_ItemList.Count - 1 do begin
      UserItem := m_ItemList;
      if UserItem.MakeIndex = buf then begin
      pUserItems := UserItem;
      pStdItems := UserEngine.GetStdItem(UserItem.wIndex);
      Break;
      end;
    end;
    if ((pUserItems = nil) or (pStdItems = nil)) then begin
      nCode := -1;
      sMsg := '你所要魂骨没有在你的包裹里发现';
      Break;
    end;
end;
{函数标签初始}
sLable := '@@BoneCompound';
{函数触发开始}
if (nCode = 0) then begin
    for i := 0 to 5 do begin
      if pUserItems <> nil then begin
      m_sScriptParam := IntToStr(pUserItems.MakeIndex);
{$IF USESDK = DEBUG}
      SysMsg(Format('物品%d:%d', .MakeIndex]), c_Pink, t_Hint);
{$IFEND}
      end;
    end;
    if (IsEnvir(ANpc.m_PEnvir) and (abs(ANpc.m_nCurrX - m_nCurrX) < 15) and (abs(ANpc.m_nCurrY - m_nCurrY) < 15)) or (ANpc.m_boIsHide) then begin
      if (sLable <> '') then ANpc.GotoLable(Self, sLable, False);
    end;
end;
if (nCode <> 0) and (sMsg <> '') then SendDefMessage(SM_MENU_OK, 0, 0, 0, 0, sMsg);
end;

//淬炼原石

procedure TPlayObject.ClientOriginalStoneSmelt(nItemIdx, nType, nState: Integer; sData: string);
var
buf                                 : array of Integer;
i, j, nLen                            : Integer;
nCode                                 : Integer;
ANpc                                  : TNormNpc;
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
pUserItems                            : array of pTUserItem;
pStdItems                           : array of pTStdItem;
sMsg, sLable                        : string;
sLableOK                              : string;
begin
for i := 0 to 6 do begin
    m_sScriptParam := '';
    pUserItems := nil;
    pStdItems := nil;
    buf := 0;
end;
sLable := '';
sLableOK := '';

if m_ClickNPC = nil then Exit;
ANpc := TNormNpc(m_ClickNPC);
nLen := Length(sData);
nLen := GetCodeMsgSize(nLen * 3 / 4);
DeCodeBuffer(sData, @buf, nLen);
buf := nItemIdx;
if m_btPermissionGM > 6 then begin
    SysMsg(Format('当前物品编号为:%d', ), c_Red, t_Hint);
    SysMsg(Format('当前指令编号为:%d', ), c_Red, t_Hint);
    SysMsg(Format('当前状态编号为:%d', ), c_Red, t_Hint);
end;
nCode := 0;
for i := 0 to 6 do begin
    for j := 0 to m_ItemList.Count - 1 do begin
      UserItem := m_ItemList;
      if UserItem.MakeIndex = buf then begin
      pUserItems := UserItem;
      pStdItems := UserEngine.GetStdItem(UserItem.wIndex);
      Break;
      end;
    end;
    if ((pUserItems = nil) or (pStdItems = nil)) and (buf <> 0) then begin
      nCode := -1;
      sMsg := '你所要淬炼的宝石或者原石没有在你的包裹里发现';
      Break;
    end;
end;
{函数标签初始}
sLable := '@@gemextract';
if nState = 0 then sLable := sLable + 'OK';

{函数触发开始}
if (nCode = 0) then begin
    for i := 0 to 6 do begin
      if pUserItems <> nil then begin
      m_sScriptParam := IntToStr(pUserItems.MakeIndex);
{$IF USESDK = DEBUG}
      SysMsg(Format('物品%d:%d', .MakeIndex]), c_Pink, t_Hint);
{$IFEND}
      end;
    end;
    if (IsEnvir(ANpc.m_PEnvir) and (abs(ANpc.m_nCurrX - m_nCurrX) < 15) and (abs(ANpc.m_nCurrY - m_nCurrY) < 15)) or (ANpc.m_boIsHide) then begin
      if (sLable <> '') then ANpc.GotoLable(Self, sLable, False);
    end;
end;
if (nCode <> 0) and (sMsg <> '') then SendDefMessage(SM_MENU_OK, 0, 0, 0, 0, sMsg);
end;

//装备融合

procedure TPlayObject.ClientfuseequipItem(nState: Integer; nItemIdx, nItemIdx2: Integer; sData: string);
var
buf                                 : array of Integer;
i, j, nLen                            : Integer;
nCode                                 : Integer;
ANpc                                  : TNormNpc;
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
pUserItems                            : array of pTUserItem;
pStdItems                           : array of pTStdItem;
sMsg, sLable                        : string;
sLableOK                              : string;
begin
for i := 0 to 3 do begin
    m_sScriptParam := '';
    pUserItems := nil;
    pStdItems := nil;
    buf := 0;
end;
sLable := '';
sLableOK := '';

if m_ClickNPC = nil then Exit;
ANpc := TNormNpc(m_ClickNPC);
DeCodeBuffer(sData, @buf, SizeOf(Integer));
buf := nItemIdx;
buf := nItemIdx2;
if m_btPermissionGM > 6 then begin
    SysMsg(Format('当前物品编号为:%d - %d - %d', ]), c_Red, t_Hint);
    SysMsg(Format('当前指令状态为:%d', ), c_Red, t_Hint);
end;

nCode := 0;
for i := 0 to 3 do begin
    for j := 0 to m_ItemList.Count - 1 do begin
      UserItem := m_ItemList;
      if UserItem.MakeIndex = buf then begin
      pUserItems := UserItem;
      pStdItems := UserEngine.GetStdItem(UserItem.wIndex);
      Break;
      end;
    end;
    if ((pUserItems = nil) or (pStdItems = nil)) and (buf <> 0) then begin
      nCode := -1;
      sMsg := '你所要融合的装备没有在你的包裹里发现';
      Break;
    end;
end;
{函数标签初始}
case nState of
    0: sLable := '@@fuseequip';
    1: sLable := '@@equipfuse';
    2: sLable := '@@xunzhangrh';
end;

{函数触发开始}
if (nCode = 0) then begin
    for i := 0 to 3 do begin
      if pUserItems <> nil then begin
      m_sScriptParam := IntToStr(pUserItems.MakeIndex);
{$IF USESDK = DEBUG}
      SysMsg(Format('物品%d:%d', .MakeIndex]), c_Pink, t_Hint);
{$IFEND}
      end;
    end;
    if (IsEnvir(ANpc.m_PEnvir) and (abs(ANpc.m_nCurrX - m_nCurrX) < 15) and (abs(ANpc.m_nCurrY - m_nCurrY) < 15)) or (ANpc.m_boIsHide) then begin
      if (sLable <> '') then ANpc.GotoLable(Self, sLable, False);
    end;
end;
if (nCode <> 0) and (sMsg <> '') then SendDefMessage(SM_MENU_OK, 0, 0, 0, 0, sMsg);
end;

//装备精炼

procedure TPlayObject.ClientRefineItems(nType: Integer; nItemIdx, nItemIdx2: Integer; sData: string);
var
buf                                 : array of Integer;
i, j, nLen                            : Integer;
nCode                                 : Integer;
ANpc                                  : TNormNpc;
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
pUserItems                            : array of pTUserItem;
pStdItems                           : array of pTStdItem;
sMsg, sLable                        : string;
sLableOK                              : string;
begin
for i := 0 to 6 do begin
    m_sScriptParam := '';
    pUserItems := nil;
    pStdItems := nil;
    buf := 0;
end;
sLable := '';
sLableOK := '';

if m_ClickNPC = nil then Exit;
ANpc := TNormNpc(m_ClickNPC);
nLen := Length(sData);
nLen := GetCodeMsgSize(nLen * 3 / 4);
DeCodeBuffer(sData, @buf, nLen);
buf := nItemIdx;
buf := nItemIdx2;
if m_btPermissionGM > 6 then begin
    SysMsg(Format('当前物品编号为:%d - %d', ), c_Red, t_Hint);
    SysMsg(Format('当前指令编号为:%d', ), c_Red, t_Hint);
end;

nCode := 0;
for i := 0 to 6 do begin
    for j := 0 to m_ItemList.Count - 1 do begin
      UserItem := m_ItemList;
      if UserItem.MakeIndex = buf then begin
      pUserItems := UserItem;
      pStdItems := UserEngine.GetStdItem(UserItem.wIndex);
      Break;
      end;
    end;
    if ((pUserItems = nil) or (pStdItems = nil)) and (buf <> 0) then begin
      nCode := -1;
      sMsg := '你所要精炼的装备或者原石没有在你的包裹里发现';
      Break;
    end;
end;
{函数标签初始}
sLable := Format('@@NUhaiSuitUp%d', );
{函数触发开始}
if (nCode = 0) then begin
    for i := 0 to 6 do begin
      if pUserItems <> nil then begin
      m_sScriptParam := IntToStr(pUserItems.MakeIndex);
{$IF USESDK = DEBUG}
      SysMsg(Format('物品%d:%d', .MakeIndex]), c_Pink, t_Hint);
{$IFEND}
      end;
    end;
    if (IsEnvir(ANpc.m_PEnvir) and (abs(ANpc.m_nCurrX - m_nCurrX) < 15) and (abs(ANpc.m_nCurrY - m_nCurrY) < 15)) or (ANpc.m_boIsHide) then begin
      if (sLable <> '') then ANpc.GotoLable(Self, sLable, False);
    end;
end;
if (nCode <> 0) and (sMsg <> '') then SendDefMessage(SM_MENU_OK, 0, 0, 0, 0, sMsg);
end;

procedure TPlayObject.ClientRepairItem(nParam1, nInt: Integer; nRepairType:
Integer;
sMsg: string);
var
i                                     : Integer;
UserItem                              : pTUserItem;
Merchant                              : TMerchant;
sName                                 : string;
boFind                              : Boolean;
begin
UserItem := nil;
boFind := False;
for i := 0 to m_ItemList.Count - 1 do begin
    UserItem := m_ItemList.Items;
    //取自定义物品名称
    sName := '';
    ItemUnit.GetCustomItemName(UserItem, sName);

    if (UserItem.MakeIndex = nInt) and (CompareText(sMsg, sName) = 0) then begin
      boFind := True;
      Break;
    end;
end;
if not boFind or (UserItem = nil) then Exit;
Merchant := UserEngine.FindMerchant(TObject(nParam1));
if (Merchant <> nil) and
    (IsEnvir(Merchant.m_PEnvir) and
    (abs(Merchant.m_nCurrX - m_nCurrX) < 15) and
    (abs(Merchant.m_nCurrY - m_nCurrY) < 15)) then
    Merchant.ClientRepairItem(Self, UserItem, nRepairType);
end;

procedure TPlayObject.ClientRequest(wIdent: word; nOp, nOpCode: Integer);
var
Hum                                 : TPlayObject;
i, nCount                           : Integer;
begin
Hum := nil;
nCount := 0;
{$IF USESDK = DEBUG}
MainOutMessage(Format('请求消息:%d-%d-%d', ));
{$IFEND}
if nOp > 0 then Hum := TPlayObject(nOp);
if (Hum <> nil) and (Hum is TPlayObject) then begin
    //检测是否是元神
    if (Hum <> nil) and (not Hum.m_boDeath) and (not Hum.m_boGhost) and
      (not Hum.m_boPneuma) and (not m_boDeath) and (not m_boGhost) and (not
      m_boPneuma) then begin
      case wIdent of
      CM_REQUESTMASTER: begin
            case nOpCode of
            1: begin                                                                              //招收徒弟
                  //Hum 徒弟 self 师傅
                  for i := 1 to 3 do if m_sMasterName <> '' then Inc(nCount);
                  if nCount >= g_Config.nPrenticeMaxCount then begin
                  //徒弟太多
                  SysMsg('你已收满徒弟', c_Red, t_Hint);
                  Exit;
                  end;
                  if m_Abil.level < g_Config.nMasterLoLevel then begin
                  //自己等级不够
                  SysMsg('你的等级不够,不能收徒', c_Red, t_Hint);
                  Exit;
                  end;
                  if Hum.m_Abil.level >= g_Config.nPrenticeHiLevel then begin
                  //对方等级太高
                  SendDefMessage(CM_REQUESTMASTER, Integer(Self), 258, 12, 0, '对方等级太高');
                  Exit;
                  end;
                  if Hum.m_sMasterName <> '' then begin
                  //对方有师傅
                  SysMsg('对方已经有师傅', c_Red, t_Hint);
                  Exit;
                  end;
                  Hum.SendDefMessage(CM_REQUESTMASTER, Integer(Self), 4, 0, 0, '');
                end;
            2: begin                                                                              //请求拜师
                  //Hum 师傅 self 徒弟
                  for i := 1 to 3 do if Hum.m_sMasterName <> '' then
                      Inc(nCount);
                  if nCount >= g_Config.nPrenticeMaxCount then begin
                  SysMsg('对方已收满徒弟', c_Red, t_Hint);
                  Exit;
                  end;
                  if Hum.m_Abil.level < g_Config.nMasterLoLevel then begin
                  //对方等级不够
                  SysMsg('对方等级不够', c_Red, t_Hint);
                  Exit;
                  end;
                  if m_Abil.level >= g_Config.nPrenticeHiLevel then begin
                  //自己等级太高
                  SendDefMessage(CM_REQUESTMASTER, Integer(Self), 258, 12, 0, '你的等级太高');
                  Exit;
                  end;
                  if m_sMasterName <> '' then begin
                  //自己已经有师傅
                  SysMsg('你已经有师傅', c_Red, t_Hint);
                  Exit;
                  end;
                  Hum.SendDefMessage(CM_REQUESTMASTER, Integer(Self), 3, 0, 0, '');
                end;
            3: begin                                                                              //同意拜师
                  //Hum 徒弟 Self 师傅
                  for i := 1 to 3 do if m_sMasterName <> '' then Inc(nCount);
                  if (nCount < g_Config.nPrenticeMaxCount) and (m_Abil.level >=
                  g_Config.nMasterLoLevel) and
                  (Hum.m_Abil.level < g_Config.nPrenticeHiLevel) then begin
                  ChangeMasterName(m_sCharName, Hum.m_sCharName, True);
                  ChangeMasterName(Hum.m_sCharName, m_sCharName, False);
                  SendMeOnlineState(1);
                  CheckMaster();
                  Hum.CheckMaster();
                  end;
                end;
            4: begin                                                                              //同意收徒
                  //Hum 师傅Self 徒弟
                  for i := 1 to 3 do if (Hum.m_sMasterName <> '') then Inc(nCount);
                  if (nCount < g_Config.nPrenticeMaxCount) and (Hum.m_Abil.level >= g_Config.nMasterLoLevel) and
                  (m_Abil.level < g_Config.nPrenticeHiLevel) then begin
                  ChangeMasterName(m_sCharName, Hum.m_sCharName, False);
                  ChangeMasterName(Hum.m_sCharName, m_sCharName, True);
                  SendMeOnlineState(1);
                  CheckMaster();
                  Hum.CheckMaster();
                  end;
                end;
            259: Hum.SendDefMessage(CM_REQUESTMASTER, Integer(Self), 258, 16, 0, '对方拒绝收你为徒');
            260: Hum.SendDefMessage(CM_REQUESTMASTER, Integer(Self), 258, 18, 0, '对方拒绝拜你为师傅');
            end;
          end;
      CM_REQUESTDEAL: begin                                                                     //请求交易
            case nOpCode of
            0: begin
                  CmdChangeAttackMode(HAM_PEACE);
                  Hum.SendDefMessage(CM_REQUESTDEAL, Integer(Self), 1, 20, 0, m_sCharName + '申请和你交易');
                end;
            1: begin
                  CmdChangeAttackMode(HAM_PEACE);
                  Hum.ClientDealTry(m_sCharName);
                end;
            else
            Hum.SendDefMessage(CM_REQUESTDEAL, Integer(Self), 256, 16, 0, '对方拒绝与你交易');
            end;
          end;
      end;
    end;
end;
end;

//同意或拒绝加为好友

procedure TPlayObject.ClientRespAddFriend(nRespCode: word; FriendName: string);
var
human                                 : TPlayObject;
begin
if nRespCode = 1 then begin                                                                     //同意
    human := UserEngine.GetPlayObject(FriendName);
    if (human <> nil) and (not human.m_boDeath) and (not human.m_boGhost) then begin
      {加到好有名单中}
      AddToFriendList(FriendName);
      {保存对方的好有名单}
      human.AddToFriendList(m_sCharName);
      SendMeOnlineState(1);
    end else begin                                                                                  //对方不在线
      SysMsg(FriendName + '当前不在线,请在他上线后再添加为好友.', c_Red, t_Hint);
    end;
end else begin                                                                                    //拒绝
    human := UserEngine.GetPlayObject(FriendName);
    if (human <> nil) and (not human.m_boDeath) and (not human.m_boGhost) then begin
      human.SysMsg(m_sCharName + '拒绝了你的好友添加申请。', c_Red, t_Hint);
    end;
end;
end;

function TPlayObject.ClientRide(): Boolean;
var
i, nX, nY                           : Integer;
nCheckCount                           : Integer;
RidePet                               : TRidePet;
btReLive, btType, btSoul            : byte;
btRideFightSpeed                      : byte;
boPetUnWater                        : Boolean;
Hum                                 : TPlayObject;
begin
Result := False;
//判断是否使用了百变披风
if (m_wBianshenImg <> 0) then begin
    if m_boRideOn then
      SendMsg(Self, RM_205, 0, 0, 0, 1, '')
    else
      SendMsg(Self, RM_205, 0, 0, 0, 0, '');
    Exit;
end;

if m_boPneuma and (m_PneumaObject <> nil) then
    Hum := (m_PneumaObject as TPlayObject)
else
    Hum := Self;

if m_boRideOn then begin
    if m_boPneuma then begin
      btReLive := Hum.m_PetInfo.btReLive;                                                      //元神骑乘
      btType := Hum.m_PetInfo.btType;
      btRideFightSpeed := Hum.m_PetInfo.btRideFightSpeed;
      boPetUnWater := Hum.m_PetInfo.boUnWater;
      btSoul := Hum.m_PetInfo.btSoul;
      //化形骑战的灵兽是否本体得下来?
      if (Hum.m_PetInfo.nMakeIndex = Hum.m_PetInfo.nMakeIndex) and (m_PneumaObject <> nil) then begin
      TPlayObject(m_PneumaObject).ClientRideOff();
      end;
    end else begin
      btReLive := Hum.m_PetInfo.btReLive;
      btType := Hum.m_PetInfo.btType;
      btRideFightSpeed := Hum.m_PetInfo.btRideFightSpeed;
      boPetUnWater := Hum.m_PetInfo.boUnWater;
      btSoul := Hum.m_PetInfo.btSoul;
    end;
end else begin
    btReLive := Hum.m_PetInfo.btReLive;
    btType := Hum.m_PetInfo.btType;
    boPetUnWater := Hum.m_PetInfo.boUnWater;
    btSoul := Hum.m_PetInfo.btSoul;
end;

if btType < 11 then btType := m_btHorseType;

if (btType in ) and (btReLive < 1) then begin
    SendMsg(Self, RM_205, 0, 0, 0, 0, '');
    SysMsg('你可骑乘的灵兽(饱食状态)或马匹不在身边', c_Red, t_Hint);
    Exit;
end;

if (m_boPneuma and m_boInosculatePneuma) then begin
    SendMsg(Self, RM_205, 0, 0, 0, 0, '');
    SysMsg('融合状态,无法骑乘灵兽。', c_Red, t_Hint);
    Exit;
end;

if m_boCatapultMode then begin
    SendMsg(Self, RM_205, 0, 0, 0, 0, '');
    SysMsg('投石车状态,禁止骑乘', c_Red, t_Hint);
    Exit;
end;

if m_wBianshenAppr <> 0 then begin
    if m_boRideOn then
      SendMsg(Self, RM_205, 0, 0, 0, 1, '')
    else
      SendMsg(Self, RM_205, 0, 0, 0, 0, '');
    SysMsg('你已使用变身披风,禁止骑马', c_Red, t_Hint);
    Exit;
end;

//判断马、宠物的类型
if (not (Hum.m_btHorseType in )) and (not (btType in )) then begin
    SendMsg(Self, RM_205, 0, 0, 0, 0, '');
    m_boRideOn := False;
    m_boRideFightOn := False;
    m_Horse := nil;
    Exit;
end;

//判断是否行会老大
if (m_btHorseType = 3) and (not IsGuildMaster) then begin
    SendMsg(Self, RM_205, 0, 0, 0, 0, '');
    SysMsg('你不是行会长,不能骑黑马', c_Red, t_Hint);
    m_boRideOn := False;
    Exit;
end;

if (m_btHorseType = 2) and (not (IsGuildMaster and (g_CastleManager.IsCastleMember(Self) <> nil))) then begin
    SendMsg(Self, RM_205, 0, 0, 0, 0, '');
    SysMsg('你不是沙城主,不能骑白马', c_Red, t_Hint);
    m_boRideOn := False;
    Exit;
end;

if (btType in ) and (m_btRulerLevel = 0) and (not g_Config.boUnRulerRidePet) then begin
    SendMsg(Self, RM_205, 0, 0, 0, 0, '');
    if (btType in ) then
      SysMsg('你不是主宰者,不能骑帝王裂天犀', c_Red, t_Hint)
    else if btType in then
      SysMsg('你不是主宰者,不能骑黄金战马', c_Red, t_Hint)
    else
      SysMsg('你不是主宰者,不能骑霜雪战熊', c_Red, t_Hint);
    m_boRideOn := False;
    Exit;
end;

if not m_boRideOn and (btType in ) and ((m_nDressShape and $000000C8) = 0) and (m_UseItems.wIndex = 0) then begin
    SendMsg(Self, RM_205, 0, 0, 0, 0, '');
    SysMsg('请先穿上骑宠专用服装才可以骑宠', c_Red, t_Hint);
    Exit;
end;

if not m_boRideOn and (btType in ) and (not m_PEnvir.m_MapFlag.boCanRideShark) then begin
    SendMsg(Self, RM_205, 0, 0, 0, 0, '');
    Exit;
end;

//有宝盒也不让骑马
if not m_boRideOn and m_boArrow then begin
    SysMsg('正在执行抢宝任务,不允许骑宠。', c_Red, t_Hint);
    if m_boRideOn then
      SendMsg(Self, RM_205, 0, 0, 0, 1, '')
    else
      SendMsg(Self, RM_205, 0, 0, 0, 0, '');
    Exit;
end;

try
    nCheckCount := 0;
    //地图不允许骑马和骑宠
    if m_PEnvir.m_MapFlag.boNoRidePet and (not m_PEnvir.m_MapFlag.boRideOn) then begin
      nCheckCount := 1;
      SendMsg(Self, RM_205, 0, 0, 0, 0, '');
      m_boRideOn := False;
      m_boRideFightOn := False;                                                                     //下马状态
      HorseHide;
      SysMsg('本地图不允许骑宠。', c_Red, t_Hint);
      Exit;
    end;

    //判断地图是否允许骑马,宠物除外
    if not m_PEnvir.m_MapFlag.boRideOn and (m_btHorseType in ) and (btReLive < 1) then begin //不允许骑马
      SendMsg(Self, RM_205, 0, 0, 0, 0, '');
      m_boRideOn := False;                                                                        //下马状态
      nCheckCount := 1;
      HorseHide;
      Result := True;
      m_dwLastRide := GetTickCount;
      SysMsg('本地图不允许骑宠。', c_Red, t_Hint);
      Exit;
    end;
    //判断地图是否允许骑宠,马除外
    if m_PEnvir.m_MapFlag.boNoRidePet and (btType in ) and (not (m_btHorseType in )) then begin //本地图禁止骑豹子
      SendMsg(Self, RM_205, 0, 0, 0, 0, '');
      m_boRideOn := False;
      m_boRideFightOn := False;
      SysMsg('本地图不允许骑宠。', c_Red, t_Hint);
      Exit;
    end;

{$IF USESDK = DEBUG}
    SysMsg('骑宠类型:' + IntToStr(btType), c_Red, t_Hint);
{$IFEND}

    m_dwLastRide := GetTickCount;
    if m_boRideOn then begin                                                                        //骑乘中
      if btType in then begin                                                      //灵兽
      nCheckCount := 4;
      if m_boRideFightOn or (btReLive < 2) then begin                                             //骑战中
          nCheckCount := 5;
          ClientRideOff();                                                                        //步行
          nCheckCount := 6;
      end else begin
          if m_PEnvir.m_MapFlag.boWaterNeed and (not (btType in )) and (not m_boUnWater) and (not boPetUnWater) then begin
            SendMsg(Self, RM_205, 0, 0, 0, 0, '');
            SysMsg('你没有开启避水护符(避水神符)或你的灵兽没有点化避水灵性,不能骑战', c_Red, t_Hint);
            ClientRideOff();
            Exit;
          end;
          nCheckCount := 7;
          m_boRideFightOn := True;
          RidePet.nFeature := GetFeatureToLong(Self);
          RidePet.btState := 1 + btRideFightSpeed;                                                //1 骑战 2 骑战速度+1
          RidePet.btSoul := btSoul;                                                               //魂佑灵兽
          SendRefMsg(RM_SITDOWN,
            m_btDirection,
            MakeLong(m_nCurrX, m_nCurrY),
            GetFeatureToLong(Self),
            1,
            EnCodeBuffer(@RidePet, SizeOf(TRidePet)));
          SendMsg(Self, RM_205, 0, 0, 0, 1, '');
          nCheckCount := 8;
          if m_boPneuma then Hum.SendPetInfo($08) else Hum.SendPetInfo($06);
          nCheckCount := 9;
      end;
      end else begin                                                                              //下马
      nCheckCount := 10;
      ClientRideOff();
      nCheckCount := 11;
      end;
      nCheckCount := 12;

      Result := True;
    end else begin
      nCheckCount := 13;
      if (Hum.m_Pet <> nil) and (btType in ) then begin                           //先骑宠物
      if (abs(m_nCurrX - Hum.m_Pet.m_nCurrX) > 2) or (abs(m_nCurrY - Hum.m_Pet.m_nCurrY) > 2) then begin
          SysMsg('你的坐骑不在身边。', c_Red, t_Hint);
          Exit;
      end;
      nCheckCount := 14;
      m_boRideOn := True;
      nCheckCount := 15;
      if m_PEnvir.MoveToMovingObject(m_nCurrX, m_nCurrY, Self, Hum.m_Pet.m_nCurrX, Hum.m_Pet.m_nCurrY, True) > 0 then begin
          m_nCurrX := Hum.m_Pet.m_nCurrX;
          m_nCurrY := Hum.m_Pet.m_nCurrY;
      end;
      nCheckCount := 16;
      if m_boPneuma then
          Hum.m_PetInfo := Hum.m_PetInfo
      else
          Hum.m_PetInfo := Hum.m_PetInfo;

      m_btDirection := Hum.m_Pet.m_btDirection;
      nCheckCount := 19;

      RidePet.nFeature := GetFeatureToLong(Self);
      RidePet.btState := 0;
      RidePet.btSoul := btSoul;
      SendRefMsg(RM_SITDOWN,
          Hum.m_Pet.m_btDirection,
          MakeLong(Hum.m_Pet.m_nCurrX, Hum.m_Pet.m_nCurrY),
          GetFeatureToLong(Self),
          1,
          EnCodeBuffer(@RidePet, SizeOf(TRidePet)));

      SendMsg(Self, RM_205, 0, 0, 0, 1, '');
      nCheckCount := 20;
      if m_boPneuma then Hum.SendPetInfo($07) else Hum.SendPetInfo($02);

      //化形骑战, 元神直接骑战状态
      if (not m_boPneuma) and (m_PneumaObject <> nil) and (btReLive > 2) {and (m_MagicSkills <> nil)} then begin
          Hum.m_PetInfo := Hum.m_PetInfo;
          btRideFightSpeed := Hum.m_PetInfo.btRideFightSpeed;
          TPlayObject(m_PneumaObject).m_boRideOn := True;
          TPlayObject(m_PneumaObject).m_boRideFightOn := True;
          //化形骑战的元神有御兽天衣的外观
          m_PneumaObject.m_nDressShape := MakeLong($00C8, HiWord(m_PneumaObject.m_nDressShape));

          RidePet.nFeature := m_PneumaObject.GetFeatureToLong(Self);
          RidePet.btState := 1 + btRideFightSpeed;                                                //1 骑战 2 骑战速度+1
          RidePet.btSoul := btSoul;
          m_PneumaObject.SendRefMsg(RM_SITDOWN,
            m_PneumaObject.m_btDirection,
            MakeLong(m_PneumaObject.m_nCurrX, m_PneumaObject.m_nCurrY),
            m_PneumaObject.GetFeatureToLong(Self),
            1,
            EnCodeBuffer(@RidePet, SizeOf(TRidePet)));
          m_PneumaObject.SendMsg(m_PneumaObject, RM_205, 0, 0, 0, 1, '');
          m_PneumaObject.SendRefMsg(RM_510, 1, 0, 180, 0, '');

          m_PneumaObject.FeatureChanged;
          m_PneumaObject.RecalcAbilitys();
      end;
      //删除灵兽
      Hum.PetHide(Hum.m_PetInfo.nMakeIndex);
      Result := True;
      nCheckCount := 22;
      end else if (m_Horse <> nil) and (m_btHorseType in ) then begin                        //上马
      nCheckCount := 23;
      //判断马和人的距离
      if (abs(m_nCurrX - m_Horse.m_nCurrX) > 2) or (abs(m_nCurrY - m_Horse.m_nCurrY) > 2) then begin
          SysMsg('你的马不在身边。', c_Red, t_Hint);
          Exit;
      end;
      nCheckCount := 24;
      m_boRideOn := True;
      if m_PEnvir.MoveToMovingObject(m_nCurrX, m_nCurrY, Self, m_Horse.m_nCurrX, m_Horse.m_nCurrY, True) > 0 then begin
          m_nCurrX := m_Horse.m_nCurrX;
          m_nCurrY := m_Horse.m_nCurrY;
      end;
      nCheckCount := 25;
      m_btDirection := m_Horse.m_btDirection;
      nCheckCount := 26;
      RidePet.nFeature := GetFeatureToLong(Self);
      RidePet.btState := 0;
      SendRefMsg(RM_SITDOWN,
          m_Horse.m_btDirection,
          MakeLong(m_Horse.m_nCurrX, m_Horse.m_nCurrY),
          GetFeatureToLong(Self),
          1,
          EnCodeBuffer(@RidePet, SizeOf(RidePet)));
      SendMsg(Self, RM_205, 0, 0, 0, 1, '');
      nCheckCount := 27;
      SendDefMessage(34977, m_Horse.m_wAppr, 612, 2, 0, '');
      //删除马宝宝
      nCheckCount := 28;
      HorseHide;
      Result := True;
      end;
    end;
    FeatureChanged;
    RecalcAbilitys();                                                                               //计算骑战属性
    SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
    SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
except
    on E: Exception do
      MainOutMessage(m_sCharName + '骑马下马出错:#' + IntToStr(nCheckCount) + ' ' + E.Message);
end;

end;

procedure TPlayObject.ClientRideOff;
var
i, nX, nY, nMakeIndex               : Integer;
Hum                                 : TPlayObject;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
btPet                                 : byte;
begin
if m_boRideOn then begin
    if m_boPneuma and (m_PneumaObject <> nil) then begin
      Hum := TPlayObject(m_PneumaObject);
      Hum.GetUserItemByMakeIndex(Hum.m_PetInfo.nMakeIndex, UserItem);                            //元神骑乘
      btPet := Hum.m_PetInfo.btType;
    end else begin
      Hum := Self;
      Hum.GetUserItemByMakeIndex(Hum.m_PetInfo.nMakeIndex, UserItem);
      btPet := Hum.m_PetInfo.btType;
    end;

    if (btPet in ) and (UserItem = nil) then Exit;

    if (not (Hum.m_btHorseType in )) and (not (btPet in )) then begin
      m_boRideOn := False;
      m_boRideFightOn := False;
      HorseName := '';
      Exit;
    end;

    if m_boPneuma then begin
      nMakeIndex := Hum.m_PetInfo.nMakeIndex;
      Hum.m_PetInfo.nMakeIndex := 0;
      Hum.m_PetInfo.wLevel := 0;
      Hum.m_PetInfo.btType := 0;
      Hum.m_PetInfo.btReLive := 0;
      Hum.m_PetInfo.btRideFightSpeed := 0;
    end else begin
      nMakeIndex := Hum.m_PetInfo.nMakeIndex;
      Hum.m_PetInfo.nMakeIndex := 0;
      Hum.m_PetInfo.wLevel := 0;
      Hum.m_PetInfo.btType := 0;
      Hum.m_PetInfo.btReLive := 0;
      Hum.m_PetInfo.btRideFightSpeed := 0;

      //化形骑战的灵兽
      if (Hum.m_PetInfo.nMakeIndex = nMakeIndex) and (m_PneumaObject <> nil) then begin
      Hum.m_PetInfo.nMakeIndex := 0;
      Hum.m_PetInfo.wLevel := 0;
      Hum.m_PetInfo.btType := 0;
      Hum.m_PetInfo.btReLive := 0;
      Hum.m_PetInfo.btRideFightSpeed := 0;

      TPlayObject(m_PneumaObject).m_boRideOn := False;
      TPlayObject(m_PneumaObject).m_boRideFightOn := False;

      //取消御兽天衣的外观
      if m_PneumaObject.m_UseItems.wIndex = 0 then
          m_PneumaObject.m_nDressShape := 0
      else begin
          StdItem := UserEngine.GetStdItem(m_PneumaObject.m_UseItems.wIndex);
          if StdItem = nil then
            m_PneumaObject.m_nDressShape := 0
          else
            m_PneumaObject.m_nDressShape := MakeLong(MakeWord(StdItem.Shape, $00), HiWord(m_PneumaObject.m_nDressShape));
      end;

      m_PneumaObject.SendRefMsg(RM_SITDOWN,
          m_PneumaObject.m_btDirection,
          MakeLong(m_PneumaObject.m_nCurrX, m_PneumaObject.m_nCurrY),
          m_PneumaObject.GetFeature(Self),
          0,
          '');
      m_PneumaObject.SendMsg(m_PneumaObject, RM_205, 0, 0, 0, 0, '');
      m_PneumaObject.FeatureChanged;
      m_PneumaObject.RecalcAbilitys();                                                            //计算骑战属性
      m_PneumaObject.SendMsg(m_PneumaObject, RM_ABILITY, 0, 0, 0, 0, '');
      m_PneumaObject.SendMsg(m_PneumaObject, RM_SUBABILITY, 0, 0, 0, 0, '');

      //融合元神需要强制刷新外观
      if TPlayObject(m_PneumaObject).m_boInosculatePneuma then
          m_PneumaObject.SendRefMsg(RM_TURN,
            m_PneumaObject.m_btDirection,
            m_PneumaObject.m_nCurrX,
            m_PneumaObject.m_nCurrY,
            CalcCent(m_PneumaObject.m_WAbil.dwHP, m_PneumaObject.m_WAbil.dwMaxHP),
            m_PneumaObject.GetShowName);
      end;
    end;
end else begin
    nMakeIndex := m_PetInfo.nMakeIndex;
    btPet := m_PetInfo.btType;
end;

if (btPet in ) and (not m_PEnvir.m_MapFlag.boCanRideShark) then begin                     //鲨鱼在普通地图不能出现
    PetHide(nMakeIndex);
end;

if m_boRideOn and (btPet in ) then begin                                          //踏云豹在任何地图都可以去
    if (Hum.m_Pet = nil) and (Hum.m_PetInfo.nMakeIndex = 0) then begin
      Hum.PetShow(UserItem.MakeIndex);

      if Hum.m_Pet <> nil then begin
      if m_PEnvir.MoveToMovingObject(Hum.m_Pet.m_nCurrX, Hum.m_Pet.m_nCurrY, Hum.m_Pet, m_nCurrX, m_nCurrY, True) > 0 then begin
          Hum.m_Pet.m_nCurrX := m_nCurrX;
          Hum.m_Pet.m_nCurrY := m_nCurrY;
      end;
      Hum.m_Pet.TurnTo(m_btDirection);
      Hum.m_Pet.GetLeftPosition(nX, nY);
      if m_PEnvir.MoveToMovingObject(m_nCurrX, m_nCurrY, Self, nX, nY, True) > 0 then begin
          m_nCurrX := nX;
          m_nCurrY := nY;
      end;
      end;
    end else begin
      m_defMsg := MakeDefaultMsg(34977, 0, 100, 0, 0);
      Hum.SendSocket(@m_defMsg, EnCodeBuffer(@nMakeIndex, 4));
    end;
end else if m_PEnvir.m_MapFlag.boRideOn and (m_btHorseType in ) then begin               //允许骑马地图,则出现马
    if (m_Horse = nil) then begin
      m_Horse := MakeSlave(HorseName, 7, 7, 100, 24 * 60 * 60, -1);
      if m_Horse <> nil then begin
      if not GetRightPosition(nX, nY) then begin
          nX := m_nCurrX;
          nY := m_nCurrY;
      end;
      if m_PEnvir.MoveToMovingObject(m_Horse.m_nCurrX, m_Horse.m_nCurrY, m_Horse, nX, nY, True) > 0 then begin
          m_Horse.m_nCurrX := nX;
          m_Horse.m_nCurrY := nY;
      end;
      m_Horse.TurnTo(m_btDirection);
      SendDefMessage(34977, m_Horse.m_wAppr, 612, 1, 0, '');
      end;
    end;
end else begin                                                                                    //不允许骑马
    //不允许骑马的地图
    if m_Horse <> nil then begin                                                                  //删除马宝宝
      HorseHide;
      SysMsg('您的' + HorseName + '无法进入此地,暂时在外面等候', c_Red, t_Hint);
    end;
end;

if m_boRideOn then begin                                                                        //在骑马,则下马
    m_boRideOn := False;
    m_boRideFightOn := False;
    SendRefMsg(RM_SITDOWN, m_btDirection, MakeLong(m_nCurrX, m_nCurrY), GetFeatureToLong(Self), 0, '');
    SendMsg(Self, RM_205, 0, 0, 0, 0, '');
end;
end;

//CM_RUN命令的处理

function TPlayObject.ClientRunXY(wIdent: word; nX, nY: Integer; nFlag: Integer;
var dwDelayTime: LongWord): Boolean;                                                            //004CB11C
var
nDir                                  : Integer;
dwCheckTime                           : LongWord;
runOK                                 : Boolean;
nPinjunTime                           : Integer;
nCheckTime                            : Integer;
btRideFightSpeed                      : byte;
nStep                                 : byte;
begin
Result := False;
dwDelayTime := 0;
if (not m_boCanRun) or (m_wShopItemCount > 0) or (m_boCatapultAttackMode) then Exit;

if not CheckCanOperate(cRun) then Exit;

if (not g_Config.boDisableM2SpeedCtrl) then begin
    //10指令时间控制
    if m_nRunCount = 0 then m_FirstRunTick := GetTickCount;
    m_nWalkCount := 0;
    Inc(m_nRunCount);
    if m_nRunCount >= 11 then begin
      nPinjunTime := (GetTickCount - m_FirstRunTick) div 10;
{$IF USESDK = DEBUG}
      //SysMsg('跑10次平均时间:'+inttostr(nPinjunTime),c_blue,t_hint);
{$IFEND}
      m_FirstRunTick := GetTickCount;
      m_nRunCount := 0;
      if nPinjunTime < g_Config.n10RunTIme then begin
      if m_boTestSpeedMode then
          SysMsg(Format('10次跑超速!限制:%d,当前:%d', ), c_Red, t_Hint);
      Exit;
      end;
    end;

    if nFlag <> wIdent then begin
      if not CheckActionStatus(wIdent, dwDelayTime) then begin
      m_boFilterAction := False;
      Exit;
      end;
      m_boFilterAction := True;
      dwCheckTime := GetTickCount - m_dwMoveTick;
      //上次移动时间和本次移动时间间隔
      if (dwCheckTime < g_Config.dwRunIntervalTime + m_dwWalkTick) then begin                     //两次行动间隔比要求的小,则可能加速
      if m_dwWalkTick = 0 then
          Inc(m_dwMoveCount);                                                                     //增加移动次数
      dwDelayTime := _Max(0, Integer(g_Config.dwRunIntervalTime) -
          Integer(dwCheckTime));                                                                  //计算超过的时间
      if dwDelayTime > g_Config.dwRunIntervalTime div 3 then begin                              //在默认的67%-100%之间的,允许4次
          if m_dwMoveCount >= 4 then begin
            m_dwMoveTick := GetTickCount();
            m_dwMoveCount := 0;
            dwDelayTime := g_Config.dwRunIntervalTime div 3;
            if m_boTestSpeedMode then
            SysMsg('跑步忙复位!!!' + IntToStr(dwDelayTime), c_Red, t_Hint);
          end else m_dwMoveCount := 0;
          Exit;
      end else begin                                                                              //超速达到33%以上的,直接认为超速
          if m_boTestSpeedMode then
            SysMsg('跑步忙!!!' + IntToStr(dwDelayTime), c_Red, t_Hint);
          Exit;
      end;
      end;
    end;
end;

m_dwMoveTick := GetTickCount();
nCheckTime := GetTickCount - m_dwDoMotaeboMoveTick;
if nCheckTime < g_Config.dwRunIntervalTime div 4 then Exit;
m_dwDoMotaeboMoveTick := GetTickCount();

m_boMoveSuccess := False;
nDir := GetNextDirection(m_nCurrX, m_nCurrY, nX, nY);

if m_boPneuma and (m_PneumaObject <> nil) then begin
    btRideFightSpeed := TPlayObject(m_PneumaObject).m_PetInfo.btRideFightSpeed;
end else begin
    btRideFightSpeed := m_PetInfo.btRideFightSpeed;
end;

nStep := _Max(abs(m_nCurrX - nX), abs(m_nCurrY - nY));

if ((m_boRideOn and not m_boRideFightOn)) or m_boFlyer or
    (m_boRideOn and (btRideFightSpeed = 1) and (m_boRideFightOn)) or
    (m_btGodRunTime > 0) then begin
    if nStep > 2 then begin
      runOK := HorseRunTo(nDir, False);
    end else if nStep > 1 then begin
      runOK := Runto(nDir, False)
    end else
      runOK := WalkTo(nDir, False);
end else if (m_dwTotemStatusTimeOutTick > 0) or (m_wStatusTimeArr <> 0) then begin //重力图腾
    runOK := WalkTo(nDir, False)
end else
    runOK := Runto(nDir, False);

if runOK then begin
    if m_boTransparent and (m_boHideMode) then                                                      //隐身模式跑动效果消失
      m_wStatusTimeArr := 1;                                                   //004CB212

    if m_boMoveSuccess or ((m_nCurrX = nX) and (m_nCurrY = nY)) then Result := True;

    if Result then                                                                                  //行走有伤害
      RunStepToDamage(nStep);

{$IF USESDK = DEBUG}
    if not Result then
      SysMsg(Format('移动失败:目标坐标:(%d,%d),新坐标:(%d,%d)', ), c_Pink, t_Hint);
{$IFEND}
    Dec(m_nHealthTick, 60);
    Dec(m_nSpellTick, 10);
    m_nSpellTick := _Max(0, m_nSpellTick);
    Dec(m_nPerHealth);
    Dec(m_nPerSpell);
end else begin
    m_dwMoveCount := 0;
    m_dwMoveCountA := 0;
end;
m_dwWalkTick := 0;
end;

procedure TPlayObject.ClientSendBlessMsg(NPC: Integer; MsgFlag: Integer; sMsg:
string);
var
ANpc                                  : TNormNpc;
sLabel                              : string;
begin
if not g_Config.boSendCustemMsg then begin
    SysMsg(g_sSendCustMsgCanNotUseNowMsg, c_Red, t_Hint);
    Exit;
end;

ANpc := UserEngine.FindMerchant(TObject(NPC));

if ANpc = nil then ANpc := UserEngine.FindNPC(TObject(NPC));
if ANpc = nil then begin
    UserEngine.SendBroadCastMsgExt(m_sCharName + '祝福:' + sMsg, t_Flymsg);
    Exit;
end;

if (IsEnvir(ANpc.m_PEnvir) and
    (abs(ANpc.m_nCurrX - m_nCurrX) < 15) and
    (abs(ANpc.m_nCurrY - m_nCurrY) < 15)) or (ANpc.m_boIsHide) then begin
    m_sScriptParam := sMsg;
    if MsgFlag = 2 then
      sLabel := '@@blessname'
    else
      sLabel := '@@sendbless';
    if not ANpc.GotoLable(Self, sLabel, False) then
      UserEngine.SendBroadCastMsgExt(m_sCharName + '祝福:' + sMsg, t_Flymsg);
    Exit;
end;
end;

{客户端发送的包裹顺序}

procedure TPlayObject.ClientSetBagOrder(nItemCount: Integer; sData: string);
var
BagItemOrder                        : array of TClientItemOrder;
i, ii                                 : Integer;
begin
if m_boPneuma then Exit;                                                                        //元神不发送
if nItemCount > 125 then
    nItemCount := 125;
DeCodeBuffer(sData, @BagItemOrder, nItemCount * SizeOf(TClientItemOrder));
for i := 0 to nItemCount - 1 do begin
    ii := m_ItemList.IndexOf(BagItemOrder.MakeIndex);
    if ii >= 0 then
      m_ItemList.Pos := BagItemOrder.Order;
end;
end;

//把包裹顺序发送到客户端

procedure TPlayObject.ClientSendBagOrder();
var
BagOrder                              : array of TClientItemOrder;
i                                     : Integer;
sData                                 : string;
UserItem                              : pTUserItem;
bo                                    : Boolean;
begin
if m_boPneuma then Exit;                                                                        //元神不发送

for i := 0 to m_ItemList.Count - 1 do begin
    UserItem := m_ItemList.Items;
    BagOrder.MakeIndex := UserItem.MakeIndex;
    BagOrder.Order := m_ItemList.Pos;
    if i >= 125 then
      Break;
end;
m_defMsg := MakeDefaultMsg($46, 0, 0, 0, m_ItemList.Count);
if m_ItemList.Count <> 0 then
    SendSocket(@m_defMsg, EnCodeBuffer(@BagOrder, m_ItemList.Count * SizeOf(TClientItemOrder)));
end;

procedure TPlayObject.ClientSetTigerTarget(nMonID, nOp, nX, nY: Integer);
var
Monster                               : TBaseObject;
begin
if (m_Tiger <> nil) and (not m_Tiger.m_boDeath) and (not m_Tiger.m_boGhost) then begin

    if (nOp = 0) or (nOp = 257) then begin
      if (nMonID > 0) and (CretInNear10XY(TBaseObject(nMonID), m_nCurrX, m_nCurrY)) then begin
      Monster := TBaseObject(nMonID);
      if (Monster <> nil) and (Monster <> m_Tiger) and (not Monster.m_boDeath) and (not Monster.m_boGhost) then begin
          if IsProperTarget(Monster) then begin
            m_Tiger.m_FirstTargetCret := Monster;
            m_Tiger.SetTargetCreat(Monster);
            SetTargetCreat(Monster);
            if m_TorDDM.Tiger.DB.Dragon > 0 then
            SendDefMessage(CM_TIGERATTACK, nMonID, 2, 0, 0, '')
            else
            SendDefMessage(CM_TIGERATTACK, nMonID, 1, 0, 0, '');
          end;
      end;
      end else
      m_Tiger.DelTargetCreat;
      Exit;
    end;

    case HiByte(nOp) of
      0: begin
          m_Tiger.m_nMissionX := -1;
          m_Tiger.m_nMissionY := -1;
          m_Tiger.m_boMission := False;
          m_Tiger.DelTargetCreat;
          SendDefMessage(CM_TIGERATTACK, 0, 3, 0, 0, '');
      end;
      2: begin
          if m_TorDDM.Tiger.DB.Dragon > 0 then begin
            if (m_nCurrX - nX <= 10) and (m_nCurrY - nY <= 10) then begin
            m_Tiger.m_nMissionX := nX;
            m_Tiger.m_nMissionY := nY;
            m_Tiger.m_boMission := True;
            SendDefMessage(CM_TIGERATTACK, 0, 4, 0, 0, '');
            end;
          end;
      end;
    end;
end;
end;

//CM_SITDOWN

function TPlayObject.ClientSitDownHit(nX, nY, nDir: Integer; var dwDelayTime:
LongWord): Boolean;                                                                               //004CC248
var
dwCheckTime                           : LongWord;
begin
Result := False;
if not CheckCanOperate(cDigUp) then Exit;
if not g_Config.boDisableM2SpeedCtrl then begin
    dwCheckTime := GetTickCount - m_dwTurnTick;

    if dwCheckTime < g_Config.dwTurnIntervalTime then begin
      dwDelayTime := g_Config.dwTurnIntervalTime - dwCheckTime;
      Exit;
    end;
    m_dwTurnTick := GetTickCount;
end;
SendRefMsg(RM_BUTCH, m_btDirection, m_nCurrX, m_nCurrY, 0, '');
//执行脚本:挖宝
if g_Config.boStartMapEvent then begin
    StartMapEventOfButch();
end;
Result := True;
end;

//魔法(CM_SPELL命令的处理)

function TPlayObject.ClientSpellXY(wIdent: word; nKey: Integer; nTargetX,
nTargetY: Integer; TargeTBaseObject: TBaseObject; boLateDelivery: Boolean; var
dwDelayTime: LongWord): Boolean;                                                                  //004CBCEC
var
UserMagic                           : pTUserMagic;
nSpellPoint                           : Integer;
n14                                 : Integer;
BaseObject                            : TBaseObject;
dwCheckTime                           : LongWord;
boIsWarrSkill                         : Boolean;
NextMagic                           : pTUserMagic;
wPercen                               : Word;
function isNoCheckTimeSkill(wMagIdx: Integer): Boolean;
begin
    Result := wMagIdx in ;
end;
begin
Result := False;
dwDelayTime := 0;
if m_boPneuma and m_PEnvir.m_MapFlag.boNoPneuma then Exit;                                        //元神在不允许释放的地图,禁止攻击

if (not m_boCanSpell) or (m_wShopItemCount > 0) or (m_boCatapultAttackMode) then Exit;

if (m_wBianshenAppr > 0) and (m_boAttackMode = False) then Exit;                                  //2016.06.22 支持ChangeAppr变身支持攻击

if (m_boRideOn and not m_boRideFightOn) then Exit;                                                //骑马不允许使用魔法

if not CheckCanOperate(cMagHit, nKey) then Exit;

UserMagic := GetMagicInfo(nKey);                                                                  //根据MagicID获取魔法

if (nKey in ) then begin
    if (not m_boPneuma) and (m_PneumaObject <> nil) then begin
      if m_PneumaObject.m_boPneumaEffMode then begin
      SysMsg('元神灵珠状态不允许使用组合技能。', c_Red, t_Notice);
      Exit;
      end;
      UserMagic := m_PneumaObject.GetMagicInfo(nKey);
    end;
end;

if (nKey in ) and (not m_boPneuma) and (m_PneumaObject <> nil) and (not g_Config.boMergeSkillByOneself) then begin
    if m_PneumaObject.m_boPneumaEffMode then begin
      SysMsg('元神灵珠状态不允许使用组合技能。', c_Red, t_Notice);
      Exit;
    end;
end;

if UserMagic = nil then Exit;

//检查是否为本地图禁止使用的技能
if m_PEnvir.ForbidMagic(UserMagic.MagicInfo.sMagicName) then begin
    SysMsg('本地图禁止使用' + UserMagic.MagicInfo.sMagicName, c_Red, t_Hint);
    Exit;
end;

//检查是否为禁止使用该技能状态
if m_dwStopMagic > GetTickCount() then begin
    SysMsg('当前' + UserMagic.MagicInfo.sMagicName + '被禁止使用状态', c_Red, t_Hint);
    Exit;
end;

boIsWarrSkill := MagicManager.IsWarrSkill(UserMagic.GetMagIdx);
if (not g_Config.boDisableM2SpeedCtrl) then begin
    if (not boLateDelivery) and not boIsWarrSkill and not isNoCheckTimeSkill(UserMagic.GetMagIdx) then begin //战士技能不做处理
//      if not CheckActionStatus(wIdent, dwDelayTime) then begin
//      m_boFilterAction := False;
//      Exit;
//      end;
      m_boFilterAction := True;
      dwCheckTime := GetTickCount - m_dwMagicAttackTick;
      if dwCheckTime < m_dwMagicAttackInterval then begin
      Inc(m_dwMagicAttackCount);
      dwDelayTime := m_dwMagicAttackInterval - dwCheckTime;
      if dwDelayTime > g_Config.dwMagicHitIntervalTime div 3 then begin
          if m_dwMagicAttackCount >= 4 then begin
            m_dwMagicAttackTick := GetTickCount();
            m_dwMagicAttackCount := 0;
            dwDelayTime := g_Config.dwMagicHitIntervalTime div 3;
            if m_boTestSpeedMode then
            SysMsg('魔法忙复位!!!' + IntToStr(dwDelayTime), c_Red, t_Hint);
          end else
            m_dwMagicAttackCount := 0;
          Exit;
      end else begin
          if m_boTestSpeedMode then
            SysMsg('魔法忙!!!' + IntToStr(dwDelayTime), c_Red, t_Hint);
          Exit;
      end;
      end;
    end;
    Dec(m_nSpellTick, 450);
    m_nSpellTick := _Max(0, m_nSpellTick);

    if boIsWarrSkill then begin                                                                     //战士的技能不做处理
      //m_dwMagicAttackInterval:=0;
      //m_dwMagicAttackInterval:=g_Config.dwMagicHitIntervalTime; //01/21 改成此行
    end else begin
      m_dwMagicAttackInterval := UserMagic.MagicInfo.dwDelayTime + g_Config.dwMagicHitIntervalTime;
    end;
    m_dwMagicAttackTick := GetTickCount();
end;

CheckProwlMagic;                                                                                  //检查是否有潜行

case UserMagic.GetMagIdx of                                                                     //
    SKILL_ERGUM {12}: begin                                                                         //刺杀剑法
      if m_MagicSkills <> nil then begin
          if not m_boUseThrusting then begin
            ThrustingOnOff(True);
            SendSocket(nil, '+LNG');
          end else begin
            ThrustingOnOff(False);
            SendSocket(nil, '+ULNG');
          end;
      end;
      Result := True;
      end;
    SKILL_BANWOL {25}: begin                                                                        //半月弯刀
      if m_MagicSkills <> nil then begin
          if not m_boUseHalfMoon then begin
            HalfMoonOnOff(True);
            SendSocket(nil, '+WID');
          end else begin
            HalfMoonOnOff(False);
            SendSocket(nil, '+UWID');
          end;
      end;
      Result := True;
      end;
    SKILL_FIRESWORD {26}: begin                                                                     //烈火剑法
      if m_MagicSkills <> nil then begin
          if AllowFireHitSkill then begin
            nSpellPoint := GetSpellPoint(UserMagic);
            if m_WAbil.dwMP >= nSpellPoint then begin
            if nSpellPoint > 0 then begin
                DamageSpell(nSpellPoint);
                //HealthSpellChanged();
            end;
            SendSocket(nil, '+FIR');
            end;
          end;
      end;
      Result := True;
      end;
    SKILL_MOOTEBO {27}, SKILL_62: begin                                                             //野蛮冲撞 ,突斩
      Result := True;
      if (GetTickCount - m_dwDoMotaeboTick) > 3 * 1000 then begin
          m_dwDoMotaeboTick := GetTickCount();
          m_btDirection := nTargetX;
          nSpellPoint := GetSpellPoint(UserMagic);
          if m_WAbil.dwMP >= nSpellPoint then begin
            if nSpellPoint > 0 then begin
            DamageSpell(nSpellPoint);
            //HealthSpellChanged();
            end;
            if DoMotaebo(m_btDirection, UserMagic.btLevel, UserMagic.GetMagIdx) then
            TrainSkill(UserMagic, Random(3) + 1, 1000);
          end;
      end;
      end;
    SKILL_WINDTEBO, SKILL_75, SKILL_77{, SKILL_176}: begin
      m_btDirection := nTargetX;
      nSpellPoint := GetSpellPoint(UserMagic);
      if m_WAbil.dwMP >= nSpellPoint then begin
          if nSpellPoint > 0 then begin
            DamageSpell(nSpellPoint);
          end;
          if MagDoBatfly(UserMagic, nTargetX, nTargetY) then begin
            Result := True;
            TrainSkill(UserMagic, Random(3) + 1, 1000);
          end;
      end;
      end;
    SKILL_40: begin                                                                                 //双龙斩
      if m_MagicSkills <> nil then begin
          if not m_boCrsHitkill then begin
            SkillCrsOnOff(True);
            SendSocket(nil, '+CRS');
          end else begin
            SkillCrsOnOff(False);
            SendSocket(nil, '+UCRS');
          end;
      end;
      Result := True;
      end;
    SKILL_43: begin                                                                                 //抱月刀
      if m_MagicSkills <> nil then begin
          if not m_bo43Skill then begin
            Skill43OnOff(True);
            SendSocket(nil, '+CIR');
          end else begin
            Skill43OnOff(False);
            SendSocket(nil, '+UCIR');
          end;
      end;
      Result := True;
      end;
    SKILL_44: begin                                                                                 //雷霆剑
      if m_MagicSkills <> nil then begin
          if AllowThunderHitSkill then begin
            nSpellPoint := GetSpellPoint(UserMagic);
            if m_WAbil.dwMP >= nSpellPoint then begin
            if nSpellPoint > 0 then begin
                DamageSpell(nSpellPoint);
                //HealthSpellChanged();
            end;
            SendSocket(nil, '+THU');                                                            //'+FIR');
            end;
          end;
      end;
      Result := True;
      end;
    SKILL_59: begin                                                                                 //破击剑法
      if m_MagicSkills <> nil then begin
          if not m_bo59Skill then begin
            Skill59OnOff(True);
            SendSocket(nil, '+PJ');
          end else begin
            Skill59OnOff(False);
            SendSocket(nil, '+UPJ');
          end;
      end;
      Result := True;
      end;
    SKILL_60: begin                                                                                 //破盾斩
      if m_MagicSkills <> nil then begin
          if not m_bo60Skill then begin
            Skill60OnOff(True);
            SendSocket(nil, '+PD');
          end else begin
            Skill60OnOff(False);
            SendSocket(nil, '+UPD');
          end;
      end;
      Result := True;
      end;
else begin
      BaseObject := nil;
      //检查目标角色,与目标座标误差范围,如果在误差范围内则修正目标座标
      if CretInNearXY(TargeTBaseObject, nTargetX, nTargetY) then begin
      BaseObject := TargeTBaseObject;
      nTargetX := BaseObject.m_nCurrX;
      nTargetY := BaseObject.m_nCurrY;
      end;
      //元神目标修正
      if ((nTargetX = 0) or (nTargetY = 0)) and m_boPneuma then begin
      nTargetX := m_nCurrX;
      nTargetY := m_nCurrY;
      end;
      //铁血神技处理
      {if (UserMagic.GetMagIdx in ) then begin
      NextMagic := nil;
      NextMagic := MagicManager.GetMagicOrder(Self, m_btMagicOrder);
      Inc(m_btMagicOrder);
      if NextMagic <> nil then begin
          UserMagic := NextMagic;
          if m_btMagicOrder = $01 then begin
            wPercen := Round((m_WAbil.wMaxVitaLity * 5) / 10);
            if m_wVitaLity < wPercen then begin
            SysMsg('元气值不足', c_Red, t_Hint);
            Exit;
            end;
            //减少元气
            DamageVitaLity(wPercen);
            SendRefMsg(RM_510, m_nCurrX, m_nCurrY, 321, 0, '');
          end;
      end;
      end;   }

      //魔法攻击(法师、道士的技能)
      Result := DoSpell(UserMagic, nTargetX, nTargetY, BaseObject);
      if not Result then begin
      SendMsg(Self, RM_MAGICFIREFAIL, 0, 0, 0, 0, '');
      end ;{else if (UserMagic.GetMagIdx in ) then begin                        //铁血技能处理
      NextMagic := nil;
      NextMagic := MagicManager.GetMagicOrder(Self, m_btMagicOrder);
      if (NextMagic <> nil) and (m_boComboMagic) then begin
          case m_btJob of
            0: SendDelayMsg(Self, 3017, NextMagic.GetMagIdx, nTargetX, nTargetY, Integer(BaseObject), '', 1000);
            1: SendDelayMsg(Self, 3017, NextMagic.GetMagIdx, nTargetX, nTargetY, Integer(BaseObject), '', 1500);
            2: SendDelayMsg(Self, 3017, NextMagic.GetMagIdx, nTargetX, nTargetY, Integer(BaseObject), '', 1500);
            3: SendDelayMsg(Self, 3017, NextMagic.GetMagIdx, nTargetX, nTargetY, Integer(BaseObject), '', 1500);
          end;
      end else if NextMagic = nil then begin
          m_btMagicOrder := 0;
          case m_btJob of
            0: SendDelayMsg(Self, 1653, m_MagicSkills.MagicInfo.dwCoolDownTime div 1000, SKILL_220, 0, 0, '', 2000);
            1: SendDelayMsg(Self, 1653, m_MagicSkills.MagicInfo.dwCoolDownTime div 1000, SKILL_224, 0, 0, '', 2000);
            2: SendDelayMsg(Self, 1653, m_MagicSkills.MagicInfo.dwCoolDownTime div 1000, SKILL_228, 0, 0, '', 2000);
            3: SendDelayMsg(Self, 1653, m_MagicSkills.MagicInfo.dwCoolDownTime div 1000, SKILL_232, 0, 0, '', 2000);
          end;
          SendRefMsg(RM_510, m_nCurrX, m_nCurrY, 321, 0, '');
      end;
      end;   }

    end;
end;
end;

//拆分物品

procedure TPlayObject.ClientSplitItem(nMakeIndex: Integer; nCount: Integer; boScript: Boolean);
var
SplitItem, UserItem                   : pTUserItem;
StdItem                               : pTStdItem;
begin
if m_boDeath or m_boGhost then Exit;
if (nMakeIndex <= 0) or (nCount <= 0) then Exit;

if GetUserItemByMakeIndex(nMakeIndex, UserItem) >= 0 then begin
    if (UserItem <> nil) then
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
end else
    Exit;

if (UserItem <> nil) and (StdItem <> nil) then begin
    //脚本拆分物品
    if boScript then begin
      if (TNormNpc(m_SMELTNPC) <> nil) and
      IsEnvir(TNormNpc(m_SMELTNPC).m_PEnvir) and
      ((abs(TNormNpc(m_SMELTNPC).m_nCurrX - m_nCurrX) < 15) and
      (abs(TNormNpc(m_SMELTNPC).m_nCurrY - m_nCurrY) < 15)) or
      (TNormNpc(m_SMELTNPC).m_boIsHide) then begin
      m_sScriptParam := IntToStr(nMakeIndex);                                                //IDX
      m_sScriptParam := StdItem.Name;
      m_sScriptParam := IntToStr(nCount);                                                      //数量
      TNormNpc(m_SMELTNPC).GotoLable(Self, m_sNextLabel, False);
      end;
    end else begin
      //只有支持自动叠加的物品才支持拆分
      if IsEnoughBag then begin
      if CheckSPCode(StdItem.Reserved, RE_ALLOWPILE) then begin
          if (UserItem.Dura > nCount) then begin

            New(SplitItem);
            if UserEngine.CopyToUserItemFromName(StdItem.Name, SplitItem) then begin
            SplitItem^.Dura := nCount;
            SplitItem^.DuraMax := StdItem.DuraMax;
            //检测绑定
            if (UserItem.btItemExt = 1) then SplitItem^.btItemExt := 1;
            Dec(UserItem.Dura, nCount);
            SendUpdateItem(UserItem);

            AddItemToBag(SplitItem);
            SendAddItem(SplitItem);

            if StdItem.boGameLog = 1 then
                AddGameDataLog('9' + #9 +
                  m_sMapName + #9 +
                  IntToStr(m_nCurrX) + #9 +
                  IntToStr(m_nCurrY) + #9 +
                  m_sCharName + #9 +
                  StdItem.Name + #9 +
                  IntToStr(UserItem.MakeIndex) + #9 +
                  IntToStr(SplitItem.MakeIndex) + #9 +
                  IntToStr(nCount));
            end else
            Dispose(SplitItem);
          end;
      end;
      end else begin
      SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, '包裹空间不够!!!');
      end;
    end;
end;
end;

//存物品到宠物

procedure TPlayObject.ClientStorageItemToPetBag(nItemIdx: Integer);
var
i                                     : Integer;
UserItem                              : pTUserItem;
bo19                                  : Boolean;
StdItem                               : pTStdItem;
begin
if (m_PetInfo.nMakeIndex = 0) and (m_PetInfo.nMakeIndex = 0) and
    (m_PetInfo.nMakeIndex = 0) and (m_PetInfo.nMakeIndex = 0) and
    (m_PetInfo.nMakeIndex = 0) and (m_PetInfo.nMakeIndex = 0) then begin
    SendDefMessage(SM_9604, Integer(Self), 0, 0, 0, '');
    SysMsg('你没有宠物,无法使用本功能。', c_Red, t_Hint);
    Exit;
end;

//检查宠物包裹是否已经满了
if m_PetItemList.Count >= m_nPetBagSize then begin
    SendDefMessage(SM_9604, Integer(Self), 0, 0, 0, '');
    SysMsg('宠物包裹已经满了,无法放入更多的东西。', c_Red, t_Hint);
    Exit;
end;

bo19 := False;
for i := 0 to m_ItemList.Count - 1 do begin
    UserItem := m_ItemList.Items;
    if (UserItem.MakeIndex = nItemIdx) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem <> nil then begin
      {物品控制,禁止放入宠物包裹}
      if CheckSPCode(StdItem.SPCode, SP_DISABLEINPETBAG) then begin
          SysMsg(StdItem.FilterName + '不允许放入宠物包裹', c_Red, t_Hint);
          bo19 := False;
          Break;
      end;

      //魂佑灵兽禁止放入宠物包裹
      if (StdItem.StdMode = 49) and (StdItem.Shape = 51) and (UserItem.btItemExt >= 2) then begin
          bo19 := False;
          Break;
      end;

      {已放出豹禁止放入宠物包裹}
      if IsDownPetItem(UserItem.MakeIndex) then begin
          bo19 := False;
          Break;
      end;

      m_PetItemList.Add(UserItem);
      m_ItemList.Delete(i);
      WeightChanged();
      SendDefMessage(SM_9604, 0, 0, 0, 1, '');
      SendAddPetItem(UserItem);
      bo19 := True;
      Break;
      end;
    end;
end;
if not bo19 then
    SendDefMessage(SM_9604, Integer(Self), 0, 0, 0, '');
end;

procedure TPlayObject.CheckStoreBagDupeItem;
var
i, ii                                 : Integer;
UserItem, UserItem1                   : pTUserItem;
StdItem                               : pTStdItem;
s14                                 : string;
begin
    //检查背包中是否有复制品
for i := m_ItemList.Count - 1 downto 0 do begin
    UserItem := m_ItemList.Items;
    StdItem := UserEngine.GetStdItem(UserItem.wIndex);
    if StdItem = nil then Continue;
    if StdItem = nil then begin
{$IF USESDK = DEBUG}
      SysMsg('删除非法物品:' + IntToStr(UserItem.MakeIndex), c_Pink, t_Hint);
{$IFEND}
      m_ItemList.Delete(i);
      Dispose(UserItem);
      Continue;
    end;

    s14 := StdItem.Name;
    for ii := i - 1 downto 0 do begin
      UserItem1 := m_ItemList.Items;
      if (UserItem.MakeIndex = UserItem1.MakeIndex) and (UserEngine.GetStdItemName(UserItem1.wIndex) = s14) then begin
{$IF USESDK = DEBUG}
      SysMsg('删除复制品:' + IntToStr(UserItem.MakeIndex), c_Pink, t_Hint);
{$IFEND}
      m_ItemList.Delete(ii);
      Dispose(UserItem1);
      Break;
      end;
    end;
      //检查背包物品和身上装备是否有复制
    for ii := Low(THumItems) to High(THumItems) do begin
      if (m_UseItems.wIndex > 0) and (UserItem.MakeIndex = m_UseItems.MakeIndex) and (UserEngine.GetStdItemName(m_UseItems.wIndex) = s14) then begin
{$IF USESDK = DEBUG}
      SysMsg('删除复制品:' + IntToStr(m_UseItems.MakeIndex), c_Pink, t_Hint);
{$IFEND}
      m_UseItems.wIndex := 0;
      Break;
      end;
    end;
end;
end;

procedure TPlayObject.ClientStorageItem(NPC: TObject; nItemIdx: Integer; boFast:
Boolean; sMsg: string);
var
Merchant                              : TMerchant;
i                                     : Integer;
UserItem                              : pTUserItem;
bo19                                  : Boolean;
StdItem                               : pTStdItem;
sName                                 : string;
StdItem80                           : TStdItem;
begin
bo19 := False;
UserItem := nil;

if (m_wShopItemCount > 0) or m_boArrow or (not m_boCanGetBackItem) then begin
    SysMsg('您现在不可以使用仓库功能!!!', c_Red, t_Hint);
    Exit;
end;

if (m_nPayMent = 1) and not g_Config.boTryModeUseStorage then begin
    SysMsg(g_sTryModeCanotUseStorage {'试玩模式不可以使用仓库功能!!!'}, c_Red, t_Hint);
    Exit;
end;

for i := m_ItemList.Count - 1 downto 0 do begin
    UserItem := m_ItemList.Items;

    StdItem := UserEngine.GetStdItem(UserItem.wIndex);
    if StdItem = nil then Break;
    StdItem80 := StdItem^;
    {取自定义物品名称}
    sName := '';
    ItemUnit.GetCustomItemName(UserItem, sName);

    if (UserItem.MakeIndex = nItemIdx) and CompareLStr(sName, sMsg, Length(sMsg)) then begin
      {物品控制-禁止存仓物品}
      if CheckSPCode(StdItem.SPCode, SP_DISABLESTORAGE) then begin
      SendDefMessage(38288, 1, 255, 0, 0, sName + ' 不允许放入仓库。');
      Break;
      end;

      {魂佑灵兽禁止存仓}
      if (StdItem.StdMode = 49) and (StdItem.Shape = 51) and (UserItem.btItemExt >= 2) then begin
      SendDefMessage(38288, 1, 255, 0, 0, '魂佑灵兽石不允许保存。');
      Break;
      end;

      {已放出豹禁止存仓}
      if IsDownPetItem(UserItem.MakeIndex) then begin
      SendDefMessage(38288, 1, 255, 0, 0, sName + ' 放出宠物时不允许保存。');
      Break;
      end;

      Merchant := UserEngine.FindMerchant(NPC);
      if (Merchant <> nil) and
      (Merchant.m_boStorage) and                                                                  {检查NPC是否允许存物品}
      ((IsEnvir(Merchant.m_PEnvir) and
      (abs(Merchant.m_nCurrX - m_nCurrX) < 15) and
      (abs(Merchant.m_nCurrY - m_nCurrY) < 15)) or (Merchant = g_FunctionNPC)) then begin
      if m_StorageItemList.Count < m_btStorageSize {49} then begin
          m_StorageItemList.Add(UserItem);
          m_ItemList.Delete(i);
          WeightChanged();
          {快捷存取}
          if boFast then begin
            m_defMsg := MakeDefaultMsg(3039, Integer(NPC), 1, 2, 0);

            if Assigned(m_VersionManage) then
            try
            SendSocket(@m_defMsg, m_VersionManage.OnGetClientItemToMsg(Self, UserItem));
            except
            MainOutMessage(Format('TPlayObject::OnGetClientItemToMsg SoftVersionDate:%d', ));
            end;

          end else
            SendDefMessage(SM_STORAGE_OK, 0, 0, 0, 0, '');

          //记录日志
          if StdItem.boGameLog = 1 then
            AddGameDataLog('1' + #9 +
            m_sMapName + #9 +
            IntToStr(m_nCurrX) + #9 +
            IntToStr(m_nCurrY) + #9 +
            m_sCharName + #9 +
            StdItem.Name + #9 +
            IntToStr(UserItem.MakeIndex) + #9 +
            '1' + #9 +
            '0');
      end else begin
          SendDefMessage(SM_STORAGE_FULL, 0, 0, 0, 0, '');                                          {仓库满了}
      end;
      bo19 := True;
      end;
      Break;
    end;
end;
CheckStoreBagDupeItem;                                                                            //检测重复id
if not bo19 then
    SendDefMessage(SM_STORAGE_FAIL, 0, 0, 0, 0, '');
end;

//取回宠物包裹中的物品

procedure TPlayObject.ClientTakebackPetItem(nItemIdx: Integer);
var
i                                     : Integer;
UserItem                              : pTUserItem;
bo19                                  : Boolean;
StdItem                               : pTStdItem;
begin
bo19 := False;
UserItem := nil;
if (m_PetInfo.nMakeIndex = 0) and (m_PetInfo.nMakeIndex = 0) and
    (m_PetInfo.nMakeIndex = 0) and (m_PetInfo.nMakeIndex = 0) and
    (m_PetInfo.nMakeIndex = 0) and (m_PetInfo.nMakeIndex = 0) then begin
    SendDefMessage(SM_9604, Integer(Self), 0, 0, 0, '');
    SendDefMessage(618, nItemIdx, 1, 0, 0, '');
    SysMsg('你没有宠物,无法使用本功能。', c_Red, t_Hint);
    Exit;
end;

for i := m_PetItemList.Count - 1 downto 0 do begin
    UserItem := m_PetItemList.Items;

    if (UserItem.MakeIndex = nItemIdx) then begin
      if (IsAddWeightAvailable(UserEngine.GetStdItemWeight(UserItem.wIndex))) then begin
      if AddItemToBag(UserItem) then begin
          SendDefMessage(SM_9605, Integer(Self), 0, 0, 1, '');
          SendAddItem(UserItem);
          m_PetItemList.Delete(i);
          SendDefMessage(SM_TAKEBACKSTORAGEITEM_OK, nItemIdx, 0, 0, 0, '');
          bo19 := True;
      end else begin
          SendDefMessage(SM_TAKEBACKSTORAGEITEM_FULLBAG, 0, 0, 0, 0, '');
      end;
      end else begin
      SysMsg(g_sCanotGetItems {'无法携带更多的东西!!!'}, c_Red,
          t_Hint);
      end;
      Break;
    end;
end;
if not bo19 then begin
    SendDefMessage(SM_9605, 0, 0, 0, 0, '');
    SendDefMessage(SM_TAKEBACKSTORAGEITEM_FAIL, 0, 0, 0, 0, '');
end;
end;

procedure TPlayObject.ClientTakeBackStorageItem(NPC: TObject; nItemIdx: Integer;
boFast: Boolean; sMsg: string);                                                                   //004DC664
var
Merchant                              : TMerchant;
i                                     : Integer;
UserItem                              : pTUserItem;
bo19                                  : Boolean;
StdItem                               : pTStdItem;
sName                                 : string;
begin
bo19 := False;
UserItem := nil;
Merchant := UserEngine.FindMerchant(NPC);
if Merchant = nil then Exit;

if (m_wShopItemCount > 0) or m_boArrow then begin
    SysMsg('您现在不可以使用仓库功能!!!', c_Red, t_Hint);
    Exit;
end;

if (m_nPayMent = 1) and not g_Config.boTryModeUseStorage then begin
    SysMsg(g_sTryModeCanotUseStorage {'试玩模式不可以使用仓库功能!!!'}, c_Red, t_Hint);
    Exit;
end;
if not m_boCanGetBackItem then begin
    if m_boPasswordLocked then begin
      if not ExecuteScript(g_FunctionNPC, '@仓库锁定') then
      SendMsg(Merchant, RM_MENU_OK, 0, Integer(Self), 0, 0,
          g_sStorageIsLockedMsg + #13#10#13#10
          + '仓库开锁命令: @' + g_GameCommand.UNLOCKSTORAGE.sCmd + #13#10
          + '仓库加锁命令: @' + g_GameCommand.Lock.sCmd + #13#10
          + '设置密码命令: @' + g_GameCommand.SETPASSWORD.sCmd + #13#10
          + '修改密码命令: @' + g_GameCommand.CHGPASSWORD.sCmd);
    end;
    Exit;
end;

for i := m_StorageItemList.Count - 1 downto 0 do begin
    UserItem := m_StorageItemList.Items;

    //取自定义物品名称
    sName := '';
    ItemUnit.GetCustomItemName(UserItem, sName);

    if (UserItem.MakeIndex = nItemIdx) and (CompareText(sMsg, sName) = 0) then begin

      if (IsAddWeightAvailable(UserEngine.GetStdItemWeight(UserItem.wIndex))) then begin
      if (Merchant <> nil) and
          (Merchant.m_boGetback) and                                                                //检查NPC是否允许取物品
          ((IsEnvir(Merchant.m_PEnvir) and
          (abs(Merchant.m_nCurrX - m_nCurrX) < 15) and
          (abs(Merchant.m_nCurrY - m_nCurrY) < 15)) or (Merchant = g_FunctionNPC)) then begin

          if AddItemToBag(UserItem) then begin
            SendAddItem(UserItem);
            m_StorageItemList.Delete(i);
            if boFast then begin
            SendDefMessage(3039, nItemIdx, 1, 3, 0, '');
            end else
            SendDefMessage(SM_TAKEBACKSTORAGEITEM_OK, nItemIdx, 0, 0, 0, '');
            StdItem := UserEngine.GetStdItem(UserItem.wIndex);
            if StdItem.boGameLog = 1 then
            AddGameDataLog('0' + #9 +
                m_sMapName + #9 +
                IntToStr(m_nCurrX) + #9 +
                IntToStr(m_nCurrY) + #9 +
                m_sCharName + #9 +
                StdItem.Name + #9 +
                IntToStr(UserItem.MakeIndex) + #9 +
                '1' + #9 +
                '0');
            m_sScriptParam := StdItem.Name;
            m_sScriptParam := IntToStr(UserItem.MakeIndex);
            ExecuteScript(g_FunctionNPC, '@仓库取物品');
          end else begin
            SendDefMessage(SM_TAKEBACKSTORAGEITEM_FULLBAG, 0, 0, 0, 0, '');
          end;
          bo19 := True;
      end;
      end else begin
      SysMsg(g_sCanotGetItems {'无法携带更多的东西!!!'}, c_Red, t_Hint);
      end;
      Break;
    end;
end;
if not bo19 then SendDefMessage(SM_TAKEBACKSTORAGEITEM_FAIL, 0, 0, 0, 0, '');
end;

procedure TPlayObject.ClientTakeItemOutTreasureBox(nItemID: Integer);
var
i, ii                                 : Integer;
tm                                    : DWORD;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
begin
if m_TreasureBoxItem = nil then Exit;
tm := MakeLong(MakeWord(m_TreasureBoxItem.btValue, m_TreasureBoxItem.btValue), MakeWord(m_TreasureBoxItem.btValue, m_TreasureBoxItem.btValue));
if (tm < DateTimeToWolTimeEx(Now)) and (tm <> 0) then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, sNeedInjectPower);
    Exit;
end;
for i := m_TreasureBoxItemList.Count - 1 downto 0 do begin
    UserItem := m_TreasureBoxItemList.Items;
    if (UserItem <> nil) and (UserItem.MakeIndex = nItemID) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem = nil then Break;
      if IsEnoughBag and IsAddWeightAvailable(UserEngine.GetStdItemWeight(UserItem.wIndex)) then begin
      m_TreasureBoxItemList.Delete(i);
      SendDefMessage(CM_TREASUREBOX, nItemID, 2, 0, 0, '');
      m_ItemList.Add(UserItem);
      SendAddItem(UserItem);
      WeightChanged();
      end else begin
      SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
      SysMsg('包裹空间或者负重不够!!!', c_Red, t_Hint);
      end;
      Break;
    end;
end;
end;

procedure TPlayObject.ClientTakeItemToTreasureBox(nItemID: Integer);
var
i, ii                                 : Integer;
tm                                    : DWORD;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
begin
if m_TreasureBoxItem = nil then Exit;
if (m_TreasureBoxItemList.Count >= m_TreasureBoxItem.DuraMax) then begin
    SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, '你的灵犀宝盒空间已满,不能存放更多物品');
    Exit;
end;

tm := MakeLong(MakeWord(m_TreasureBoxItem.btValue, m_TreasureBoxItem.btValue), MakeWord(m_TreasureBoxItem.btValue, m_TreasureBoxItem.btValue));
if (tm < DateTimeToWolTimeEx(Now)) and (tm <> 0) then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, sNeedInjectPower);
    Exit;
end;
for i := m_ItemList.Count - 1 downto 0 do begin
    UserItem := m_ItemList.Items;
    if (UserItem <> nil) and (UserItem.MakeIndex = nItemID) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem = nil then Break;
      {物品控制-禁止放入灵犀宝盒}
      if CheckSPCode(StdItem.SPCode, SP_DISABLEGINREASUREBOX) then begin
      SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
      SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, Format(sCanNotInTreasureBox, ));
      Break;
      end;

      //魂佑灵兽禁止放入灵犀宝盒
      if (StdItem.StdMode = 49) and (StdItem.Shape = 51) and (UserItem.btItemExt >= 2) then begin
      SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
      Exit;
      end;

      {已放出豹禁止放入灵犀}
      if IsDownPetItem(UserItem.MakeIndex) then begin
      SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
      Exit;
      end;
      m_ItemList.Delete(i);
      m_TreasureBoxItemList.Add(UserItem);
      SendDefMessage(CM_TREASUREBOX, nItemID, 3, 0, 0, '');
      WeightChanged();
      Break;
    end;
end;
end;

//取下装备

procedure TPlayObject.ClientTakeOffItems(btWhere: byte; nItemIdx: Integer; sItemName: string);
var
N10, i                              : Integer;
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
sName                                 : string;
nCheckCode                            : Integer;
label
FailExit;
begin
N10 := 0;
nCheckCode := 0;
if m_PEnvir.m_MapFlag.boNOTAKEON then begin
    SysMsg('当前地图禁止取下物品!!!', c_Red, t_Hint);
    N10 := -4;
    goto FailExit;
end;

if (btWhere = U_RIDEDRESS) or m_boInosculatePneuma then begin
    N10 := -4;
    goto FailExit;
end;

if not m_boDealing and (btWhere < MAX_HUMITEM_COUNT) then begin
    if m_UseItems.wIndex > 0 then begin
      if m_UseItems.MakeIndex = nItemIdx then begin
      StdItem := UserEngine.GetStdItem(m_UseItems.wIndex);
      if (StdItem <> nil) then begin
          if (StdItem.StdMode in ) then begin
            if (not m_boUserUnLockDurg) and (m_UseItems.btValue <> 0) then begin
            SysMsg(g_sCanotTakeOffItem {'无法取下物品!!!'}, c_Red, t_Hint);
            N10 := -4;
            goto FailExit;
            end;
          end;

          //物品控制-禁止取下物品
          if CheckSPCode(StdItem.SPCode, SP_DISABLETAKEOFF) then begin
            SysMsg(g_sCanotTakeOffItem {'无法取下物品!!!'}, c_Red, t_Hint);
            N10 := -4;
            goto FailExit;
          end;

          //取下的是马牌
          try
            if (StdItem.StdMode = 33) then begin
            nCheckCode := 1;
            if m_Horse <> nil then begin                                                          //下马状态
                HorseHide;
                if m_PEnvir.m_MapFlag.boRideOn then
                  SysMsg('你的' + HorseName + '已被收起', c_Red, t_Hint);
            end else begin                                                                        //在马上,或者这个地图不能骑马
                if m_PEnvir.m_MapFlag.boRideOn and (HorseName <> '') then
                  SysMsg('你的' + HorseName + '已被收起', c_Red, t_Hint);
            end;
            m_btHorseType := 0;
            HorseName := '';
            if m_boRideOn and (m_PetInfo.nMakeIndex = 0) then m_boRideOn := False;             //本体骑乘灵兽
            end;
            //虎王盾
            if (StdItem.StdMode = 12) and (StdItem.Shape in ) and (m_Tiger <> nil) then begin
            ClientReCallTiger;
            end;
          except

          end;
          //取自定义物品名称
          sName := '';
          ItemUnit.GetCustomItemName(@m_UseItems, sName);

          if (CompareText(sItemName, sName) = 0) then begin
            New(UserItem);
            UserItem^ := m_UseItems;
            if AddItemToBag(UserItem) then begin
            m_UseItems.wIndex := 0;
            //取下装备触发脚本

            SendAddItem(UserItem);
            SendDefMessage(SM_TAKEOFF_OK, GetFeatureToLong(Self), GetGender, 0, 0, '');
            RecalcAbilitys(True);
            SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
            SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');

            //刷新镶嵌玉石的属性
            if (btWhere in ) and (StdItem.StdItemAdd.btHole > 0) and
                (m_UseItems).IsGem then begin
                RecalcGemSacredDam();
            end;

            m_sScriptParam := StdItem.Name;
            m_sScriptParam := StdItem.FilterName;
            m_sScriptParam := IntToStr(btWhere);
            if not ExecuteScript(g_FunctionNPC, '@TakeOff' + IntToStr(btWhere)) then
                ExecuteScript(g_FunctionNPC, '@TakeOffAll');
            if btWhere = 0 then begin
                m_nMagicStatus := GetMagicStatus;
                Status2Changed;
            end;
            FeatureChanged();
            end else begin
            Dispose(UserItem);
            N10 := -3;
            end;
          end;
      end;
      end;
    end else N10 := -2;
end else N10 := -1;

FailExit:
if N10 <= 0 then
    SendDefMessage(SM_TAKEOFF_FAIL, N10, 0, 0, 0, '');
end;

//装备物品                                             MakeIndex

function TPlayObject.ClientTakeOnItems(btWhere: byte; nItemIdx: Integer; sItemName: string; boFlag: Boolean): Boolean; //004DAC70
var
i, n14, n18, j                        : Integer;
UserItem, TakeoffItem               : pTUserItem;
StdItem, StdItem20                  : pTStdItem;
StdItem58                           : TStdItem;
sName                                 : string;
boCanTakeOn, boSacredBelt             : Boolean;
label
FailExit;
begin
StdItem := nil;
UserItem := nil;
Result := False;
n14 := -1;
if m_PEnvir.m_MapFlag.boNOTAKEON then begin
    SysMsg('当前地图禁止穿戴物品!!!', c_Red, t_Hint);
    n18 := -1;
    goto FailExit;
end;

if (btWhere = U_RIDEDRESS) or m_boInosculatePneuma then begin
    n18 := -1;
    goto FailExit;
end;

if m_boPneuma then begin
    //灵珠状态下不能使用武器
    if (btWhere = U_WEAPON) and m_boPneumaEffMode then begin
      n18 := -1;
      goto FailExit;
    end;
end;

for i := 0 to m_ItemList.Count - 1 do begin
    UserItem := m_ItemList.Items;                                                                //包裹里的物品
    if (UserItem <> nil) and (UserItem.MakeIndex = nItemIdx) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem <> nil then begin
      sName := '';
      ItemUnit.GetCustomItemName(UserItem, sName);
      if (CompareText(sItemName, sName) = 0) then begin
          n14 := i;
          Break;
      end;
      end;
    end;
    UserItem := nil;
end;

n18 := 0;
if (StdItem <> nil) and (UserItem <> nil) then begin
    if CheckUserItems(btWhere, StdItem) then begin
      //物品控制-禁止元神、红名、本体穿戴
      if m_boPneuma then
      boCanTakeOn := not (CheckSPCode(StdItem.SPCode, SP_DISABLEPNEUMATAKEON))
      else if (PKLevel > 2) then
      boCanTakeOn := not (CheckSPCode(StdItem.SPCode, SP_DISABLEREDTAKEON))
      else
      boCanTakeOn := not (CheckSPCode(StdItem.SPCode, SP_DISABLEHUMANTAKEON));

      if boCanTakeOn then begin
      case StdItem.NeedRace of
          1: begin
            if m_btJob < 3 then begin
                boCanTakeOn := False;
            {此物品仅支持妖士佩戴!!!}
            end;
            end;
          3: begin
            if m_btJob <> 0 then begin
                boCanTakeOn := False;
            {此物品仅支持战士佩戴!!!}
            end;
            end;
          4: begin
            if m_btJob <> 1 then begin
                boCanTakeOn := False;
            {此物品仅支持法师佩戴!!!}
            end;
            end;
          5: begin
            if m_btJob <> 2 then begin
                boCanTakeOn := False;
            {此物品仅支持道士佩戴!!!}
            end;
            end;
          6: begin
            if (m_btJob <> 0) and (m_btJob <> 1) then begin
                boCanTakeOn := False;
            {此物品仅支持战士、法师佩戴!!!}
            end;
            end;
          7: begin
            if (m_btJob <> 0) and (m_btJob <> 2) then begin
                boCanTakeOn := False;
            {此物品仅支持战士、道士佩戴!!!}
            end;
            end;
          8: begin
            if (m_btJob <> 0) and (m_btJob <> 3) then begin
                boCanTakeOn := False;
            {此物品仅支持战士、妖士佩戴!!!}
            end;
            end;
          9: begin
            if (m_btJob <> 1) and (m_btJob <> 2) then begin
                boCanTakeOn := False;
            {此物品仅支持法师、道士佩戴!!!}
            end;
            end;
          10: begin
            if (m_btJob <> 1) and (m_btJob <> 3) then begin
                boCanTakeOn := False;
            {此物品仅支持法师、妖士佩戴!!!}
            end;
            end;
          11: begin
            if (m_btJob <> 2) and (m_btJob <> 3) then begin
                boCanTakeOn := False;
            {此物品仅支持道士、妖士佩戴!!!}
            end;
            end;
          12: begin
            if (m_btJob <> 1) and (m_btJob <> 2) and (m_btJob <> 3) then begin
                boCanTakeOn := False;
            {此物品仅支持法师、道士、妖士佩戴!!!}
            end;
            end;
          13: begin
            if (m_btJob <> 0) and (m_btJob <> 2) and (m_btJob <> 3) then begin
                boCanTakeOn := False;
            {此物品仅支持战士、道士、妖士佩戴!!!}
            end;
            end;
          14: begin
            if (m_btJob <> 0) and (m_btJob <> 1) and (m_btJob <> 3) then begin
                boCanTakeOn := False;
            {此物品仅支持战士、法师、妖士佩戴!!!}
            end;
            end;
      end;
      end;
      if not boCanTakeOn then begin
      SysMsg('你不能佩戴此物品!!!', c_Red, t_Hint);
      n18 := -1;
      goto FailExit;
      end;
      //马牌检测
      if (StdItem.StdMode = 33) and (m_btHorseType <> 0) then begin
      n18 := -1;
      end;

      if m_boPneuma then begin
      //破碎装备不能佩戴
      if (UserItem.btItemExt = 4) and (UserItem.Dura <= 0) then begin
          n18 := -1;
          goto FailExit;
      end;
      end;

      StdItem58 := StdItem^;
      ItemUnit.GetItemAddValue(UserItem, StdItem58);
      if (n18 = 0) and CheckTakeOnItems(btWhere, StdItem58) and CheckItemBindUse(UserItem) then begin
      TakeoffItem := nil;
      if btWhere in then begin
          //取下物品
          if m_UseItems.wIndex > 0 then begin                                              //当前位置已装备了物品,则取下
            StdItem20 := UserEngine.GetStdItem(m_UseItems.wIndex);
            if (StdItem20 <> nil) then begin
            if (StdItem20.StdMode in ) then begin               //神秘物品
                if (not m_boUserUnLockDurg) and (m_UseItems.btValue <> 0) then begin
                  SysMsg(g_sCanotTakeOffItem {'无法取下物品!!!'}, c_Red, t_Hint);
                  n18 := -4;
                  goto FailExit;
                end;
            end;
            if not m_boUserUnLockDurg and ((StdItem20.Reserved and 2) <> 0) then begin
                SysMsg(g_sCanotTakeOffItem {'无法取下物品!!!'}, c_Red, t_Hint);
                n18 := -4;
                goto FailExit;
            end;                                                                                  //004DAE78
            if (StdItem20.Reserved and 4) <> 0 then begin
                SysMsg(g_sCanotTakeOffItem {'无法取下物品!!!'}, c_Red, t_Hint);
                n18 := -4;
                goto FailExit;
            end;
            //物品控制-禁止取下物品
            if CheckSPCode(StdItem20.SPCode, SP_DISABLETAKEOFF) then begin
                SysMsg(g_sCanotTakeOffItem {'无法取下物品!!!'}, c_Red, t_Hint);
                n18 := -4;
                goto FailExit;
            end;
            if StdItem20.StdMode = 33 then begin                                                //取下马牌
                HorseHide;
                if m_boRideOn and (m_PetInfo.nMakeIndex = 0) then begin
                  m_boRideOn := False;
                end;
                if m_PEnvir.m_MapFlag.boRideOn then
                  SysMsg('你的' + HorseName + '被收起', c_Red, t_Hint);                           //只有可以骑马的地图才提示
            end;
            HorseName := '';
            //虎王盾
            if (StdItem.StdMode = 12) and (StdItem.Shape in ) and (m_Tiger <> nil) then begin
                ClientReCallTiger;
            end;

            end;
            New(TakeoffItem);
            TakeoffItem^ := m_UseItems;
            //取下装备触发脚本
            if (TakeoffItem <> nil) then begin
            m_sScriptParam := StdItem20.Name;
            m_sScriptParam := StdItem20.FilterName;
            m_sScriptParam := IntToStr(btWhere);
            if not ExecuteScript(g_FunctionNPC, '@TakeOff' + IntToStr(btWhere)) then
                ExecuteScript(g_FunctionNPC, '@TakeOffAll');
            end;
          end;

          if (StdItem58.StdMode in ) then begin
            if StdItem.Shape in then begin
            if (UserItem.btValue <> 0) then
                UserItem.btValue := 0;
            SendUpdateItem(UserItem);
            end;
          end;

          m_UseItems := UserItem^;

          DelBagItem(n14);
          boCanTakeOn := False;
          if TakeoffItem <> nil then begin
            AddItemToBag(TakeoffItem);
            SendAddItem(TakeoffItem);
            if TakeoffItem^.IsGem then
            boCanTakeOn := True;
          end;

          //马牌的处理:装上马牌
          if StdItem.StdMode = 33 then begin
            //取得马的名字
            m_btHorseType := StdItem.Shape;
            if m_btHorseType = 0 then begin
            m_btHorseType := UserItem.btValue;
            HorseName := UserEngine.GetHorseName(UserItem);
            end else begin
            HorseName := StdItem.Name;
            ArrestStringEx(StdItem.Name, '(', ')', HorseName);
            end;
            if m_btHorseType in then Dec(m_btHorseType, 50);
            //地图允许骑马,则生成马
            if not boFlag then begin
            //扣持久
            m_UseItems.Dura := m_UseItems.Dura - 500;

            if m_UseItems.Dura <= 0 then begin
                SendDelItems(@m_UseItems);
                m_UseItems.wIndex := 0;
            end else
                SendMsg(Self, RM_DURACHANGE, btWhere, m_UseItems.Dura, m_UseItems.DuraMax, 0, '');

            if (m_UseItems.wIndex > 0) and (m_btHorseType > 0) and (HorseName <> '') then begin
                if (m_PEnvir.m_MapFlag.boRideOn) then begin
                  m_Horse := MakeSlave(HorseName, 7, 7, 100, 24 * 60 * 60, -1);
                  if m_Horse <> nil then begin
                  m_Horse.TurnTo(m_btDirection);
                  SysMsg('你的' + HorseName + '被放出', c_Red, t_Hint);
                  SendDefMessage(34977, m_Horse.m_wAppr, 612, 1, 0, '');
                  end else
                  SysMsg('释放马失败', c_Red, t_Hint);
                end else begin
                  m_Horse := nil;
                  if m_UseItems.wIndex > 0 then
                  SysMsg('本地图不允许骑宠', c_Red, t_Hint);
                end;
            end;
            end else
            SendMsg(Self, RM_TAKEON2, btWhere, m_UseItems.MakeIndex, 0, 0, '');
            {超级技能项链}
          end else if StdItem.StdMode = 18 then begin
            if CheckUserItemTimeOut(@m_UseItems, StdItem) then begin
            m_UseItems.wIndex := 0;
            SendDelItems(@m_UseItems);
            SysMsg(Format('你的%s已经到期', ), c_Red, t_Hint);
            n18 := -1;
            goto FailExit;
            end;
            {灵鼠神佑、金牛神佑}
          end else if StdItem.StdMode = 29 then begin
            if CheckUserItemTimeOut(@m_UseItems, StdItem) then begin
            m_UseItems.wIndex := 0;
            SendDelItems(@m_UseItems);
            SysMsg(Format('你的%s已经到期', ), c_Red, t_Hint);
            n18 := -1;
            goto FailExit;
            end;
          end else if (StdItem.StdMode = 6) and (StdItem.Shape = 20) then begin
            if CheckUserItemTimeOut(@m_UseItems, StdItem) then begin
            m_UseItems.wIndex := 0;
            SendDelItems(@m_UseItems);
            SysMsg(Format('你的%s已经到期', ), c_Red, t_Hint);
            n18 := -1;
            goto FailExit;
            end;
          end;

          //检查要装备的物品是否已经附魔

          if (m_UseItems.Evil.MakeIndex <> 0) and (m_UseItems.Evil.sName <> '') then begin
            if not m_boPneuma then                                                                  //人物穿戴
            SysMsg('主体佩带附魔装备,不能发挥出附魔属性的威力,请将附魔装备给元神佩带!', c_Red, t_Hint)
          end;
          boSacredBelt := m_boSacredBelt;
          RecalcAbilitys(True);
          SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
          SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');

          //刷新镶嵌玉石的属性
          if (btWhere in ) and
            (((StdItem.StdItemAdd.btHole > 0) and (m_UseItems).IsGem) or boCanTakeOn) then begin
            RecalcGemSacredDam();
          end;

          //神圣腰带
          if m_boSacredBelt and (not boSacredBelt) then
            SendDefMessage(SM_HOLYBELT, Integer(Self), 3, 0, 0, '');

          //穿上装备触发脚本

          m_sScriptParam := StdItem.Name;
          m_sScriptParam := StdItem.FilterName;
          m_sScriptParam := IntToStr(btWhere);
          if not ExecuteScript(g_FunctionNPC, '@TakeOn' + IntToStr(btWhere)) then
            ExecuteScript(g_FunctionNPC, '@TakeOnAll');

          if btWhere = 0 then begin
            if m_UseItems.btValue = 0 then begin
            m_UseItems.btValue := Random(16);
            m_UseItems.btValue := 1;
            end;
            m_nMagicStatus := GetMagicStatus;
            Status2Changed;
          end;
          n18 := 1;
          FeatureChanged();
          SendDefMessage(SM_TAKEON_OK, GetFeatureToLong(Self), GetGender, 0, 0, '');

          if m_UseItems.IsGod() then begin
            if (StdItem58.StdMode = 5) then begin
            if m_UseItems.btItemExt >= 100 then begin
                Dec(m_UseItems.btItemExt, _Max(m_UseItems.btValue, 1));
            end;
            m_UseItems.btValue := 0;
            m_UseItems.btValue := 0;
            SendDelayMsg(Self, RM_SENDGODUSEVAL, 0, m_UseItems.btItemExt, 0, 0, '', 500);
            end else if (StdItem58.StdMode in ) then
            SendDelayMsg(Self, RM_SENDGODUSEVAL, 1, m_UseItems.btValue, 0, 0, '', 500);
          end;
          Result := True;
      end;
      end else n18 := -1;
    end else n18 := -1;
end;
FailExit:
if n18 <= 0 then
    SendDefMessage(SM_TAKEON_FAIL, n18, 0, 0, 0, '');
end;

procedure TPlayObject.ClientTakeOnTigerItem(nWhere, nMakeIndex: Integer);
var
n18, n14, i                           : Integer;
StdItem                               : pTStdItem;
UserItem, TakeoffItem               : pTUserItem;
sName                                 : string;
StdItem18                           : TStdItem;
label
FailExit;
begin
if m_boPneuma then Exit;
if m_btJob = 3 then Exit;                                                                         //妖士是没有虎王盾的

StdItem := nil;
UserItem := nil;
n14 := -1;
n18 := 0;
for i := 0 to m_ItemList.Count - 1 do begin
    UserItem := m_ItemList.Items;                                                                //包裹里的物品
    if (UserItem <> nil) and (UserItem.MakeIndex = nMakeIndex) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem <> nil then begin
      n14 := i;
      Break;
      end;
    end;
    UserItem := nil;
end;

if (m_Tiger <> nil) and (StdItem <> nil) and (UserItem <> nil) then begin
    if CheckTigerUserItems(nWhere, StdItem) then begin
      StdItem18 := StdItem^;

      if (m_TorDDM.Tiger.DB.Dragon <> StdItem18.Shape) then begin
      if StdItem18.Shape = 0 then
          SysMsg('请先招出虎王', c_Red, t_Hint)
      else
          SysMsg('请先招出龙王', c_Red, t_Hint);
      n18 := -1;
      goto FailExit;
      end;

      if (m_TorDDM.Tiger.DB.level < StdItem18.NeedLevel) then begin
      SysMsg('等级不满足条件,无法佩戴。', c_Red, t_Hint);
      n18 := -1;
      goto FailExit;
      end;

      TakeoffItem := nil;
      if nWhere in then begin
      //取下物品
      if m_TorDDM.Tiger.Items.wIndex > 0 then begin
          New(TakeoffItem);
          TakeoffItem^ := m_TorDDM.Tiger.Items;
      end;
      m_TorDDM.Tiger.Items := UserItem^;
      DelBagItem(n14);
      if TakeoffItem <> nil then begin
          AddItemToBag(TakeoffItem);
          SendAddItem(TakeoffItem);
      end;
      n18 := 1;
      SendDefMessage(SM_TAKETIGER_OK, 1, 1, 0, 0, '');
      RecalcTigerAbility;
      end;
    end;
end;

FailExit:
if n18 <= 0 then
    SendDefMessage(SM_TAKEON_FAIL, n18, 0, 0, 0, '');
end;

procedure TPlayObject.ClientTakeOffTigerItem(nWhere, nMakeIndex: Integer);
var
n18                                 : Integer;
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
label
FailExit;
begin
if m_boPneuma then Exit;
if m_btJob = 3 then Exit;                                                                         //妖士是没有虎王盾的
n18 := 0;
if nWhere in then begin
    if m_TorDDM.Tiger.Items.wIndex > 0 then begin
      if m_TorDDM.Tiger.Items.MakeIndex = nMakeIndex then begin
      StdItem := UserEngine.GetStdItem(m_TorDDM.Tiger.Items.wIndex);
      if (StdItem <> nil) then begin
          New(UserItem);
          UserItem^ := m_TorDDM.Tiger.Items;
          if AddItemToBag(UserItem) then begin
            m_TorDDM.Tiger.Items.wIndex := 0;
            SendAddItem(UserItem);
            SendDefMessage(SM_TAKETIGER_OK, 0, 1, 0, 0, '');
            RecalcTigerAbility;
            n18 := 1;
          end else begin
            Dispose(UserItem);
            n18 := -1;
          end;
      end;
      end;
    end;
end;

FailExit:
if n18 <= 0 then
    SendDefMessage(SM_TAKEOFF_FAIL, n18, 0, 0, 0, '');
end;

procedure TPlayObject.ClientUPGradeTreasureBox(nCount: Integer; sBuf: string);
var
i, j, nCode                           : Integer;
sMsg                                  : string;
ANpc                                  : TNormNpc;
buf                                 : array of Integer;
UserItem                              : pTUserItem;
pUserItems                            : array of pTUserItem;
pStdItems                           : array of pTStdItem;
tm                                    : DWORD;
begin
if (m_ClickNPC = nil) or (nCount <= 0) or (nCount > 6) then Exit;
ANpc := TNormNpc(m_ClickNPC);
FillChar(buf, SizeOf(Integer) * 6, 0);
DeCodeBuffer(sBuf, @buf, SizeOf(Integer) * nCount);
nCode := 0;

if (m_TreasureBoxItem = nil) then begin
    nCode := -1;
    sMsg := '你的灵犀宝盒还没有注入灵力,无法强化';
end;

if (nCode = 0) then begin
    tm := MakeLong(MakeWord(m_TreasureBoxItem.btValue, m_TreasureBoxItem.btValue), MakeWord(m_TreasureBoxItem.btValue, m_TreasureBoxItem.btValue));
    if (tm < DateTimeToWolTimeEx(Now)) and (tm <> 0) then begin
      sMsg := '你的灵犀宝盒灵力已经耗尽,无法强化';
      Exit;
    end;
end;

if (nCode = 0) then begin
    tm := MakeLong(MakeWord(m_TreasureBoxItem.btValue, m_TreasureBoxItem.btValue), MakeWord(m_TreasureBoxItem.btValue, m_TreasureBoxItem.btValue));
    if (tm = 0) then begin
      nCode := -1;
      sMsg := '你的灵犀宝盒已经强化,不需要再次强化';
    end;
end;

if (nCode = 0) then begin
    for i := 0 to nCount - 1 do begin
      for j := 0 to m_ItemList.Count - 1 do begin
      UserItem := m_ItemList;
      if UserItem.MakeIndex = buf then begin
          pUserItems := UserItem;
          pStdItems := UserEngine.GetStdItem(UserItem.wIndex);
          Break;
      end;
      end;
      if ((pUserItems = nil) or (pStdItems = nil)) and (buf <> 0) then begin
      nCode := -1;
      sMsg := '没有在你的包裹中发现强化宝盒所需要的元灵晶石或幸运符';
      Break;
      end;
    end;
end;
{函数触发开始}
if (nCode = 0) then begin
    m_sScriptParam := IntToStr(nCount);
    for i := 0 to nCount - 1 do begin
      if pUserItems <> nil then begin
      m_sScriptParam := IntToStr(pUserItems.MakeIndex);
{$IF USESDK = DEBUG}
      SysMsg(Format('物品%d:%d', .MakeIndex]), c_Pink, t_Hint);
{$IFEND}
      end;
    end;
    if (IsEnvir(ANpc.m_PEnvir) and
      (abs(ANpc.m_nCurrX - m_nCurrX) < 15) and
      (abs(ANpc.m_nCurrY - m_nCurrY) < 15)) or (ANpc.m_boIsHide) then begin
      ANpc.GotoLable(Self, '@强化灵犀宝盒', False);
    end;
end;
if (nCode <> 0) and (sMsg <> '') then begin
    SendMsg(ANpc, RM_MERCHANTDLGCLOSE, 0, Integer(ANpc), 0, 0, '');
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, sMsg);
end;
end;

//使用物品

procedure TPlayObject.ClientUseItems(nItemIdx: Integer; sItemName: string; nPackIdx: Integer);
//根据物品名字获得打包后的物品Shape
function GetBindItemShape(sName: string): Integer;
var
    i                                 : Integer;
begin
    Result := -1;
    for i := 0 to g_UnbindList.Count - 1 do begin
      if g_UnbindList.Strings = sName then begin
      Result := Integer(g_UnbindList.Objects);
      Break;
      end;
    end;
end;
//叠加物品
function PileItems(UserItem: pTUserItem; nMakeIndex: Integer; pStd: pTStdItem): Boolean;
var
    i                                 : Integer;
    PileItem                            : pTUserItem;
    nCount                              : Integer;
begin
    Result := False;
    //获得要叠加的物品
    nCount := 0;
    for i := 0 to m_ItemList.Count - 1 do begin
      if (pTUserItem(m_ItemList).MakeIndex = nMakeIndex) and
      (pTUserItem(m_ItemList).wIndex = UserItem.wIndex) and (pTUserItem(m_ItemList).Dura > 0) then
      begin
      PileItem := pTUserItem(m_ItemList);
      Result := True;
      Break;
      end;
    end;
    if Result then begin
      //叠加上限检测
      if (UserItem.Dura >= pStd.Stock) or (PileItem.Dura >= pStd.Stock) then begin
      SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, g_sCanotPileItemsMsg);
      Result := True;
      Exit;
      end;

      //检测绑定
      if (UserItem.btItemExt = 1) or (PileItem.btItemExt = 1) then begin
      UserItem.btItemExt := 1;
      end;

      //检测持久
      if (UserItem.Dura + PileItem.Dura) > pStd.Stock then begin
      nCount := pStd.Stock - UserItem.Dura;
      Dec(PileItem.Dura, nCount);
      SendUpdateItem(PileItem);
      end else begin
      nCount := PileItem.Dura;
      SendDelItems(PileItem);
      DelBagItem(PileItem.MakeIndex, pStd.Name);
      end;
      Inc(UserItem.Dura, nCount);
      SendUpdateItem(UserItem);
    end;
end;
//乾坤袋打包物品

function PackageItems(nMakeIndex: Integer): Boolean;
var
    i                                 : Integer;
    UserItem                            : pTUserItem;
    BindItem                            : pTStdItem;
    pStdItem                            : pTStdItem;
    nItemIdx                            : Integer;
    nCount                              : Integer;
    nShape                              : Integer;
begin
    Result := False;
    //获得要打包的物品名字
    nItemIdx := -1;
    for i := 0 to m_ItemList.Count - 1 do begin
      UserItem := pTUserItem(m_ItemList);
      if (UserItem.wIndex > 0) and (UserItem.MakeIndex = nMakeIndex) then begin
      pStdItem := UserEngine.GetStdItem(UserItem.wIndex);
      nItemIdx := UserItem.wIndex;
      if pStdItem <> nil then Result := True;
      Break;
      end;
    end;
    if Result then begin                                                                            //如果获得名字,则获得打包后的物品
      nShape := GetBindItemShape(pStdItem.Name);
      BindItem := UserEngine.GetBindItem(nShape);
      if (BindItem = nil) then Result := False;
    end;
    if Result then begin
      //检查要打包的物品数量够不够
      nCount := 0;
      for i := m_ItemList.Count - 1 downto 0 do begin
      UserItem := pTUserItem(m_ItemList);
      if (UserItem.wIndex > 0) and (UserItem.Dura = UserItem.DuraMax) and (UserItem.wIndex = nItemIdx) then Inc(nCount);
      end;
      if nCount < 6 then begin
      SysMsg(pStdItem.FilterName + '数量不足6个,不可被乾坤药袋收纳。', c_Red, t_Hint);
      Result := False;
      end else begin
      //删除6个要打包的物品
      nCount := 0;
      for i := m_ItemList.Count - 1 downto 0 do begin
          UserItem := pTUserItem(m_ItemList);
          if (UserItem.wIndex > 0) and (UserItem.wIndex = nItemIdx) then begin
            SendDelItems(UserItem);
            Dispose(UserItem);
            m_ItemList.Delete(i);
            Inc(nCount);
            if nCount >= 6 then Break;
          end;
      end;
      //给一个打包后的物品
      New(UserItem);
      if UserEngine.CopyToUserItemFromName(BindItem.Name, UserItem) then begin
          m_ItemList.Add(UserItem);
          SendAddItem(UserItem);
      end else begin
          Dispose(UserItem);
          Result := False;
      end;
      WeightChanged;                                                                              //重量改变
      end;
    end else begin
      SysMsg('此物品不可被乾坤药袋收纳', c_Red, t_Hint);
    end;
end;

function CheckUserItemTimeOut(UserItem: pTUserItem; StdItem: pTStdItem): Boolean;
var
    tm, nowtm                           : DWORD;
begin
    Result := False;
    tm := MakeLong(MakeWord(UserItem.btValue, UserItem.btValue),
      MakeWord(UserItem.btValue, UserItem.btValue));
    if (tm = 0) and (StdItem.Shape <> 53) then begin                                                //第一次使用
      tm := DateTimeToWolTIme(Now);
      UserItem.btValue := LoByte(LoWord(tm));
      UserItem.btValue := HiByte(LoWord(tm));
      UserItem.btValue := LoByte(HiWord(tm));
      UserItem.btValue := HiByte(HiWord(tm));
      UserItem.btItemExt := 1;                                                                   //绑定
      SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
      SendUpdateItem(UserItem);
      case StdItem.Shape of
      1, 2, 3, 4, 22, 51, 52, 53: ;
      61..80: begin
            SysMsg('您开启了小时卡,使用期限:开启后' + IntToStr(UserItem.Dura) + '小时。', c_Red, t_Hint);
          end else begin
          SysMsg('您开启了天数卡,使用期限:开启后' + IntToStr(UserItem.Dura) + '天。', c_Red, t_Hint);
      end;
      end;
    end else begin
      nowtm := DateTimeToWolTIme(Now);
      if (tm + UserItem.Dura * 86400 < nowtm) or
      ((StdItem.Shape in ) and (tm + UserItem.Dura * 3600 < nowtm)) then begin
      Result := True;
      SysMsg('该物品已经到期', c_Red, t_Hint);
      end;
    end;
end;
var
j, n14, i                           : Integer;
boEatOK, boFind                     : Boolean;
UserItem, UserItem2                   : pTUserItem;
ObjList                               : TList;
StdItem                               : pTStdItem;
StdItem2                              : pTStdItem;
StdItem3                              : pTStdItem;
StdItem24                           : TStdItem;
UserItem34                            : TUserItem;
Monster, BaseObject                   : TBaseObject;
nX, nY, nCode, nCheckCode             : Integer;
sMAP, sTmp                            : string;
tm                                    : DWORD;
TargeList                           : array of Integer;
UserMagic                           : pTUserMagic;
Magic                                 : pTMagic;
label
EAT_END;

resourcestring
sExceptionMsg                         = 'CM_EAT:: %d 人物:%s,参数:%d,%s,%d';
begin
nCheckCode := 0;
boEatOK := False;
n14 := 0;
m_nEatItemMakeIndex := 0;
m_sScriptParam := '';
m_sScriptParam := '';
m_sScriptParam := '';
m_sScriptParam := '';
m_sScriptParam := '';
m_sScriptParam := '';
Monster := nil;
try
    StdItem := nil;
    if m_boCanUseItem then begin
      if not m_boDeath then begin
      nCheckCode := 1;
      GetUserItemByMakeIndex(nItemIdx, UserItem);
      if (UserItem <> nil) and (UserItem.MakeIndex = nItemIdx) then begin
          UserItem34 := UserItem^;
          nCheckCode := 2;
          StdItem := UserEngine.GetStdItem(UserItem34.wIndex);
          if StdItem <> nil then begin                                                            //物品存在
            m_sScriptParam := IntToStr(nItemIdx);
            m_sScriptParam := IntToStr(nPackIdx);
            m_sScriptParam := StdItem.Name;
            GetStdItemByMakeIndex(nPackIdx, StdItem3);
            if StdItem3 <> nil then m_sScriptParam := StdItem3.Name;
            m_nEatItemMakeIndex := UserItem34.MakeIndex;
            sItemName := StdItem.Name;
            nCheckCode := 3;

            //自动叠加的物品
            if CheckSPCode(StdItem.Reserved, RE_ALLOWPILE) and (nPackIdx > 0) then begin
            if PileItems(UserItem, nPackIdx, StdItem) then begin
                m_nEatItemMakeIndex := 0;
                boEatOK := False;
                SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                goto EAT_END;
            end;
            end;

{$IF USESDK = DEBUG}
            SysMsg(Format('nItemIdx: %d; sItemName: %s;nPackIdx: %d', ), c_Red, t_Hint);
{$IFEND}
            //检查是否为本地图禁止使用的物品
            if m_PEnvir.ForbidItem(sItemName) then begin
            SysMsg('本地图禁止使用 ' + StdItem.FilterName, c_Red, t_Hint);
            goto EAT_END;
            end;

            nCheckCode := 4;
            //灵符类物品控制
            if (StdItem.StdMode = 3) and (StdItem.Shape in ) then begin
            if m_PEnvir.m_MapFlag.boCanUseSuperItem and m_PEnvir.AllowSoulItem(sItemName) then begin
                nCheckCode := 5;
                if (nPackIdx > 0) then Monster := TBaseObject(nPackIdx);
                nCheckCode := 6;
                if (nPackIdx > 0) and CretInNear10XY(TBaseObject(nPackIdx), m_nCurrX, m_nCurrY) and (Monster <> nil) and (not Monster.m_boDeath) and (not Monster.m_boGhost) and (Monster.m_btRaceServer >= RC_ANIMAL) then
{$IF USESDK = DEBUG}
                  //SysMsg('灵符攻击目标有效', c_Red, t_Hint)
                  OutputDebugString('灵符攻击目标有效')
{$IFEND}
                else
                  goto EAT_END;
            end else begin
{$IF USESDK = DEBUG}
                SysMsg('本地图不允许使用此道具。', c_Red, t_Hint);
{$IFEND}
                goto EAT_END;
            end;
            end;
            nCheckCode := 190;
            case StdItem.StdMode of
            0..2: begin                                                                           //药,肉(食物)
                  if EatItems(StdItem) then begin
                  if (StdItem.StdMode = 0) and (StdItem.Shape in ) then begin
                      if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                        if UserItem.Dura > 0 then Dec(UserItem.Dura);
                        if (UserItem.Dura <= 0) then begin
                        m_nEatItemMakeIndex := 0;
                        DelBagItem(UserItem34.MakeIndex, '');
                        boEatOK := True;
                        end else begin
                        boEatOK := False;
                        //SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                        SendUpdateItem(UserItem);
                        end;
                      end;
                  end else if (StdItem.StdMode = 0) and (StdItem.Shape = 211) then begin          //海神生命神水
                      if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                        //n14 := _MIN(High(byte), LoWord(StdItem.AC)) * _Max(1, HiWord(StdItem.AC));
                        n14 := _MIN(m_WAbil.dwMaxHP - m_WAbil.dwHP, UserItem.Dura);
                        if n14 > 0 then begin
                        IncHealthSpell(n14, 0);
                        Dec(UserItem.Dura, n14);
                        end;
                        if (UserItem.Dura <= 0) then begin
                        m_nEatItemMakeIndex := 0;
                        DelBagItem(UserItem34.MakeIndex, '');
                        boEatOK := True;
                        end else begin
                        boEatOK := False;
                        //SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                        SendUpdateItem(UserItem);
                        end;
                      end;
                  end else if (StdItem.StdMode = 0) and (StdItem.Shape = 212) then begin          //海神魔法神水
                      if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                        n14 := _MIN(m_WAbil.dwMaxMP - m_WAbil.dwMP, UserItem.Dura);
                        if n14 > 0 then begin
                        IncHealthSpell(0, n14);
                        Dec(UserItem.Dura, n14);
                        end;
                        if (UserItem.Dura <= 0) then begin
                        m_nEatItemMakeIndex := 0;
                        DelBagItem(UserItem34.MakeIndex, '');
                        boEatOK := True;
                        end else begin
                        boEatOK := False;
                        //SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                        SendUpdateItem(UserItem);
                        end;
                      end;
                  end else begin
                      if (m_nEatItemMakeIndex = UserItem34.MakeIndex) and (StdItem.Shape <> 5) then begin
                        m_nEatItemMakeIndex := 0;
                        DelBagItem(UserItem34.MakeIndex, '');
                        boEatOK := True;
                      end;
                  end;
                  end;
                  goto EAT_END;
                end;
            3: begin
                  case StdItem.Shape of
                  27, 29: begin                                                                   //镇魔符、镇魔神符
                        if (not m_PEnvir.m_MapFlag.boCanReCallEvil) or
                        (Monster.m_btRaceServer <> RC_EVIL) or (Monster.m_Master <> nil) or (not IsProperTarget(Monster)) then begin
{$IF USESDK = DEBUG}
                        SysMsg(FilterItemShowName(StdItem.Name) + '攻击目标无效!', c_Red, t_Hint);
{$IFEND}
                        goto EAT_END;
                        end;
                        for j := 0 to m_SlaveList.Count - 1 do begin
                        if TBaseObject(m_SlaveList).m_btRaceServer = RC_EVIL then begin
                            Inc(n14);
                            if n14 >= g_Config.nMaxRecallEvilCount then Break;
                        end;
                        end;
                        if n14 >= g_Config.nMaxRecallEvilCount then begin
                        SysMsg('你已无法召唤更多的心魔', c_Red, t_Hint);
                        goto EAT_END;
                        end;
                        TurnTo(GetNextDirection(m_nCurrX, m_nCurrY, Monster.m_nCurrX, Monster.m_nCurrY));
                        //显示一个效果
                        SendRefMsg(RM_ASSISTSKILL, $0D, Integer(Monster), m_btDirection, MakeLong(Monster.m_nCurrX, Monster.m_nCurrY), '');
                        if Random(g_Config.nRecallEvilRate) = 0 then begin
                        //镇魔符召怪
                        ExecuteScript(g_FunctionNPC, '@镇魔符召怪');
                        Monster.m_Master := Self;
                        Monster.m_btRaceImg := 254;
                        Monster.m_dwMasterRoyaltyTick := GetTickCount + 20 * 60 * 60 * 1000;
                        Monster.m_boSuperMan := g_Config.boEvilSlaveSuperMan;
                        Monster.RecalcAbilitys;
                        m_SlaveList.Add(Monster);
                        Monster.SetTargetCreat(m_TargetCret);
                        Monster.m_wStatusTimeArr := 1;
                        Monster.HealthSpellChanged;
                        Monster.RefShowName;
                        Monster.SendRefMsg(RM_510, 1, 0, 72, 0, '');
                        //显示心魔控制面板
                        m_nEvilFollowerPower := _MIN(m_nEvilFollowerPowerMax, m_nEvilFollowerPower + StdItem.AC * 1000);
                        ClientQueryEvilFollower;
                        ClearEvilFollower(4);
                        m_dwClearObjTick := GetTickCount();
                        SendDefMessage(CM_RECALLEVIL, Integer(Self), 3, LoWord(m_nEvilFollowerPower), HiWord(m_nEvilFollowerPower), '');
                        end else begin
                        //镇魔符冻结心魔
                        Monster.MakePosion(POISON_DONTMOVE, Round(StdItem.AC / 10) * g_Config.nAntiEvilDontMoveTime, 0);
                        end;
                        {减少持久}
                        if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                        if UserItem.Dura > 0 then Dec(UserItem.Dura);
                        if (UserItem.Dura <= 0) then begin
                            m_nEatItemMakeIndex := 0;
                            DelBagItem(UserItem34.MakeIndex, '');
                            boEatOK := True;
                        end else begin
                            boEatOK := False;
                            //SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                            SendUpdateItem(UserItem);
                        end;
                        end;
                      end;
                  202, 203: begin                                                               //灵符
                        if (not IsProperTarget(Monster)) or (Monster.m_Master <> nil) or (Monster.m_boHideMode) or (CheckSPCode(Monster.m_dwRuleCtrlCode, SP_MON_DISABLELINGFU)) then begin
{$IF USESDK = DEBUG}
                        SysMsg('灵符攻击目标无效', c_Red, t_Hint);
{$IFEND}
                        boEatOK := False;
                        //SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                        goto EAT_END;
                        end else begin
                        TurnTo(GetNextDirection(m_nCurrX, m_nCurrY, Monster.m_nCurrX, Monster.m_nCurrY));
                        if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                            if StdItem.Shape = 203 then begin                                       //灵符(捆)
                              //快速救公主地图
                              if m_PEnvir.m_MapFlag.boFastUseItem then begin
                              n14 := 0;
                              SetLength(TargeList, 0);
                              ObjList := TList.Create;
                              try
                                  m_PEnvir.GetRangeBaseObject(Monster.m_nCurrX, Monster.m_nCurrY, 20, True, ObjList);
                                  for j := 0 to ObjList.Count - 1 do begin
                                    BaseObject := TBaseObject(ObjList.Items);
                                    if (BaseObject = Monster) or (BaseObject.m_btRaceServer = RC_PRINCESSGUARD) or
                                    (BaseObject.m_Master <> nil) or (BaseObject.m_boHideMode) or
                                    CheckSPCode(BaseObject.m_dwRuleCtrlCode, SP_MON_DISABLELINGFU) or
                                    BaseObject.m_boDeath or BaseObject.m_boGhost or BaseObject.m_boHideMode then Continue;

                                    if IsProperTarget(BaseObject) then begin
                                    BaseObject.m_boHideMode := True;
                                    BaseObject.SendDelayMsg(Self, RM_LINGFUSTRUCK, 0, g_Config.nLinfuDecHP, 0, 0, '', 300);
                                    Inc(n14);
                                    SetLength(TargeList, n14);
                                    TargeList := Integer(BaseObject);
                                    end;
                                    if n14 >= UserItem.Dura then Break;
                                  end;
                              finally
                                  ObjList.free;
                              end;
                              //扣除灵符持久
                              if n14 >= UserItem.Dura then UserItem.Dura := 0;
                              end else
                              n14 := 1;
                              //发送效果
                              if n14 > 1 then begin
                              sTmp := EnCodeBuffer(@TargeList, SizeOf(Integer) * n14);
                              SendRefMsg(RM_USEBINDLINGFU, n14, Integer(Monster), $0D, m_btDirection, sTmp);
                              end else begin
                              SendRefMsg(RM_ASSISTSKILL, $0D, Integer(Monster), m_btDirection, MakeLong(Monster.m_nCurrX, Monster.m_nCurrY), '');
                              end;
                              //目标怪物
                              Monster.m_boHideMode := True;
                              Monster.SendDelayMsg(Self, RM_LINGFUSTRUCK, 0, g_Config.nLinfuDecHP, 0, 0, '', 300);

                              //扣除灵符
                              if (UserItem.Dura > 0) then Dec(UserItem.Dura, n14);
                              if (UserItem.Dura <= 0) then begin
                              m_nEatItemMakeIndex := 0;
                              DelBagItem(UserItem34.MakeIndex, '');
                              boEatOK := True;
                              end else begin
                              boEatOK := False;
                              //SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                              SendUpdateItem(UserItem);
                              end;
                            end else begin
                              m_nEatItemMakeIndex := 0;
                              DelBagItem(UserItem34.MakeIndex, '');
                              boEatOK := True;
                              n14 := 1;
                            end;
                            //触发脚本
                            m_sScriptParam := IntToStr(n14);                                     //杀怪数量
                            ExecuteScript(g_FunctionNPC, '@灵符杀怪');
                        end;
                        end;
                      end;
                  206, 207: begin
                        if (not CheckSPCode(Monster.m_dwRuleCtrlCode, SP_MON_ALLOWCATCH)) then begin
                        SysMsg('灵兽项圈不能用来捕捉此怪物!', c_Red, t_Hint);
                        goto EAT_END;
                        end;
                        if (Monster.m_Master <> nil) or (Monster.m_boIsPet) then begin
                        SysMsg('灵兽已有主人,不能被捕捉', c_Red, t_Hint);
                        goto EAT_END;
                        end;
                        {灵兽减血}
                        Monster.SendDelayMsg(Self, RM_LINGFUSTRUCK, 0, g_Config.nChapLetDecHP, 0, 0, '', 300);
                        n14 := Monster.m_WAbil.dwHP div g_Config.nChapLetMonHPRate;
                        if n14 <= 2 then n14 := 2;
                        if (Random(20) > (Monster.m_wSlaveExpLevel + g_Config.nChapLetMonLevel {10})) and ((Random(n14) = 0)) then begin
                        nCode := $123F;
                        m_sScriptParam := Monster.m_sCharName;                                 //灵兽名称
                        m_sScriptParam := IntToStr(Monster.m_wAppr);                           //灵兽Appr
                        m_sScriptParam := IntToStr(Monster.m_wSlaveExpLevel);                  //灵兽等级
                        m_sScriptParam := IntToStr(nItemIdx);
                        ExecuteScript(g_FunctionNPC, '@捕捉灵兽');
                        end else begin
                        nCode := $123E;
                        end;
                        //显示一个效果
                        TurnTo(GetNextDirection(m_nCurrX, m_nCurrY, Monster.m_nCurrX, Monster.m_nCurrY));
                        SendRefMsg(RM_ASSISTSKILL, nCode, Integer(Monster), m_btDirection, MakeLong(Monster.m_nCurrX, Monster.m_nCurrY), '');
                        if nCode = $123F then Monster.MakeGhost;                                    //抓捕成功
                        if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                        if StdItem.Shape = 207 then begin                                       //捆
                            if UserItem.Dura > 0 then Dec(UserItem.Dura);
                            if (UserItem.Dura <= 0) then begin
                              m_nEatItemMakeIndex := 0;
                              DelBagItem(UserItem34.MakeIndex, '');
                              boEatOK := True;
                            end else begin
                              boEatOK := False;
                              //SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                              SendUpdateItem(UserItem);
                            end;
                        end else begin
                            m_nEatItemMakeIndex := 0;
                            DelBagItem(UserItem34.MakeIndex, '');
                            boEatOK := True;
                        end;
                        end;
                      end;
                  210: begin
                        tm := MakeLong(MakeWord(UserItem.btValue, UserItem.btValue),
                        MakeWord(UserItem.btValue, UserItem.btValue));
                        if (tm = 0) then begin                                                      //第一次使用
                        tm := DateTimeToWolTIme(Now);
                        tm := tm + (StdItem.sC * 86400);
                        Move(tm, UserItem.btValue, 4);                                       //激活时间
                        UserItem.btItemExt := 1;                                             //绑定
                        SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                        SendUpdateItem(UserItem);
                        end else begin
                        if (DateTimeToWolTIme(Now) > tm) then begin
                            SysMsg('该物品已经到期', c_Red, t_Hint);
                        end else begin
                            ExecuteScript(g_ManageNPC, '@_释放_兽尊灵丹');
                        end;
                        end;
                      end
                  else begin
                      if (StdItem.Shape = 201) and (StdItem.AniCount = 20000) then begin
                        if m_PEnvir.m_MapFlag.boNORANDOMMOVE then begin
                        SysMsg('此地图禁止使用随机', c_Red, t_Hint);
                        goto EAT_END;
                        end else begin
                        SendRefMsg(RM_SPACEMOVE_FIRE, 0, 0, 0, 0, '');
                        BaseObjectMove(m_sMapName, '', '');
                        if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                            if UserItem.Dura > 0 then Dec(UserItem.Dura);
                            if (UserItem.Dura = 0) then begin
                              m_nEatItemMakeIndex := 0;
                              DelBagItem(UserItem34.MakeIndex, '');
                              boEatOK := True;
                            end else begin
                              //SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                              SendUpdateItem(UserItem);
                            end;
                        end;
                        end;

                      end else if (StdItem.Shape = 15) or ((StdItem.Shape = 17) and ((StdItem.Looks = 729) or (StdItem.Looks = 942))) then begin
                        //回城神石
                        if (m_wShopItemCount > 0) or m_boArrow then goto EAT_END;                   //禁止使用回城石的条件

                        if (GetTickCount - m_dwUseStoreTick) < 10000 then begin
                        SysMsg('每隔10秒才允许使用回城石一次。', c_Red, t_Hint);
                        goto EAT_END;
                        end;

                        if m_PEnvir.m_MapFlag.boNOSTOREMOVE then begin
                        SysMsg('当前地图禁止使用回城石。', c_Red, t_Hint);
                        goto EAT_END;
                        end;

                        if StdItem.AniCount = 0 then begin
                        nX := MakeWord(UserItem.btValue, UserItem.btValue);
                        nY := MakeWord(UserItem.btValue, UserItem.btValue);
                        sMAP := '';
                        for j := 4 to 9 do begin
                            if UserItem.btValue = 0 then Break;
                            sMAP := sMAP + Chr(UserItem.btValue);
                        end;

                        if (sMAP <> '') then begin
                            m_sScriptParam := m_PEnvir.m_sMapName;
                            m_sScriptParam := sMAP;
                            SendRefMsg(RM_SPACEMOVE_FIRE, 0, 0, 0, 0, '');
                            SpaceMove(sMAP, nX + Random(8) - 4, nY + Random(8) - 4, 0, nil);
                            m_dwUseStoreTick := GetTickCount;
                            ExecuteScript(g_FunctionNPC, '@使用回城石');
                            if (StdItem.Shape = 17) then begin
                              if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                              if UserItem.Dura > 0 then Dec(UserItem.Dura);
                              if (UserItem.Dura = 0) then begin
                                  m_nEatItemMakeIndex := 0;
                                  DelBagItem(UserItem34.MakeIndex, '');
                                  boEatOK := True;
                              end else begin
                                  boEatOK := False;
                                  SendUpdateItem(UserItem);
                              end;
                              end;
                            end;
                        end else
                            SysMsg('该' + StdItem.Name + '没有刻地名,请到各地老兵处记录回城点。', c_Red, t_Hint);
                        end else begin
                        ExecuteScript(g_FunctionNPC, '@使用回城石');
                        boEatOK := False;
                        SendUpdateItem(UserItem);
                        end;
                      end else begin                                                                //其他类物品
                        if EatItems(StdItem) then begin
                        if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                            if UserItem.Dura > 0 then Dec(UserItem.Dura);
                            if (UserItem.Dura <= 0) then begin
                              m_nEatItemMakeIndex := 0;
                              DelBagItem(UserItem34.MakeIndex, '');
                              boEatOK := True;
                            end else begin
                              boEatOK := False;
                              //SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                              SendUpdateItem(UserItem);
                            end;
                        end;
                        end;
                      end;
                  end;
                  end;
                  goto EAT_END;
                end;
            4, 8: begin                                                                           //书
                  nCheckCode := 192;
                  if (g_FunctionNPC <> nil) and (StdItem.AniCount > 0) then begin
                  SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                  UseStdmodeFunItem(StdItem, True);
                  end else begin
                  boEatOK := ReadBook(StdItem);
                  if boEatOK then begin
                      if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                        m_nEatItemMakeIndex := 0;
                        DelBagItem(UserItem34.MakeIndex, '');
                      end;
                      //刺杀剑法
                      if (m_MagicSkills <> nil) and (not m_boUseThrusting) then begin
                        ThrustingOnOff(True);
                        SendSocket(nil, '+LNG');
                      end;
                      //半月弯刀
                      if (m_MagicSkills <> nil) and (not m_boUseHalfMoon) then begin
                        HalfMoonOnOff(True);
                        SendSocket(nil, '+WID');
                      end;
                  end;
                  end;
                end;
            12: begin                                                                           //盾牌升级
                  SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                  ExecuteScript(g_FunctionNPC, '@TigerShield');
                end;
            30: begin                                                                           //精英勋章
                  nCheckCode := 193;
                  if (StdItem.Looks = 8020) then begin
                  SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                  ExecuteScript(g_FunctionNPC, '@EliteMedal');
                  end;
                end;
            31: begin                                                                           //解包物品
                  nCheckCode := 194;
                  if StdItem.AniCount = 0 then begin                                                //打包的物品
                  if (m_ItemList.Count + 6 - 1) <= m_nBagSize then begin
                      if m_boPneuma then SendDelItems(UserItem);
                      if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                        m_nEatItemMakeIndex := 0;
                        DelBagItem(UserItem34.MakeIndex, '');
                      end;
                      GetUnBindItems(GetUnbindItemName(StdItem.Shape), 6);
                      boEatOK := True;
                  end;
                  end else if StdItem.AniCount = 255 then begin                                     //魔法字体、魔法颜料
                  if StdItem.AC > 1 then begin
                      m_btChatColor := StdItem.AC;
                      SysMsg('您改变了文字颜色', c_Red, t_Hint);
                  end;
                  if StdItem.MAC > 0 then begin
                      m_btChatFont := StdItem.MAC;
                      SysMsg('您改变了文字字体', c_Red, t_Hint);
                  end;
                  if (StdItem.DC > 0) and (StdItem.DC <= 77) then begin
                      if (m_MagicSkills <> nil) then begin
                        m_MagicSkills.nSkillColor :=
                        MakeLong(MakeWord(HiWord(StdItem.MC),
                        LoWord(StdItem.MC)), MakeWord(HiWord(StdItem.SC),
                        LoWord(StdItem.SC)));
                        SendDefMessage($B4A4, m_MagicSkills.nSkillColor, StdItem.DC, 0, 0, '');
                        SysMsg('您改变了魔法颜色', c_Red, t_Hint);
                      end;
                  end;
                  if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                      if UserItem.Dura > 0 then Dec(UserItem.Dura);
                      if (UserItem.Dura <= 0) then begin
                        m_nEatItemMakeIndex := 0;
                        DelBagItem(UserItem34.MakeIndex, '');
                        boEatOK := True;
                      end else begin
                        //SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                        SendUpdateItem(UserItem);
                      end;
                  end;
                  end else if StdItem.AniCount = 254 then begin                                     //天气卷轴
                  if GetTickCount - m_PEnvir.m_dwChangeTick < 2 * 60 * 1000 then begin
                      SysMsg('天气效果2分钟内不可以连续更换!', c_Red, t_Hint);
                      goto EAT_END;
                  end;
                  m_PEnvir.m_dwChangeTick := GetTickCount();
                  m_PEnvir.m_MapFlag.nWeather := MakeWord(LoWord(StdItem.AC), HiWord(StdItem.AC));
                  m_PEnvir.m_MapFlag.wWindSpeed := MakeWord(LoWord(StdItem.MAC), HiWord(StdItem.MAC));
                  m_PEnvir.m_MapFlag.dwWindColor := MakeLong(MakeWord(LoWord(StdItem.DC), HiWord(StdItem.DC)), MakeWord(LoWord(StdItem.MC), HiWord(StdItem.MC)));
                  UserEngine.SendMapMsg(m_PEnvir, Self, RM_DAYCHANGING, 0, 0, 0, 0, '');
                  UserEngine.SendMapMsg(m_PEnvir, Self, RM_TITLEMSM, 0, $38FF, $FC, 10, m_sCharName + '改变' + m_PEnvir.m_sMapDesc + '的天气为' + StdItem.Name + ',您现在可以打开天气效果欣赏。');
                  if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                      if UserItem.Dura > 0 then Dec(UserItem.Dura);
                      if (UserItem.Dura <= 0) then begin
                        m_nEatItemMakeIndex := 0;
                        DelBagItem(UserItem34.MakeIndex, '');
                        boEatOK := True;
                      end else begin
                        //SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                        SendUpdateItem(UserItem);
                      end;
                  end;
                  end else begin                                                                  //其他物品,比如卷、回城石
                  if (m_wShopItemCount > 0) or m_boArrow then goto EAT_END;
                  if UseStdmodeFunItem(StdItem) then begin
                      if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                        m_nEatItemMakeIndex := 0;
                        DelBagItem(UserItem34.MakeIndex, '');
                        boEatOK := True;
                      end;
                  end;
                  end;
                end;
            32: begin
                  nCheckCode := 195;                                                                //空马牌
                  if (m_btHorseType = 0) or (HorseName = '') then begin
                  SysMsg('你现在没有马,无法使用马牌(空)', c_Red, t_Hint);
                  goto EAT_END;
                  end;
                  UserItem2 := nil;
                  if m_UseItems.wIndex > 0 then begin
                  UserItem2 := @m_UseItems;
                  StdItem2 := UserEngine.GetStdItem(UserItem2.wIndex);
                  if (StdItem2.StdMode <> 33) then UserItem2 := nil;
                  end;
                  //杂物位置
                  if (UserItem2 = nil) and (m_UseItems.wIndex > 0) then begin
                  UserItem2 := @m_UseItems;
                  StdItem2 := UserEngine.GetStdItem(UserItem2.wIndex);
                  if (StdItem2.StdMode <> 33) then UserItem2 := nil;
                  end;
                  if UserItem2 <> nil then begin
                  SysMsg('你已绑定好了马牌,不用在次绑定马牌', c_Red, t_Hint);
                  goto EAT_END;
                  end;

                  //给他一个马牌
                  New(UserItem2);
                  if UserEngine.CopyToUserItemFromName('马牌', UserItem2) then begin
                  StdItem2 := UserEngine.GetStdItem(UserItem2.wIndex);
                  m_ItemList.Add(UserItem2);
                  UserItem2.Dura := UserItem2.DuraMax;
                  if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                      m_nEatItemMakeIndex := 0;
                      DelBagItem(UserItem34.MakeIndex, '');
                      WeightChanged();
                      SendDefMessage(SM_EAT_OK, 0, 0, 0, 0, '');
                  end;
                  SendAddItem(UserItem2);
                  //绑定马牌
                  UserItem2.btValue := m_btHorseType;
                  for j := 1 to Length(HorseName) do
                      UserItem2.btValue := byte(HorseName);
                  SendUpdateItem(UserItem2);
                  m_btHorseType := 0;
                  if ClientTakeOnItems(U_RIGHTHAND, UserItem2.MakeIndex, StdItem2.Name, True) then
                      SysMsg(Format('你的%s马牌已经装备到身上', ), c_Red, t_Hint);
                  boEatOK := True;
                  //Exit;
                  end else
                  Dispose(UserItem2);
                end;
            36, 46: begin                                                                         //天气卷轴
                  nCheckCode := 196;
                  if (StdItem.StdMode = 36) and (StdItem.Shape = 1) then begin
                  m_PEnvir.m_MapFlag.nWeather := MakeWord(LoWord(StdItem.AC), HiWord(StdItem.AC));
                  m_PEnvir.m_MapFlag.wWindSpeed := MakeWord(LoWord(StdItem.MAC), HiWord(StdItem.MAC));
                  m_PEnvir.m_MapFlag.dwWindColor := MakeLong(MakeWord(LoWord(StdItem.DC), HiWord(StdItem.DC)), MakeWord(LoWord(StdItem.MC), HiWord(StdItem.MC)));
                  UserEngine.SendMapMsg(m_PEnvir, Self, RM_DAYCHANGING, 0, 0, 0, 0, '');
                  UserEngine.SendBroadCastMsgExt(m_sCharName + '改变' + m_PEnvir.m_sMapDesc + '的天气为' + ReplaceStr(StdItem.Name, '卷轴', '') + ',您现在可以打开天气效果欣赏。', t_center);
                  if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                      if UserItem.Dura > 0 then Dec(UserItem.Dura);
                      if (UserItem.Dura <= 0) then begin
                        m_nEatItemMakeIndex := 0;
                        DelBagItem(UserItem34.MakeIndex, '');
                        boEatOK := True;
                      end else begin
                        SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                        SendUpdateItem(UserItem);
                      end;
                  end
                  end else if (StdItem.StdMode = 46) and (StdItem.Shape = 106) then begin         //财神许愿符
                  if m_PEnvir.m_MapFlag.boCanUseSuperItem and m_PEnvir.AllowSoulItem(sItemName) then begin
                      if (abs(45 - m_nCurrX) > 3) or (abs(45 - m_nCurrY) > 3) then begin
                        SysMsg('您站的太远了,请在许愿池附近使用该物品', c_Red, t_Hint);
                        goto EAT_END;
                      end else begin
                        SendRefMsg(RM_ASSISTSKILL, $1536, 0, 4, MakeLong(45, 45), '');
                        SendWishAwardInfo();
                        if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                        if UserItem.Dura > 0 then Dec(UserItem.Dura);
                        if (UserItem.Dura <= 0) then begin
                            m_nEatItemMakeIndex := 0;
                            DelBagItem(UserItem34.MakeIndex, '');
                            boEatOK := True;
                        end else begin
                            boEatOK := False;
                            SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                            SendUpdateItem(UserItem);
                        end;
                        end;
                      end;
                  end else
                      goto EAT_END;
                  end else begin                                                                  //执行脚本
                  if (StdItem.AniCount > 0) then begin
                      SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                      UseStdmodeFunItem(StdItem, True);
                  end;
                  goto EAT_END;
                  end;
                end;
            37: begin
                  nCheckCode := 197;
                  case StdItem.Shape of
                  2: begin
                        if (m_wShopItemCount > 0) or m_boArrow then goto EAT_END;                   //随机神石
                        if m_PEnvir.m_MapFlag.boNORANDOMMOVE then begin
                        SysMsg('此地图禁止使用随机', c_Red, t_Hint);
                        goto EAT_END;
                        end else begin
                        SendRefMsg(RM_SPACEMOVE_FIRE, 0, 0, 0, 0, '');
                        BaseObjectMove(m_sMapName, '', '');
                        if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                            if UserItem.Dura > 0 then Dec(UserItem.Dura);
                            if (UserItem.Dura = 0) then begin
                              m_nEatItemMakeIndex := 0;
                              DelBagItem(UserItem34.MakeIndex, '');
                              boEatOK := True;
                            end else begin
                              SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                              SendUpdateItem(UserItem);
                            end;
                        end;
                        end;
                      end;
                  3: begin
                        if m_sDearName = '' then begin
                        SysMsg('尚未婚配,不可以种植' + g_Config.sLoveTree, c_Red, t_Hint);
                        goto EAT_END;
                        end;
                        if not InPlantZone then begin
                        SysMsg('该地区不可以植树。', c_Red, t_Hint);
                        goto EAT_END;
                        end;
                        GetFrontPosition(nX, nY);
                        sTmp := m_sCharName;
                        if (m_sDearName <> '') then sTmp := sTmp + '和' + m_sDearName;
                        sTmp := sTmp + '的' + g_Config.sLoveTree;
                        Monster := UserEngine.RegenMonsterByName(m_PEnvir, nX, nY, g_Config.sLoveTree, sTmp, 3);
                        if Monster <> nil then begin
                        Monster.m_wSlaveMakeLevel := 0;
                        Monster.m_wSlaveExpLevel := 0;
                        Monster.RecalcAbilitys;
                        Monster.RefNameColor;
                        SysMsg('恭喜您,爱情之树种植成功,您的爱情之树现在的寿命是3天。', c_Red, t_Hint);
                        if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                            if UserItem.Dura > 0 then Dec(UserItem.Dura);
                            if (UserItem.Dura <= 0) then begin
                              m_nEatItemMakeIndex := 0;
                              DelBagItem(UserItem34.MakeIndex, '');
                              boEatOK := True;
                            end else begin
                              SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                              SendUpdateItem(UserItem);
                            end;
                        end;
                        end;
                      end;
                  4: begin
                        if m_sDearName = '' then begin
                        SysMsg('尚未婚配,不可以种植' + g_Config.sLoveTree, c_Red, t_Hint);
                        goto EAT_END;
                        end;
                        if not InPlantZone then begin
                        SysMsg('该地区不可以植树。', c_Red, t_Hint);
                        goto EAT_END;
                        end;
                        sTmp := m_sCharName;
                        if m_sDearName <> '' then sTmp := sTmp + '和' + m_sDearName;
                        sTmp := sTmp + '的' + g_Config.sLoveTree;

                        ObjList := TList.Create;
                        try
                        m_PEnvir.GetRangeBaseObject(m_nCurrX, m_nCurrY, 2, True, ObjList);
                        boFind := False;
                        for j := 0 to ObjList.Count - 1 do begin
                            Monster := TBaseObject(ObjList);
                            if (Monster.m_wAppr = 241) and (CompareText(Monster.m_sCharName, sTmp) = 0) then begin
                              Monster.m_nLifeSpan := Monster.m_nLifeSpan + StdItem.AC;
                              SysMsg(sTmp + '寿命成功延长' + IntToStr(StdItem.AC) + '天,死亡时间推迟到' + DateToChStr(Monster.m_dtBirthday + Monster.m_nLifeSpan, True), c_Red, t_Hint);
                              if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                              if UserItem.Dura > 0 then Dec(UserItem.Dura);
                              if (UserItem.Dura <= 0) then begin
                                  m_nEatItemMakeIndex := 0;
                                  DelBagItem(UserItem34.MakeIndex, '');
                                  boEatOK := True;
                              end else begin
                                  SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                                  SendUpdateItem(UserItem);
                              end;
                              end;
                              boFind := True;
                              Break;
                            end;
                        end;
                        finally
                        ObjList.free;
                        end;
                        if not boFind then
                        SysMsg('附近没有发现' + sTmp + ',请在5格范围内使用', c_Red, t_Hint);
                      end;
                  202: begin
                        if PackageItems(nPackIdx) then begin
                        if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                            if UserItem.Dura > 0 then Dec(UserItem.Dura);
                            if (UserItem.Dura <= 0) then begin
                              m_nEatItemMakeIndex := 0;
                              DelBagItem(UserItem34.MakeIndex, '');
                              boEatOK := True;
                            end else begin
                              SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                              SendUpdateItem(UserItem);
                            end;
                        end;
                        end;
                      end;
                  10: begin
                        if (m_Pet = nil) or (m_PetInfo.nMakeIndex = 0) then begin
                        SysMsg('你的身边没有可喂食的宠物,不能喂食。', c_Red, t_Hint);
                        goto EAT_END;
                        end;

                        if PetStoreAddExp(m_PetInfo.nMakeIndex, StdItem.AC, LoWord(StdItem.AC), True) then begin
                        if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                            if UserItem.Dura > 0 then Dec(UserItem.Dura);
                            if (UserItem.Dura <= 0) then begin
                              m_nEatItemMakeIndex := 0;
                              SendDelItems(UserItem);
                              DelBagItem(UserItem34.MakeIndex, '');
                              goto EAT_END;
                            end else begin
                              SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                              SendUpdateItem(UserItem);
                            end;
                        end;
                        end;
                      end;
                  11: begin
                        m_boRideOn := False;
                        if StdItem.AniCount <> m_btGender then begin
                        SysMsg('性别不符,不能使用', c_Red, t_Hint);
                        m_boRideOn := True;
                        goto EAT_END;
                        end;

                        if m_UseItems.wIndex > 0 then begin
                        m_UseItems.wIndex := 0;
                        m_nDressShape := 0;
                        SendDefMessage(SM_TAKEOFF_OK, GetFeatureToLong(Self), GetGender, 0, 0, '');
                        end;

                        if ((m_nDressShape and $000000C8) = $000000C8) then begin
                        if m_UseItems.wIndex = 0 then
                            m_nDressShape := 0
                        else begin
                            StdItem2 := UserEngine.GetStdItem(m_UseItems.wIndex);
                            if StdItem2 = nil then
                              m_nDressShape := 0
                            else
                              m_nDressShape := MakeLong(MakeWord(StdItem2.Shape, $00), HiWord(m_nDressShape));
                        end;
                        if m_boRideOn then ClientRideOff();
                        end else begin
                        m_nDressShape := MakeLong($00C8, HiWord(m_nDressShape));
                        if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                            if UserItem.Dura > 0 then Dec(UserItem.Dura);
                            if (UserItem.Dura <= 0) then begin
                              m_nEatItemMakeIndex := 0;
                              DelBagItem(UserItem34.MakeIndex, '');
                              boEatOK := True;
                            end else begin
                              SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                              SendUpdateItem(UserItem);
                            end;
                        end;
                        end;
                        RecalcAbilitys();
                        SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
                        SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
                        m_nMagicStatus := GetMagicStatus;
                        Status2Changed;
                        FeatureChanged;
                      end;
                  14, 30: begin
                        //极品御兽天衣、仙魂御龙袍
                        m_boRideOn := False;
                        if StdItem.AniCount <> m_btGender then begin
                        SysMsg('性别不符,不能使用', c_Red, t_Hint);
                        m_boRideOn := True;
                        goto EAT_END;
                        end;

                        if m_UseItems.wIndex > 0 then begin
                        m_UseItems.wIndex := 0;
                        m_nDressShape := 0;
                        SendDefMessage(SM_TAKEOFF_OK, GetFeatureToLong(Self), GetGender, 0, 0, '');
                        if m_boRideOn then ClientRideOff();
                        end else begin
                        m_UseItems := UserItem^;
                        SendUseitems();
                        end;

                        RecalcAbilitys();
                        SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
                        SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
                        m_nMagicStatus := GetMagicStatus;
                        Status2Changed;
                        FeatureChanged;
                      end;
                  200: begin
                        if SuperRepairUseItems then begin
                        if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                            if UserItem.Dura > 0 then Dec(UserItem.Dura);
                            if (UserItem.Dura <= 0) then begin
                              m_nEatItemMakeIndex := 0;
                              DelBagItem(UserItem34.MakeIndex, '');
                              boEatOK := True;
                            end else begin
                              SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                              SendUpdateItem(UserItem);
                            end;
                        end;
                        end;
                      end;
                  207, 209: begin
                        if ExecuteScript(g_ManageNPC, '@加点装备') then begin
                        if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                            if UserItem.Dura > 0 then Dec(UserItem.Dura);
                            if (UserItem.Dura <= 0) then begin
                              m_nEatItemMakeIndex := 0;
                              DelBagItem(UserItem34.MakeIndex, '');
                              boEatOK := True;
                            end else begin
                              SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                              SendUpdateItem(UserItem);
                            end;
                        end;
                        end;
                      end;
                  else begin
                      SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                      if UseStdmodeFunItem(StdItem) then begin
                        if (m_nEatItemMakeIndex = UserItem34.MakeIndex) then begin
                        if (UserItem.Dura > 0) and (StdItem.Source <> 1) then Dec(UserItem.Dura);
                        if (UserItem.Dura = 0) and (StdItem.Source <> 1) then begin
                            m_nEatItemMakeIndex := 0;
                            SendDelItems(UserItem);
                            DelBagItem(UserItem34.MakeIndex, '');
                            boEatOK := True;
                        end else begin
                            SendUpdateItem(UserItem);
                        end;
                        end;
                      end;
                  end;
                  end;
                end;
            49: begin
                  nCheckCode := 198;
                  m_nEatItemMakeIndex := 0;
                  case StdItem.Shape of
                  51: begin                                                                     //豹魔石
                        if (m_Pet = nil) and (m_PetInfo.nMakeIndex = 0) and (not IsDownPetItem(UserItem.MakeIndex)) then begin //放出豹子
                        //检查豹子状态
                        tm := MakeLong(MakeWord(UserItem.btValue, UserItem.btValue), MakeWord(UserItem.btValue, UserItem.btValue));
                        if (tm > 0) and (tm + (PETMAXUSEDAY * 86400) <= DateTimeToWolTIme(Now)) then begin //第5天死亡
                            SysMsg('你的宠物已经死亡。', c_Red, t_Hint);
                            goto EAT_END;
                        end;

                        //绑定灵兽
                        if (not g_Config.boClassicServer) and (UserItem.btItemExt = 0) then begin
                            UserItem.btItemExt := 1;
                            SendUpdateItem(UserItem);
                        end;

                        if tm = 0 then begin
                            tm := DateTimeToWolTIme(Now);
                            UserItem.btValue := LoByte(LoWord(tm));
                            UserItem.btValue := HiByte(LoWord(tm));
                            UserItem.btValue := LoByte(HiWord(tm));
                            UserItem.btValue := HiByte(HiWord(tm));
                            SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                            m_sPetName := '';
                            SendUpdateItem(UserItem);
                        end;
                        PetShow(UserItem.MakeIndex);

                        sMAP := _PETNAME)];
                        if m_Pet <> nil then begin
                            n14 := DateTimeToWolTIme(Now) - tm;
                            n14 := n14 div 86400;
                            if n14 <= 2 then
                              SysMsg('您的' + sMAP + '精神饱满。', c_Red, t_Hint)
                            else if n14 = 3 then
                              SysMsg('您的' + sMAP + '状态为微饿。红袖处有兽粮出售。', c_Red, t_Hint)
                            else if n14 = 4 then
                              SysMsg('您的' + sMAP + '状态为饥饿。红袖处有兽粮出售。', c_Red, t_Hint)
                            else
                              SysMsg('您的' + sMAP + '已饿死,您可以带着神水请驯兽师帮您复活。商城内有神水出售。', c_Red, t_Hint);
                            nCheckCode := 19891;
                            m_Pet.RefShowName;
                            ExecuteScript(g_FunctionNPC, '@ReleasePet');
                            if UserItem.btValue < 3 then
                              SendUpdateDelayMsg(Self, RM_REFRESHRANK, 0, 3, UserItem.MakeIndex, 0, '', 200) //刷新灵兽排名
                            else
                              SendUpdateDelayMsg(Self, RM_REFRESHRANK, 0, 4, UserItem.MakeIndex, 0, '', 200);
                        end;
                        end else begin                                                            //收起豹子
                        if (m_Pet <> nil) and
                            (m_PetInfo.nMakeIndex <> UserItem.MakeIndex) and
                            (not IsDownPetItem(UserItem.MakeIndex)) then
                        begin
                            SysMsg('你无法同时使两个灵兽跟随', c_Red, t_Hint);
                            goto EAT_END;
                        end;

                        if (m_PackPet <> nil) and (m_PetInfo.nMakeIndex = UserItem.MakeIndex) then
                            SysMsg('你的宠物正在替你守摊,停止守摊后才能召唤你的宠物。', c_Red, t_Hint)
                        else if (m_PetInfo.nMakeIndex = UserItem.MakeIndex) then
                            SysMsg('你的宠物正在替你探宝,停止探宝后才能召唤你的宠物。', c_Red, t_Hint)
                        else if (m_PetInfo.nMakeIndex = UserItem.MakeIndex) then
                            SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, '该灵兽处于魂佑附体状态,无法跟随')
                        else
                            PetHide(UserItem.MakeIndex);
                        end;
                      end;
                  52: begin                                                                     //兽粮
                        if (m_Pet = nil) or (m_PetInfo.nMakeIndex = 0) then begin
                        SysMsg('你的身边没有可喂食的宠物,不能喂食。', c_Red, t_Hint);
                        goto EAT_END;
                        end;
                        if PetStoreAddExp(m_PetInfo.nMakeIndex, StdItem.DuraMax, LoWord(StdItem.AC), True) then begin
                        m_nEatItemMakeIndex := 0;
                        SendDelItems(UserItem);
                        DelBagItem(UserItem34.MakeIndex, '');
                        boEatOK := True;
                        goto EAT_END;
                        end;
                      end;
                  15, 16, 17, 18: begin
                        //摊位样式,摊位旗帜,百变披风
                        if (StdItem.Shape = 18) and (m_boRideOn or m_boCatapultMode) then begin
                        SysMsg('你现在不可以使用变身披风', c_Red, t_Hint);
                        goto EAT_END;
                        end;
                        boEatOK := CheckUserItemTimeOut(UserItem, StdItem);
                        if boEatOK then begin
                        DelBagItem(UserItem34.MakeIndex, '');
                        goto EAT_END;
                        end else begin
                        if StdItem.Shape = 15 then begin
                            if StdItem.AC > 1 then begin
                              m_btChatColor := StdItem.AC;
                              SysMsg('您改变了文字颜色', c_Red, t_Hint);
                            end;
                            if StdItem.MAC > 0 then begin
                              m_btChatFont := StdItem.MAC;
                              SysMsg('您改变了文字字体', c_Red, t_Hint);
                            end;
                            if (StdItem.DC > 0) and (StdItem.DC <= 77) then begin
                              if (m_MagicSkills <> nil) then begin
                              m_MagicSkills.nSkillColor := MakeLong(MakeWord(HiWord(StdItem.MC),
                                  LoWord(StdItem.MC)),
                                  MakeWord(HiWord(StdItem.SC),
                                  LoWord(StdItem.SC)));
                              SendDefMessage($B4A4, m_MagicSkills.nSkillColor, StdItem.DC, 0, 0, '');
                              SysMsg('您改变了魔法颜色', c_Red, t_Hint);
                              end;
                            end;
                        end else if StdItem.Shape = 16 then begin                                 //摊位类型
                            m_wShopKind := StdItem.DC;
                            SysMsg('您改变了摊位类型', c_Red, t_Hint);
                        end else if StdItem.Shape = 17 then begin                                 //摊位旗帜
                            m_btShopBanner := StdItem.DC;
                            m_nBannerColor :=
                              MakeLong(MakeWord(LoWord(StdItem.MC),
                              HiWord(StdItem.MC)), MakeWord(LoWord(StdItem.SC),
                              HiWord(StdItem.SC)));
                            SysMsg('您改变了摊位旗帜', c_Red, t_Hint);
                        end else if StdItem.Shape = 18 then begin                                 //变身披风
                            if (StdItem.DC = m_wBianshenImg) and (StdItem.MC = m_wBianshenAppr) then begin //取消变身
                              m_wBianshenImg := 0;
                              m_wBianshenAppr := 0;
                            end else begin
                              m_wBianshenImg := StdItem.DC;
                              m_wBianshenAppr := StdItem.MC;
                            end;
                            if m_wExtraLevel > 0 then begin
                              if m_wBianshenAppr = 0 then
                              SendMsg(Self, RM_FENGHAO, MakeWord(8, LoByte(m_wExtraLevel)), GetPneumaAmbit, HiByte(m_wExtraLevel), 0, GetExtraLevelName)
                              else
                              SendMsg(Self, RM_FENGHAO, MakeWord(8, 0), 0, 0, 0, '');
                            end;
                            SendRefMsg(RM_FENGHAO, 64, m_wBianshenImg, m_wBianshenAppr, 0, '');
                        end;
                        goto EAT_END;
                        end;
                      end;
                  22: begin
                        //御兽天衣 ,御兽天袍 Anicount=0为男性,Anicount=1为女性
                        boEatOK := CheckUserItemTimeOut(UserItem, StdItem);
                        m_boRideOn := False;
                        if StdItem.AniCount <> m_btGender then begin
                        SysMsg('性别不符,不能使用', c_Red, t_Hint);
                        m_boRideOn := True;
                        goto EAT_END;
                        end;
                        if boEatOK then begin
                        DelBagItem(UserItem34.MakeIndex, '');
                        goto EAT_END;
                        end else begin

                        if m_UseItems.wIndex > 0 then begin
                            m_UseItems.wIndex := 0;
                            m_nDressShape := 0;
                            SendDefMessage(SM_TAKEOFF_OK, GetFeatureToLong(Self), GetGender, 0, 0, '');
                        end;

                        if ((m_nDressShape and $000000C8) = $000000C8) then begin
                            if m_UseItems.wIndex = 0 then
                              m_nDressShape := 0
                            else begin
                              StdItem2 := UserEngine.GetStdItem(m_UseItems.wIndex);
                              if StdItem2 = nil then
                              m_nDressShape := 0
                              else
                              m_nDressShape := MakeLong(MakeWord(StdItem2.Shape, $00), HiWord(m_nDressShape));
                            end;
                            if m_boRideOn then ClientRideOff();
                        end else begin
                            m_nDressShape := MakeLong($00C8, HiWord(m_nDressShape));
                        end;
                        RecalcAbilitys();
                        SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
                        SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
                        m_nMagicStatus := GetMagicStatus;
                        Status2Changed;
                        FeatureChanged;
                        goto EAT_END;
                        end;
                      end;
                  55, 56: ;                                                                     //封元印
                  107: begin
                        m_ExpeditionCount := 0;
                        FillChar(m_ExpeditionBox, SizeOf(TExpeditionBox), #0);
                        UseStdmodeFunItem(StdItem);
                        m_nEatItemMakeIndex := 0;
                        boEatOK := True;
                        goto EAT_END;
                      end
                  else begin                                                                        //49类的其他物品,同37类物品,但支持使用天数
                      boEatOK := CheckUserItemTimeOut(UserItem, StdItem);
                      if boEatOK then begin
                        m_nEatItemMakeIndex := 0;
                        DelBagItem(UserItem34.MakeIndex, '');
                        goto EAT_END;
                      end else begin
                        UseStdmodeFunItem(StdItem);
                        goto EAT_END;
                      end;
                  end;
                  end;
                end;
            59: begin
                  nCheckCode := 199;
                  if StdItem.Shape in then begin
                  ExecuteScript(g_FunctionNPC, '@圣灵宝石' + IntToStr(StdItem.Shape));
                  SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                  end;
                end;
            82, 83: begin
                  nCheckCode := 200;
                  if StdItem.Shape = 131 then begin
                  ExecuteScript(g_FunctionNPC, '@AppraisalItem' + IntToStr(StdItem.AniCount));
                  SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
                  end;
                end;
            end;
          end;
      end;
      end;
    end else begin
      //SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, g_sCanotUseItemMsg);
      SysMsg(g_sCanotUseItemMsg, c_Pink, t_Hint);
    end;

    EAT_END:
    nCheckCode := 201;
    if boEatOK then begin
      //WeightChanged(); //这里不需要了
      SendDefMessage(SM_EAT_OK, 0, 0, 0, 0, '');
      nCheckCode := 202;
      if StdItem.boGameLog = 1 then
      AddGameDataLog('11' + #9 +
          m_sMapName + #9 +
          IntToStr(m_nCurrX) + #9 +
          IntToStr(m_nCurrY) + #9 +
          m_sCharName + #9 +
          sItemName + #9 +
          IntToStr(UserItem34.MakeIndex) + #9 +
          '1' + #9 +
          '0');
    end else begin
      SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
    end;
except
    on E: Exception do begin
      MainOutMessage(Format(sExceptionMsg, ));
      MainOutMessage(E.Message);
    end;
end;
end;

{客户端快捷交易}

procedure TPlayObject.ClientQueryUserSet(ProcessMsg: pTProcessMessage);
begin
if Assigned(m_VersionManage) then
try
    m_VersionManage.OnClientQueryUserSet(Self, ProcessMsg);
except
    MainOutMessage(Format('TPlayObject::ClientQueryUserSet SoftVersionDate:%d', ));
end;
end;

//发送货物明细

procedure TPlayObject.ClientUserBuyItem(nIdent, nParam1, nInt, nZz: Integer; sMsg: string; nType: Integer = 0); //004DCA10
begin
if Assigned(m_VersionManage) then
try
    m_VersionManage.OnClientUserBuyItem(Self, nIdent, nParam1, nInt, nZz, sMsg);
except
    MainOutMessage(Format('TPlayObject::ClientUserBuyItem SoftVersionDate:%d', ));
end;
end;

procedure TPlayObject.ClientUserSellItem(nParam1, nMakeIndex: Integer; sMsg: string);
var
i                                     : Integer;
UserItem                              : pTUserItem;
Merchant                              : TMerchant;
sName                                 : string;
begin
for i := m_ItemList.Count - 1 downto 0 do begin
    UserItem := m_ItemList.Items;
    if (UserItem <> nil) and (UserItem.MakeIndex = nMakeIndex) then begin
      {取自定义物品名称}
      sName := '';
      ItemUnit.GetCustomItemName(UserItem, sName);

      if (CompareText(sMsg, sName) = 0) then begin
      Merchant := UserEngine.FindMerchant(TObject(nParam1));
      if (Merchant <> nil) and
          (Merchant.m_boSell) and
          (IsEnvir(Merchant.m_PEnvir) and
          (abs(Merchant.m_nCurrX - m_nCurrX) < 15) and
          (abs(Merchant.m_nCurrY - m_nCurrY) < 15)) then begin
          if Merchant.ClientSellItem(Self, UserItem) then begin
            if UserItem.btValue and $01 = 1 then begin
            ItemUnit.DelCustomItemName(UserItem.MakeIndex, UserItem.wIndex);
            UserItem.btValue := UserItem.btValue and $FE;
            //清除自定义物品名字标记
            end;
            m_ItemList.Delete(i);
            WeightChanged();
          end;
      end;
      Break;
      end;
    end;
end;                                                                                              // for
end;

//CM_WALK命令的处理

function TPlayObject.ClientWalkXY(wIdent: word; nX, nY: Integer; boLateDelivery:
Boolean; var dwDelayTime: LongWord): Boolean;                                                   //004CAF08
var
n14, n18, n1C                         : Integer;
dwCheckTime                           : LongWord;
nPinjunTime                           : Integer;
nCheckTime                            : Integer;
begin
Result := False;
dwDelayTime := 0;
if (not m_boCanWalk) or (m_wShopItemCount > 0) or (m_boCatapultAttackMode) then Exit;

if not CheckCanOperate(cWalk) then Exit;

if (not g_Config.boDisableM2SpeedCtrl) then begin
    //10指令时间控制
    if m_nWalkCount = 0 then m_FirstWalkTick := GetTickCount;
    m_nRunCount := 0;
    Inc(m_nWalkCount);
    if m_nWalkCount >= 11 then begin
      nPinjunTime := (GetTickCount - m_FirstWalkTick) div 10;
{$IF USESDK = DEBUG}
      //SysMsg('走10次平均时间:'+inttostr(nPinjunTime),c_blue,t_hint);
{$IFEND}
      m_FirstWalkTick := GetTickCount;
      m_nWalkCount := 0;
      if nPinjunTime < g_Config.n10WalkTIme then begin
      if m_boTestSpeedMode then
          SysMsg(Format('10次走超速!限制:%d,当前:%d', ), c_Red, t_Hint);
      Exit;
      end;
    end;
end;

nCheckTime := GetTickCount - m_dwDoMotaeboMoveTick;
if nCheckTime < g_Config.dwWalkIntervalTime div 4 then
    Exit;                                                                                           //如果间隔时间小于 600 毫秒
m_dwDoMotaeboMoveTick := GetTickCount();

if (not g_Config.boDisableM2SpeedCtrl) and (not boLateDelivery) then begin
    if not CheckActionStatus(wIdent, dwDelayTime) then begin
      m_boFilterAction := False;                                                                  //行动被过滤
      Exit;
    end;
    m_boFilterAction := True;
    dwCheckTime := GetTickCount - m_dwMoveTick;

    if (dwCheckTime < g_Config.dwWalkIntervalTime + m_dwWalkTick) then begin
      if m_dwWalkTick = 0 then
      Inc(m_dwMoveCount);
      dwDelayTime := _Max(0, g_Config.dwWalkIntervalTime - dwCheckTime);
      if dwDelayTime > g_Config.dwWalkIntervalTime div 3 then begin
      if m_dwMoveCount >= 4 then begin
          m_dwMoveTick := GetTickCount();
          m_dwMoveCount := 0;
          dwDelayTime := g_Config.dwWalkIntervalTime div 3;
          if m_boTestSpeedMode then
            SysMsg('走路忙复位!!!' + IntToStr(dwDelayTime), c_Red, t_Hint);
      end else
          m_dwMoveCount := 0;
      Exit;
      end else begin
      if m_boTestSpeedMode then
          SysMsg('走路忙!!!' + IntToStr(dwDelayTime), c_Red, t_Hint);
      Exit;
      end;
    end;
end;
m_dwWalkTick := 0;

m_dwMoveTick := GetTickCount();

m_boMoveSuccess := False;
n18 := m_nCurrX;
n1C := m_nCurrY;
n14 := GetNextDirection(m_nCurrX, m_nCurrY, nX, nY);
//取得走到目标的方向

if WalkTo(n14, False) then begin
    if m_boMoveSuccess or ((m_nCurrX = nX) and (m_nCurrY = nY)) then begin
      Result := True;
      RunStepToDamage(1);
    end;
    Dec(m_nHealthTick, 10);
end else begin
    m_dwMoveCount := 0;
    m_dwMoveCountA := 0;
end;
end;

procedure TPlayObject.CmdAddGold(Cmd: pTGameCmd; sHumName: string; nCount: Integer);                //004CD550
var
PlayObject                            : TPlayObject;
nServerNumber                         : Integer;
begin
if (m_btPermissionGM < 6) then Exit;
if (sHumName = '') or (nCount <= 0) then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称金币数量', c_Red,
      t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumName);
if PlayObject <> nil then begin
    if (PlayObject.m_nGold + nCount) < PlayObject.m_nGoldMax then begin
      Inc(PlayObject.m_nGold, nCount);
    end else begin
      nCount := PlayObject.m_nGoldMax - PlayObject.m_nGold;
      PlayObject.m_nGold := PlayObject.m_nGoldMax;
    end;
    PlayObject.GoldChanged();
    SysMsg(sHumName + '的金币已增加' + IntToStr(nCount) + '.', c_Green, t_Hint);
    if g_boGameLogGold then
      AddGameDataLog('14' + #9 +
      m_sMapName + #9 +
      IntToStr(m_nCurrX) + #9 +
      IntToStr(m_nCurrY) + #9 +
      m_sCharName + #9 +
      sSTRING_GOLDNAME + #9 +
      IntToStr(nCount) + #9 +
      '1' + #9 +
      sHumName);
end else begin
    if UserEngine.FindOtherServerUser(sHumName, nServerNumber) then begin
      SysMsg(sHumName + ' 现在' + IntToStr(nServerNumber) + '号服务器上', c_Green, t_Hint);
    end else begin
      SysMsg(sHumName + ' 现在不在线!!!', c_Green, t_Hint);
    end;
end;
end;

procedure TPlayObject.CmdAddGuild(Cmd: pTGameCmd; sGuildName, sGuildChief:
string);                                                                                          //004CEBA0
var
human                                 : TPlayObject;
boAddState                            : Boolean;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if g_Config.nServerNumber <> 0 then begin
    SysMsg('这个命令只能使用在主服务器上', c_Red, t_Hint);
    Exit;
end;
if (sGuildName = '') or (sGuildChief = '') then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 行会名称 掌门人名称',
      c_Red, t_Hint);
    Exit;
end;

boAddState := False;
human := UserEngine.GetPlayObject(sGuildChief);
if human = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red,
      t_Hint);
    Exit;
end;
if g_GuildManager.MemberOfGuild(sGuildChief) = nil then begin
    if g_GuildManager.AddGuild(sGuildName, sGuildChief) then begin
      UserEngine.SendServerGroupMsg(SS_205, g_Config.nServerNumber, sGuildName + '/' + sGuildChief);
      SysMsg('行会名称: ' + sGuildName + ' 掌门人: ' + sGuildChief, c_Green, t_Hint);
      boAddState := True;
    end;
end;                                                                                              //004CECB4
if boAddState then begin
    human.m_MyGuild := g_GuildManager.MemberOfGuild(human.m_sCharName);
    if human.m_MyGuild <> nil then begin
      human.m_sGuildRankName := TGuild(human.m_MyGuild).GetRankName(Self, human.m_nGuildRankNo);
      human.RefShowName();
    end;
end;                                                                                              //004CED14
end;

procedure TPlayObject.CmdAdjuestExp(Cmd: pTGameCmd; sHumanName, sExp: string);
var
PlayObject                            : TPlayObject;
dwExp                                 : LongWord;
dwOExp                              : LongWord;
resourcestring
sLogMsg                               = '[经验调整] %s(%s %d -> %d)';
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称 经验值', c_Red,
      t_Hint);
    Exit;
end;
dwExp := Str_ToInt(sExp, 0);

PlayObject := UserEngine.GetPlayObject(sHumanName);

if PlayObject <> nil then begin
    dwOExp := PlayObject.m_Abil.Exp;
    PlayObject.m_Abil.Exp := dwExp;
    PlayObject.HasLevelUp(0);
    SysMsg(PlayObject.m_sCharName + ' 经验调整完成。', c_Green, t_Hint);
    if g_Config.boShowMakeItemMsg then
      MainOutMessage(Format(sLogMsg, [m_sCharName, PlayObject.m_sCharName,
      dwOExp, PlayObject.m_Abil.Exp]));
end else begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdAdjuestLevel(Cmd: pTGameCmd; sHumanName: string;
nLevel: Integer);
var
PlayObject                            : TPlayObject;
nOLevel                               : Integer;
resourcestring
sLogMsg                               = '[等级调整] %s(%s %d -> %d)';
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if sHumanName = '' then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称 等级', c_Red,
      t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject <> nil then begin
    nOLevel := PlayObject.m_Abil.level;
    PlayObject.m_Abil.level := _Max(1, _MIN(MAXUPLEVEL, nLevel));
    m_nMagicStatus := GetMagicStatus;
    PlayObject.HasLevelUp(1);
    SysMsg(sHumanName + ' 等级调整完成。', c_Green, t_Hint);
    if g_Config.boShowMakeItemMsg then
      MainOutMessage(Format(sLogMsg, [m_sCharName, PlayObject.m_sCharName,
      nOLevel, PlayObject.m_Abil.level]));
end else begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdAdjustExp(human: TPlayObject; nExp: Integer);                              //004CDDAC
begin
if (m_btPermissionGM < 6) then Exit;
end;

procedure TPlayObject.CmdAllowGroupReCall(sCmd, sParam: string);
begin
if (sParam <> '') and (sParam = '?') then begin
    SysMsg('此命令用于允许或禁止编组传送功能。', c_Red,
      t_Hint);
    Exit;
end;

m_boAllowGroupReCall := not m_boAllowGroupReCall;
if m_boAllowGroupReCall then
    SysMsg(g_sEnableGroupRecall {'[允许天地合一]'}, c_Green, t_Hint)
else SysMsg(g_sDisableGroupRecall {'[禁止天地合一]'}, c_Green, t_Hint);
end;

procedure TPlayObject.CmdAnnouncement(Cmd: pTGameCmd; sGuildName: string);
//004CF564
var
i                                     : Integer;
Guild                                 : TGuild;
//PlayObject:TPlayObject;
sHumanName                            : string;
nPoint                              : Integer;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sGuildName = '') or ((sGuildName <> '') and (sGuildName = '?')) then begin
    SysMsg('查看行会争霸赛结果。', c_Red, t_Hint);
    SysMsg(Format('命令格式: @%s 行会名称', ), c_Red, t_Hint);
    Exit;
end;

if not m_PEnvir.m_MapFlag.boFight3 then begin
    SysMsg('此命令不能在当前地图中使用!!!', c_Red, t_Hint);
    Exit;
end;
Guild := g_GuildManager.FindGuild(sGuildName);
if Guild <> nil then begin
    UserEngine.CryCry(RM_CRY, m_PEnvir, m_nCurrX, m_nCurrY, 1000,
      g_Config.btCryMsgFColor, g_Config.btCryMsgBColor,
      Format(' - %s 行会争霸赛结果: ', ));
    for i := 0 to Guild.TeamFightDeadList.Count - 1 do begin
      nPoint := Integer(Guild.TeamFightDeadList.Objects);
      sHumanName := Guild.TeamFightDeadList.Strings;
      UserEngine.CryCry(RM_CRY,
      m_PEnvir,
      m_nCurrX,
      m_nCurrY,
      1000,
      g_Config.btCryMsgFColor,
      g_Config.btCryMsgBColor,
      Format(' - %s: %d 分/死亡%d次。 ', [sHumanName, HiWord(nPoint),
      LoWord(nPoint)]));
    end;
end;
UserEngine.CryCry(RM_CRY,
    m_PEnvir,
    m_nCurrX,
    m_nCurrY,
    1000,
    g_Config.btCryMsgFColor,
    g_Config.btCryMsgBColor,
    Format(' - [%s] : %d 分。', ));
UserEngine.CryCry(RM_CRY,
    m_PEnvir,
    m_nCurrX,
    m_nCurrY,
    1000,
    g_Config.btCryMsgFColor,
    g_Config.btCryMsgBColor,
    '------------------------------------');
end;

procedure TPlayObject.CmdBackStep(sCmd: string; nType, nCount: Integer);
begin
if (m_btPermissionGM < 6) then Exit;
nType := _MIN(nType, 8);
if nType = 0 then begin
    CharPushed(GetBackDir(m_btDirection), nCount, False);
end else begin
    CharPushed(Random(nType), nCount, False);
end;
end;

procedure TPlayObject.CmdBindGameGold(Cmd: pTGameCmd; sHumanName: string; sCtr: string; nGold: Integer);
var
PlayObject                            : TPlayObject;
Ctr                                 : Char;
resourcestring
sLogMsg                               = '[调整金币] %s 给:%s %s %d 绑定元宝';
begin
Ctr := '1';
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sCtr <> '') then begin
    Ctr := sCtr;
end;

if (sHumanName = '') or not (Ctr in ['=', '+', '-']) or (nGold < 0) or (nGold > 200000000) or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, ), c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
case sCtr of
    '=': begin
      if nGold > g_Config.nHumanMaxGameGold then begin
          SysMsg(sHumanGameGoldLargeThenLimit, c_Red, t_Hint);
          Exit;
      end;
      PlayObject.m_nBindGameGold := nGold;
      end;
    '+': begin
      if nGold + PlayObject.m_nBindGameGold > g_Config.nHumanMaxGameGold then begin
          SysMsg(sHumanGameGoldLargeThenLimit, c_Red, t_Hint);
          Exit;
      end;
      Inc(PlayObject.m_nBindGameGold, nGold);
      end;
    '-': begin
      nGold := _Max(0, PlayObject.m_nBindGameGold - nGold);
      PlayObject.m_nBindGameGold := nGold;
      end;
end;
if g_boGameLogGameGold then begin
    AddGameDataLog(Format(g_sGameLogMsg, [LOG_GAMEGOLD,
      PlayObject.m_sMapName,
      PlayObject.m_nCurrX,
      PlayObject.m_nCurrY,
      PlayObject.m_sCharName,
      '绑定元宝',
      nGold,
      sCtr,
      m_sCharName]));
end;
GameGoldChanged(1);
PlayObject.SysMsg(Format(g_sGameCommandGameGoldHumanMsg, ['绑定元宝', nGold, PlayObject.m_nBindGameGold, '绑定元宝']), c_Green, t_Hint);
SysMsg(Format(g_sGameCommandGameGoldGMMsg, ), c_Green, t_Hint);

if g_Config.boShowMakeItemMsg and (m_btPermissionGM >= 6) then
    MainOutMessage(Format(sLogMsg, , nGold]));
end;

procedure TPlayObject.CmdBindGold(Cmd: pTGameCmd; sHumanName: string; sCtr: string; nGold: Integer);
var
PlayObject                            : TPlayObject;
Ctr                                 : Char;
resourcestring
sLogMsg                               = '[调整金币] %s 给:%s %s %d 绑定金币';
begin
Ctr := '1';
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sCtr <> '') then begin
    Ctr := sCtr;
end;

if (sHumanName = '') or not (Ctr in ['=', '+', '-']) or (nGold < 0) or (nGold > 200000000) or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, ), c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
case sCtr of
    '=': begin
      if nGold > g_Config.nHumanMaxGold then begin
          SysMsg(sHumanGoldLargeThenLimit, c_Red, t_Hint);
          Exit;
      end;
      PlayObject.m_nBindGold := nGold;
      end;
    '+': begin
      if nGold + PlayObject.m_nBindGold > g_Config.nHumanMaxGold then begin
          SysMsg(sHumanGoldLargeThenLimit, c_Red, t_Hint);
          Exit;
      end;
      Inc(PlayObject.m_nBindGold, nGold);
      end;
    '-': begin
      nGold := _Max(0, PlayObject.m_nBindGold - nGold);
      PlayObject.m_nBindGold := nGold;
      end;
end;
if g_boGameLogGold then begin
    AddGameDataLog(Format(g_sGameLogMsg, [LOG_GOLD,
      PlayObject.m_sMapName,
      PlayObject.m_nCurrX,
      PlayObject.m_nCurrY,
      PlayObject.m_sCharName,
      sSTRING_BINDGOLDNAME,
      nGold,
      sCtr,
      m_sCharName]));
end;
GoldChanged(1);
PlayObject.SysMsg(Format(g_sGameCommandGameGoldHumanMsg, ), c_Green, t_Hint);
SysMsg(Format(g_sGameCommandGameGoldGMMsg, ), c_Green, t_Hint);

if g_Config.boShowMakeItemMsg and (m_btPermissionGM >= 6) then
    MainOutMessage(Format(sLogMsg, , nGold]));
end;

procedure TPlayObject.CmdBindUseItem(Cmd: pTGameCmd; sHumanName, sItem,
sType: string);
var
i                                     : Integer;
PlayObject                            : TPlayObject;
UserItem                              : pTUserItem;
nItem, nBind                        : Integer;
ItemBind                              : pTItemBind;
nItemIdx, nMakeIdex                   : Integer;
sBindName                           : string;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
nBind := -1;
nItem := GetUseItemIdx(sItem);
if CompareText(sType, '帐号') = 0 then nBind := 0;
if CompareText(sType, '人物') = 0 then nBind := 1;
if CompareText(sType, 'IP') = 0 then nBind := 2;

if (nItem < 0) or (nBind < 0) or (sHumanName = '') or ((sHumanName <> '') and
    (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandBindUseItemHelpMsg]), c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
UserItem := @PlayObject.m_UseItems;
if UserItem.wIndex = 0 then begin
    SysMsg(Format(g_sGameCommandBindUseItemNoItemMsg, ),
      c_Red, t_Hint);
    Exit;
end;
nItemIdx := UserItem.wIndex;
nMakeIdex := UserItem.MakeIndex;
case nBind of                                                                                     //
    0: begin
      sBindName := PlayObject.m_sUserID;
      for i := 0 to g_ItemBindAccount.Count - 1 do begin
          ItemBind := g_ItemBindAccount.Items;
          if (ItemBind.nItemIdx = nItemIdx) and (ItemBind.nMakeIdex = nMakeIdex) then begin
            SysMsg(Format(g_sGameCommandBindUseItemAlreadBindMsg, [sHumanName,
            sItem]), c_Red, t_Hint);
            Exit;
          end;
      end;
      New(ItemBind);
      ItemBind.nItemIdx := nItemIdx;
      ItemBind.nMakeIdex := nMakeIdex;
      ItemBind.sBindName := sBindName;
      g_ItemBindAccount.Insert(0, ItemBind);
      SaveItemBindAccount();
      SysMsg(Format('%s[%s]IDX[%d]系列号[%d]持久[%d-%d],绑定到%s成功。',
          [GetUseItemName(nItem),
          UserEngine.GetStdItemName(UserItem.wIndex),
            UserItem.wIndex,
            UserItem.MakeIndex,
            UserItem.Dura,
            UserItem.DuraMax,
            sBindName]),
            c_Blue, t_Hint);
      PlayObject.SysMsg(Format('你的%s[%s]已经绑定到%s[%s]上了。',
          [GetUseItemName(nItem),
          UserEngine.GetStdItemName(UserItem.wIndex),
            sType,
            sBindName
            ]), c_Blue, t_Hint);
      end;
    1: begin
      sBindName := PlayObject.m_sCharName;

      for i := 0 to g_ItemBindCharName.Count - 1 do begin
          ItemBind := g_ItemBindCharName.Items;
          if (ItemBind.nItemIdx = nItemIdx) and (ItemBind.nMakeIdex = nMakeIdex) then begin
            SysMsg(Format(g_sGameCommandBindUseItemAlreadBindMsg, [sHumanName,
            sItem]), c_Red, t_Hint);
            Exit;
          end;
      end;
      New(ItemBind);
      ItemBind.nItemIdx := nItemIdx;
      ItemBind.nMakeIdex := nMakeIdex;
      ItemBind.sBindName := sBindName;
      g_ItemBindCharName.Insert(0, ItemBind);

      SaveItemBindCharName();
      SysMsg(Format('%s[%s]IDX[%d]系列号[%d]持久[%d-%d],绑定到%s成功。',
          [GetUseItemName(nItem),
          UserEngine.GetStdItemName(UserItem.wIndex),
            UserItem.wIndex,
            UserItem.MakeIndex,
            UserItem.Dura,
            UserItem.DuraMax,
            sBindName]),
            c_Blue, t_Hint);
      PlayObject.SysMsg(Format('你的%s[%s]已经绑定到%s[%s]上了。',
          [GetUseItemName(nItem),
          UserEngine.GetStdItemName(UserItem.wIndex),
            sType,
            sBindName
            ]), c_Blue, t_Hint);
      end;
    2: begin
      sBindName := PlayObject.m_sIPaddr;
      for i := 0 to g_ItemBindIPaddr.Count - 1 do begin
          ItemBind := g_ItemBindIPaddr.Items;
          if (ItemBind.nItemIdx = nItemIdx) and (ItemBind.nMakeIdex = nMakeIdex) then begin
            SysMsg(Format(g_sGameCommandBindUseItemAlreadBindMsg, ), c_Red, t_Hint);
            Exit;
          end;
      end;
      New(ItemBind);
      ItemBind.nItemIdx := nItemIdx;
      ItemBind.nMakeIdex := nMakeIdex;
      ItemBind.sBindName := sBindName;
      g_ItemBindIPaddr.Insert(0, ItemBind);

      SaveItemBindIPaddr();
      SysMsg(Format('%s[%s]IDX[%d]系列号[%d]持久[%d-%d],绑定到%s成功。',
          [GetUseItemName(nItem),
          UserEngine.GetStdItemName(UserItem.wIndex),
            UserItem.wIndex,
            UserItem.MakeIndex,
            UserItem.Dura,
            UserItem.DuraMax,
            sBindName]),
            c_Blue, t_Hint);
      PlayObject.SysMsg(Format('你的%s[%s]已经绑定到%s[%s]上了。',
          [GetUseItemName(nItem),
          UserEngine.GetStdItemName(UserItem.wIndex),
            sType,
            sBindName
            ]), c_Blue, t_Hint);
      end;
end;
end;

procedure TPlayObject.CmdBonuPoint(Cmd: pTGameCmd; sHumName: string; nCount:
Integer);
var
PlayObject                            : TPlayObject;
sMsg                                  : string;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumName = '') then begin
    SysMsg('命令格式: @' + Cmd.sCmd +
      ' 人物名称 属性点数(不输入为查看点数)', c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
if (nCount > 0) then begin
    PlayObject.m_nBonusPoint := nCount;
    PlayObject.SendMsg(Self, RM_ADJUST_BONUS, 0, 0, 0, 0, '');
    Exit;
end;
sMsg :=
    Format('未分配点数:%d 已分配点数:(DC:%d MC:%d SC:%d AC:%d MAC:%d HP:%d MP:%d HIT:%d SPEED:%d)',
    [PlayObject.m_nBonusPoint,
    PlayObject.m_BonusAbil.DC,
      PlayObject.m_BonusAbil.MC,
      PlayObject.m_BonusAbil.SC,
      PlayObject.m_BonusAbil.AC,
      PlayObject.m_BonusAbil.MAC,
      PlayObject.m_BonusAbil.HP,
      PlayObject.m_BonusAbil.MP,
      PlayObject.m_BonusAbil.Hit,
      PlayObject.m_BonusAbil.Speed
      ]);
SysMsg(Format('%s的属性点数为:%s', ), c_Red, t_Hint);
end;

procedure TPlayObject.CmdChangeAdminMode(sCmd: string; nPermission: Integer;
sParam1: string; boFlag: Boolean);
begin
if (m_btPermissionGM < nPermission) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if ((sParam1 <> '') and (sParam1 = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, ), c_Red, t_Hint);
    Exit;
end;

m_boAdminMode := boFlag;
if m_boAdminMode then SysMsg(sGameMasterMode, c_Green, t_Hint)
else SysMsg(sReleaseGameMasterMode, c_Green, t_Hint);
end;

procedure TPlayObject.CmdChangeAttackMode(nMode: Integer);
var
OldAttatckMode                        : Integer;
begin
if m_PEnvir.m_MapFlag.boNoChAttackMode then begin
    SysMsg(sDisableChangeAttackMode, c_Red, t_Hint);
    Exit;
end;

OldAttatckMode := m_btAttatckMode;
if (nMode >= 0) and (nMode <= 7) then
    m_btAttatckMode := nMode
else begin
{$IF COUNTRYSYSTEM = 1}
    if m_btAttatckMode < HAM_COUNTRY then Inc(m_btAttatckMode)
{$ELSE}
      if m_btAttatckMode < HAM_DEAR then Inc(m_btAttatckMode)
{$IFEND}
      else m_btAttatckMode := HAM_PKATTACK;
end;
while (True) do begin
    if g_Config.boShowAttackModeMsg then Break;
{$IF COUNTRYSYSTEM = 1}
    if m_btAttatckMode < HAM_COUNTRY then Inc(m_btAttatckMode)
{$ELSE}
      if m_btAttatckMode < HAM_DEAR then Inc(m_btAttatckMode)
{$IFEND}
      else m_btAttatckMode := HAM_PKATTACK;
end;
case m_btAttatckMode of
    HAM_PKATTACK: SysMsg(sAttackModeOfRedWhite, c_Green, t_Client);
    //[攻击模式: 红名攻击]
    HAM_ALL: SysMsg(sAttackModeOfAll, c_Green, t_Client);
    //[攻击模式: 全体攻击]
    HAM_PEACE: SysMsg(sAttackModeOfPeaceful, c_Green, t_Client);
    //[攻击模式: 和平攻击]
    HAM_DEAR: SysMsg(sAttackModeOfDear, c_Green, t_Client);
    //[攻击模式: 夫妻攻击]
    HAM_MASTER: SysMsg(sAttackModeOfMaster, c_Green, t_Client);
    //[攻击模式: 师徒攻击]
    HAM_GROUP: SysMsg(sAttackModeOfGroup, c_Green, t_Client);
    //[攻击模式: 编组攻击]
    HAM_GUILD: SysMsg(sAttackModeOfGuild, c_Green, t_Client);
    //[攻击模式: 行会攻击]
{$IF COUNTRYSYSTEM = 1}
    HAM_COUNTRY: if g_Config.boShowAttackModeMsg then
      SysMsg(sAttackModeOfCountry, c_Green, t_Client);
    //[攻击模式:国家攻击]
{$IFEND}
end;
//元神的攻击模式和主人相同
if not m_boPneuma and (m_PneumaObject <> nil) then
    m_PneumaObject.m_btAttatckMode := m_btAttatckMode;
end;

procedure TPlayObject.CmdChangeDearName(Cmd: pTGameCmd; sHumanName, sDearName:
string);
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or (sDearName = '') then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称 配偶名称(如果为 无 则清除)', c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject <> nil then begin
    if CompareText(sDearName, '无') = 0 then begin
      PlayObject.m_sDearName := '';
      PlayObject.RefShowName;
      if g_Config.boShowScriptActionMsg then
      SysMsg(sHumanName + ' 的配偶名清除成功。', c_Green, t_Hint);
    end else begin
      PlayObject.m_sDearName := sDearName;
      PlayObject.RefShowName;
      if g_Config.boShowScriptActionMsg then
      SysMsg(sHumanName + ' 的配偶名更改成功。', c_Green, t_Hint);
    end;
end else begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
end;
end;

//改性别

procedure TPlayObject.CmdChangeGender(Cmd: pTGameCmd; sHumanName, sSex: string);
var
PlayObject                            : TPlayObject;
nSex                                  : Integer;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
nSex := -1;
if (sSex = 'Man') or (sSex = '男') or (sSex = '0') then begin
    nSex := 0;
end;
if (sSex = 'WoMan') or (sSex = '女') or (sSex = '1') then begin
    nSex := 1;
end;
if (sHumanName = '') or (nSex = -1) then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称 性别(男、女)',
      c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject <> nil then begin
    if PlayObject.m_btGender <> nSex then begin
      PlayObject.m_btGender := nSex;
      PlayObject.FeatureChanged();
      SysMsg(PlayObject.m_sCharName + ' 的性别已改变。', c_Green, t_Hint);
    end else begin
      SysMsg(PlayObject.m_sCharName + ' 的性别未改变!!!', c_Red, t_Hint);
    end;
end else begin
    SysMsg(sHumanName + '没有在线!!!', c_Red, t_Hint);
end;
end;

//自定义物品名字

procedure TPlayObject.CmdChangeItemName(sCmd, sMakeIndex, sItemIndex, sItemName:
string);
var
nMakeIndex, nItemIndex                : Integer;
begin
if (m_btPermissionGM < 6) then Exit;
if (sMakeIndex = '') or (sItemIndex = '') or (sItemName = '') then begin
    SysMsg('命令格式: @' + sCmd + ' 物品编号 物品ID号 物品名称', c_Red, t_Hint);
    Exit;
end;
nMakeIndex := Str_ToInt(sMakeIndex, -1);
nItemIndex := Str_ToInt(sItemIndex, -1);
if (nMakeIndex <= 0) or (nItemIndex < 0) then begin
    SysMsg('命令格式: @' + sCmd + ' 物品编号 物品ID号 物品名称', c_Red, t_Hint);
    Exit;
end;
if ItemUnit.AddCustomItemName(nMakeIndex, nItemIndex, sItemName) then begin
    ItemUnit.SaveCustomItemName();
    SysMsg('物品名称设置成功。', c_Green, t_Hint);
    Exit;
end;

SysMsg('此物品,已经设置了其它的名称!!!', c_Red, t_Hint);
end;

//改变职业

procedure TPlayObject.CmdChangeJob(Cmd: pTGameCmd; sHumanName, sJobName: string);
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;

if (sHumanName = '') or (sJobName = '') then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandChangeJobHelpMsg]), c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject <> nil then begin
    if CompareText(sJobName, 'Warr') = 0 then PlayObject.m_btJob := 0;
    if CompareText(sJobName, 'Wizard') = 0 then PlayObject.m_btJob := 1;
    if CompareText(sJobName, 'Taos') = 0 then PlayObject.m_btJob := 2;
    if CompareText(sJobName, 'Goblin') = 0 then PlayObject.m_btJob := 3;
    PlayObject.HasLevelUp(0);
    PlayObject.SysMsg(g_sGameCommandChangeJobHumanMsg, c_Green, t_Hint);
    SysMsg(Format(g_sGameCommandChangeJobMsg, ), c_Green, t_Hint);
    if not m_boPneuma then begin
      PlayObject.SendUpdateDelayMsg(PlayObject, RM_REFRESHRANK, 0, 0, 0, 0, '', 1000);
      PlayObject.SendUpdateDelayMsg(PlayObject, RM_REFRESHRANK, 0, 5, 0, 0, '', 1000);
    end else begin
      PlayObject.SendUpdateDelayMsg(PlayObject, RM_REFRESHRANK, 0, 1, 0, 0, '', 1000);
    end;
end else begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
end;
end;

//修改等级

procedure TPlayObject.CmdChangeLevel(Cmd: pTGameCmd; sParam1: string);
var
nOLevel                               : Integer;
nLevel                              : Integer;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if ((sParam1 <> '') and (sParam1 = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, ), c_Red, t_Hint);
    Exit;
end;
nLevel := Str_ToInt(sParam1, 1);
nOLevel := m_Abil.level;

m_Abil.level := _MIN(MAXUPLEVEL, nLevel);
HasLevelUp(m_Abil.level - 1);
if g_Config.boShowMakeItemMsg then begin
    MainOutMessage(Format(g_sGameCommandLevelConsoleMsg, [m_sCharName, nOLevel,
      m_Abil.level]));
end;
end;

procedure TPlayObject.CmdChangeMasterName(Cmd: pTGameCmd; sHumanName,
sMasterName, sIsMaster: string);
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or (sMasterName = '') then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称 师徒名称(如果为 无 则清除)', c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject <> nil then begin
    ChangeMasterName(sHumanName, sMasterName, sIsMaster = '1');
    if g_Config.boShowScriptActionMsg then
      SysMsg(sHumanName + ' 的师徒名更改成功。', c_Green, t_Hint);
end else begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdChangeObMode(sCmd: string; nPermission: Integer;
sParam1: string; boFlag: Boolean);
begin
if (m_btPermissionGM < nPermission) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if ((sParam1 <> '') and (sParam1 = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, ), c_Red, t_Hint);
    Exit;
end;
if boFlag then begin
    SendRefMsg(RM_DISAPPEAR, 0, 0, 0, 0, '');
    //01/21 强行发送刷新数据到客户端,解决GM登录隐身有影子问题
end;
m_boObMode := boFlag;
if m_boObMode then
    SysMsg(sObserverMode, c_Green, t_Hint)
else
    SysMsg(g_sReleaseObserverMode, c_Green, t_Hint);
end;

procedure TPlayObject.CmdChangeSabukLord(Cmd: pTGameCmd; sCASTLENAME,
sGuildName: string; boFlag: Boolean);                                                             //004CFE1C
var
Guild                                 : TGuild;
Castle                              : TUserCastle;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;

if (sCASTLENAME = '') or (sGuildName = '') then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 城堡名称 行会名称', c_Red, t_Hint);
    Exit;
end;
Castle := g_CastleManager.Find(sCASTLENAME);
if Castle = nil then begin
    SysMsg(Format(g_sGameCommandSbkGoldCastleNotFoundMsg, ), c_Red, t_Hint);
    Exit;
end;

Guild := g_GuildManager.FindGuild(sGuildName);
if Guild <> nil then begin
    //4CFEC7
    AddGameDataLog('27' + #9 +
      Castle.m_sOwnGuild + #9 +
      '0' + #9 +
      '1' + #9 +
      'sGuildName' + #9 +
      m_sCharName + #9 +
      '0' + #9 +
      '1' + #9 +
      '0');
    Castle.GetCastle(Guild);
    if boFlag then
      UserEngine.SendServerGroupMsg(SS_211, g_Config.nServerNumber, sGuildName);
    SysMsg(Castle.m_sName + ' 所属行会已经更改为 ' + sGuildName,
      c_Green, t_Hint);
end else begin
    SysMsg('行会 ' + sGuildName + '还没建立!!!', c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdChangeSalveStatus;
var
i, nCount                           : Integer;
begin
nCount := 0;
if m_SlaveList.Count > 0 then begin
    m_boSlaveRelax := not m_boSlaveRelax;
    if (m_TorDDM.Tiger.DB.Dragon > 0) then m_boTigerRelax := m_boSlaveRelax;

    if m_PneumaObject <> nil then
      m_PneumaObject.m_boSlaveRelax := m_boSlaveRelax;

    for i := 0 to m_SlaveList.Count - 1 do begin
      if TBaseObject(m_SlaveList).IsTiger and (m_TorDDM.Tiger.DB.Dragon = 0) then Continue;

      TBaseObject(m_SlaveList).m_boSlaveRelax := m_boSlaveRelax;
      if m_boSlaveRelax then
      TBaseObject(m_SlaveList).DelTargetCreat;

      Inc(nCount);
    end;
end else if (m_PneumaObject <> nil) and (m_PneumaObject.m_SlaveList.Count > 0) then begin
    m_boSlaveRelax := not m_boSlaveRelax;
    m_PneumaObject.m_boSlaveRelax := m_boSlaveRelax;
    for i := 0 to m_PneumaObject.m_SlaveList.Count - 1 do begin
      if TBaseObject(m_PneumaObject.m_SlaveList).IsTiger then Continue;

      TBaseObject(m_PneumaObject.m_SlaveList).m_boSlaveRelax := m_boSlaveRelax;
      if m_boSlaveRelax then
      TBaseObject(m_PneumaObject.m_SlaveList).DelTargetCreat;

      Inc(nCount);
    end;
end;
if nCount > 0 then begin
    if m_boSlaveRelax then
      SysMsg(sPetRest, c_Green, t_Hint)
    else
      SysMsg(sPetAttack, c_Green, t_Hint);
end;
end;

procedure TPlayObject.CmdChangeSuperManMode(sCmd: string; nPermission: Integer;
sParam1: string; boFlag: Boolean);
begin
if (m_btPermissionGM < nPermission) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if ((sParam1 <> '') and (sParam1 = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, ), c_Red, t_Hint);
    Exit;
end;
m_boSuperMan := boFlag;
if m_boSuperMan then SysMsg(sSupermanMode, c_Green, t_Hint)
else SysMsg(sReleaseSupermanMode, c_Green, t_Hint);
end;

procedure TPlayObject.CmdChangeTigerStatus;
begin
if (m_Tiger <> nil) and (not m_Tiger.m_boDeath) and (not m_Tiger.m_boGhost) and (m_TorDDM.Tiger.DB.Dragon = 0) then begin
    m_boTigerRelax := not m_boTigerRelax;
    if m_boTigerRelax then begin
      SysMsg('虎王休息', c_Green, t_Hint);
      SendDefMessage(SM_TIGERSTATUS, 0, 0, 0, 0, '');
      m_Tiger.DelTargetCreat;
    end else begin
      SysMsg('虎王攻击', c_Green, t_Hint);
      SendDefMessage(SM_TIGERSTATUS, 0, 1, 0, 0, '');
    end;
    m_Tiger.m_boTigerRelax := m_boTigerRelax;
end;
end;

procedure TPlayObject.CmdChangeUserFull(sCmd, sUserCount: string);
var
nCount                              : Integer;
begin
if (m_btPermissionGM < 6) then Exit;
nCount := Str_ToInt(sUserCount, -1);
if (sUserCount = '') or (nCount < 1) or ((sUserCount <> '') and (sUserCount
    = '?')) then begin
    SysMsg('设置服务器最高上线人数。', c_Red, t_Hint);
    SysMsg('命令格式: @' + sCmd + ' 人数', c_Red, t_Hint);
    Exit;
end;
g_Config.nUserFull := nCount;
SysMsg(Format('服务器上线人数限制: %d', ), c_Green, t_Hint);
end;

procedure TPlayObject.CmdChangeZenFastStep(sCmd, sFastStep: string);
var
nFastStep                           : Integer;
begin
if (m_btPermissionGM < 6) then Exit;
nFastStep := Str_ToInt(sFastStep, -1);
if (sFastStep = '') or (nFastStep < 1) or ((sFastStep <> '') and (sFastStep
    = '?')) then begin
    SysMsg('设置怪物行动速度。', c_Red, t_Hint);
    SysMsg('命令格式: @' + sCmd + ' 速度', c_Red, t_Hint);
    Exit;
end;
g_Config.nZenFastStep := nFastStep;
SysMsg(Format('怪物行动速度: %d', ), c_Green, t_Hint);
end;

procedure TPlayObject.CmdClearBagItem(Cmd: pTGameCmd; sHumanName: string);
var
i                                     : Integer;
PlayObject                            : TPlayObject;
UserItem                              : pTUserItem;
DelList                               : TStringList;
begin
DelList := nil;
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, ), c_Red,
      t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;

for i := 0 to PlayObject.m_ItemList.Count - 1 do begin
    UserItem := PlayObject.m_ItemList.Items;
    //if DelList = nil then DelList := TStringList.Create;
    //DelList.AddObject(UserEngine.GetStdItemName(UserItem.wIndex), TObject(UserItem.MakeIndex));
    SendDelItems(UserItem);
    Dispose(UserItem);
end;
PlayObject.m_ItemList.Clear;
WeightChanged;
//if DelList <> nil then begin
//    PlayObject.SendMsg(PlayObject, RM_SENDDELITEMLIST, 0, Integer(DelList), 0, 0, '');
//end;
end;

procedure TPlayObject.CmdClearHumanPassword(sCmd: string; nPermission: Integer;
sHumanName: string);
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < nPermission) then Exit;
if (sHumanName = '') or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg('清除玩家的仓库密码!!!', c_Red, t_Hint);
    SysMsg(Format('命令格式: @%s 人物名称', ), c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    Exit;
end;
PlayObject.m_boPasswordLocked := False;
PlayObject.m_boUnLockStoragePwd := False;
PlayObject.m_sStoragePwd := '';
PlayObject.SysMsg('你的保护密码已被清除!!!', c_Green, t_Hint);
SysMsg(Format('%s的保护密码已被清除!!!', ),
    c_Green, t_Hint);
end;

procedure TPlayObject.CmdClearMapMonster(Cmd: pTGameCmd; sMapName, sMonName,
sItems, sGhost: string);
var
i, ii                                 : Integer;
MonList                               : TList;
Envir                                 : TEnvirnoment;
nMonCount                           : Integer;
boKillAll                           : Boolean;
boKillAllMap                        : Boolean;
boNotItem                           : Boolean;
boMakeGhost                           : Boolean;
BaseObject                            : TBaseObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sMapName = '') or (sMonName = '') or (sItems = '') then begin
    SysMsg('命令格式: @' + Cmd.sCmd +
      ' 地图号(* 为所有) 怪物名称(* 为所有) 掉物品(0,1) 清理尸体(0,1)',
      c_Red, t_Hint);
    Exit;
end;
boKillAll := False;
boKillAllMap := False;
boNotItem := True;
boMakeGhost := False;
nMonCount := 0;
Envir := nil;
if sMonName = '*' then boKillAll := True;
if sMapName = '*' then boKillAllMap := True;
if sItems = '1' then boNotItem := False;
if sGhost = '1' then boMakeGhost := True;

MonList := TList.Create;
if boKillAllMap then begin
    for i := 0 to g_MapManager.Count - 1 do begin
      Envir := TEnvirnoment(g_MapManager.Values]);
      if (Envir <> nil) then begin
      MonList.Clear;
      UserEngine.GetMapMonster(Envir, MonList);
      for ii := 0 to MonList.Count - 1 do begin
          BaseObject := TBaseObject(MonList.Items);
          if boKillAll or (CompareText(sMonName, BaseObject.m_sCharName) = 0) then begin
            BaseObject.m_nHealthTick := 0;
            BaseObject.m_boNoItem := boNotItem;
            if boMakeGhost then BaseObject.MakeGhost else BaseObject.Die;
            Inc(nMonCount);
          end;
      end;
      end;
    end;
end else begin
    Envir := g_MapManager.FindMap(sMapName);
    if (Envir <> nil) then begin
      MonList.Clear;
      UserEngine.GetMapMonster(Envir, MonList);
      for ii := 0 to MonList.Count - 1 do begin
      BaseObject := TBaseObject(MonList.Items);
      if boKillAll or (CompareText(sMonName, BaseObject.m_sCharName) = 0) then begin
          BaseObject.m_nHealthTick := 0;
          BaseObject.m_boNoItem := boNotItem;
          if boMakeGhost then BaseObject.MakeGhost else BaseObject.Die;
          Inc(nMonCount);
      end;
      end;
    end;
end;
MonList.free;
if Envir = nil then begin
    SysMsg('输入的地图不存在!!!', c_Red, t_Hint);
    Exit;
end;

SysMsg('已清除怪物数: ' + IntToStr(nMonCount), c_Red, t_Hint);
end;

procedure TPlayObject.CmdClearMission(Cmd: pTGameCmd; sHumanName: string);
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称)', c_Red, t_Hint);
    Exit;
end;
if sHumanName = '?' then begin
    SysMsg('此命令用于清除人物的任务标志。', c_Blue, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format('%s不在线,或在其它服务器上!!', ),
      c_Red, t_Hint);
    Exit;
end;
FillChar(PlayObject.m_QuestFlag, SizeOf(TQuestFlag), #0);
SysMsg(Format('%s的任务标志已经全部清零。', ),
    c_Green, t_Hint);
end;

procedure TPlayObject.CmdContestPoint(Cmd: pTGameCmd; sGuildName: string);
//004CEF08
var
//I: Integer;
Guild                                 : TGuild;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sGuildName = '') or ((sGuildName <> '') and (sGuildName = '?')) then begin
    SysMsg('查看行会战的得分数。', c_Red, t_Hint);
    SysMsg(Format('命令格式: @%s 行会名称', ), c_Red, t_Hint);
    Exit;
end;
Guild := g_GuildManager.FindGuild(sGuildName);
if Guild <> nil then begin
    SysMsg(Format('%s 的得分为: %d', ),
      c_Green, t_Hint);
end else begin
    SysMsg(Format('行会: %s 不存在!!!', ), c_Green,
      t_Hint);
end;
end;

procedure TPlayObject.CmdCreditPoint(Cmd: pTGameCmd; sHumanName, sCtr: string;
nPoint: Integer);
var
PlayObject                            : TPlayObject;
Ctr                                 : Char;
nCreditPoint                        : Integer;
begin
Ctr := '1';
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sCtr <> '') then begin
    Ctr := sCtr;
end;

if (sHumanName = '') or not (Ctr in ['=', '+', '-']) or (nPoint < 0) or (nPoint > High(byte)) or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandCreditPointHelpMsg]), c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
case sCtr of
    '=': begin
      PlayObject.m_wCreditPoint := nPoint;
      end;
    '+': begin
      if (PlayObject.m_wCreditPoint + nPoint) > High(word) then
          PlayObject.m_wCreditPoint := High(word)
      else
          PlayObject.m_wCreditPoint := PlayObject.m_wCreditPoint + nPoint;
      end;
    '-': begin
      if (PlayObject.m_wCreditPoint - nPoint) < 0 then
          PlayObject.m_wCreditPoint := 0
      else
          PlayObject.m_wCreditPoint := PlayObject.m_wCreditPoint - nPoint;
      end;
end;

PlayObject.SendUpdateMsg(PlayObject, RM_SUBABILITY, 0, 0, 0, 0, '');

PlayObject.SysMsg(Format(g_sGameCommandCreditPointHumanMsg, ), c_Green, t_Hint);
SysMsg(Format(g_sGameCommandCreditPointGMMsg, [sHumanName, nPoint,
    PlayObject.m_wCreditPoint]), c_Green, t_Hint);
end;

procedure TPlayObject.CmdDearRecall(sCmd, sParam: string);
begin
if (sParam <> '') and (sParam = '?') then begin
    SysMsg('命令格式: @' + sCmd +
      ' (夫妻传送,将对方传送到自己身边,对方必须允许传送。)',
      c_Green, t_Hint);
    Exit;
end;
if m_sDearName = '' then begin
    SysMsg('你没有结婚!!!', c_Red, t_Hint);
    Exit;
end;
if m_PEnvir.m_MapFlag.boNODEARRECALL then begin
    SysMsg('本地图禁止夫妻传送!!!', c_Red, t_Hint);
    Exit;
end;

if (m_DearHuman = nil) or m_DearHuman.m_boGhost or m_DearHuman.m_boDeath then begin
    if m_btGender = 0 then begin
      SysMsg('你的老婆不在线!!!', c_Red, t_Hint);
    end else begin
      SysMsg('你的老公不在线!!!', c_Red, t_Hint);
    end;
    Exit;
end;
if GetTickCount - m_dwDearRecallTick < 10000 then begin
    SysMsg('稍等会儿才能再次使用此功能!!!', c_Red, t_Hint);
    Exit;
end;
if m_boArrow then begin
    SysMsg('您正在执行任务,目前无法使用此功能!!!',
      c_Red, t_Hint);
    Exit;
end;

m_dwDearRecallTick := GetTickCount();
if m_DearHuman.m_boCanDearRecall then begin
    RecallHuman(m_DearHuman.m_sCharName, $20);
    SendRefMsg(RM_510, 1, 0, $20, 0, '');
    m_DearHuman.SendDelayMsg(Self, RM_510, 1, 0, $20, 0, '', 100);
end else begin
    SysMsg(m_DearHuman.m_sCharName + ' 不允许传送!!!', c_Red,
      t_Hint);
    Exit;
end;

end;

procedure TPlayObject.CmdDelBonuPoint(Cmd: pTGameCmd; sHumName: string);
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if sHumName = '' then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称', c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumName);
if PlayObject <> nil then begin
    FillChar(PlayObject.m_BonusAbil, SizeOf(TNakedAbility), #0);
    PlayObject.m_nBonusPoint := 0;
    PlayObject.SendMsg(PlayObject, RM_ADJUST_BONUS, 0, 0, 0, 0, '');
    PlayObject.HasLevelUp(0);
    PlayObject.SysMsg('分配点数已清除!!!', c_Red, t_Hint);
    SysMsg(sHumName + ' 的分配点数已清除.', c_Green, t_Hint);
end else begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdDelDenyAccountLogon(Cmd: pTGameCmd; sAccount,
sFixDeny: string);
var
i                                     : Integer;
boDelete                              : Boolean;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if sAccount = '' then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 登录帐号', c_Red, t_Hint);
    Exit;
end;
boDelete := False;
g_DenyAccountList.Lock;
try
    for i := g_DenyAccountList.Count - 1 downto 0 do begin
      if CompareText(sAccount, g_DenyAccountList.Strings) = 0 then begin
      if Integer(g_DenyAccountList.Objects) <> 0 then
          SaveDenyAccountList;
      g_DenyAccountList.Delete(i);
      SysMsg(sAccount + '已从禁止登录帐号列表中删除。', c_Green,
          t_Hint);
      boDelete := True;
      Break;
      end;
    end;
finally
    g_DenyAccountList.UnLock;
end;
if not boDelete then
    SysMsg(sAccount + '没有被禁止登录。', c_Green, t_Hint);
end;

procedure TPlayObject.CmdDelDenyCharNameLogon(Cmd: pTGameCmd; sCharName,
sFixDeny: string);
var
i                                     : Integer;
boDelete                              : Boolean;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if sCharName = '' then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称', c_Red, t_Hint);
    Exit;
end;
boDelete := False;
g_DenyChrNameList.Lock;
try
    for i := g_DenyChrNameList.Count - 1 downto 0 do begin
      if CompareText(sCharName, g_DenyChrNameList.Strings) = 0 then begin
      if Integer(g_DenyChrNameList.Objects) <> 0 then
          SaveDenyChrNameList;
      g_DenyChrNameList.Delete(i);
      SysMsg(sCharName + '已从禁止登录人物列表中删除。',
          c_Green, t_Hint);
      boDelete := True;
      Break;
      end;
    end;
finally
    g_DenyChrNameList.UnLock;
end;
if not boDelete then
    SysMsg(sCharName + '没有被禁止登录。', c_Green, t_Hint);
end;

procedure TPlayObject.CmdDelDenyIPaddrLogon(Cmd: pTGameCmd; sIPaddr,
sFixDeny: string);
var
i                                     : Integer;
boDelete                              : Boolean;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if sIPaddr = '' then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' IP地址', c_Red, t_Hint);
    Exit;
end;
boDelete := False;
g_DenyIPAddrList.Lock;
try
    for i := g_DenyIPAddrList.Count - 1 downto 0 do begin
      if CompareText(sIPaddr, g_DenyIPAddrList.Strings) = 0 then begin
      if Integer(g_DenyIPAddrList.Objects) <> 0 then
          SaveDenyIPAddrList;
      g_DenyIPAddrList.Delete(i);
      SysMsg(sIPaddr + '已从禁止登录IP列表中删除。', c_Green,
          t_Hint);
      boDelete := True;
      Break;
      end;
    end;
finally
    g_DenyIPAddrList.UnLock;
end;
if not boDelete then
    SysMsg(sIPaddr + '没有被禁止登录。', c_Green, t_Hint);
end;

procedure TPlayObject.CmdDeleteItem(Cmd: pTGameCmd; sHumanName, sItemName:
string; nCount: Integer);                                                                         //004CDFF8
var
i                                     : Integer;
PlayObject                            : TPlayObject;
nItemCount                            : Integer;
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or (sItemName = '') then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称 物品名称 数量)',
      c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
nItemCount := 0;
for i := PlayObject.m_ItemList.Count - 1 downto 0 do begin
    UserItem := PlayObject.m_ItemList.Items;
    StdItem := UserEngine.GetStdItem(UserItem.wIndex);
    if (StdItem <> nil) and (CompareText(sItemName, StdItem.Name) = 0) then begin
      PlayObject.SendDelItems(UserItem);
      Dispose(UserItem);
      PlayObject.m_ItemList.Delete(i);
      Inc(nItemCount);
      if nItemCount >= nCount then Break;
    end;
end;
end;

procedure TPlayObject.CmdDelGold(Cmd: pTGameCmd; sHumName: string; nCount:
Integer);                                                                                       //004CD27C
var
PlayObject                            : TPlayObject;
nServerNumber                         : Integer;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumName = '') or (nCount <= 0) then Exit;
PlayObject := UserEngine.GetPlayObject(sHumName);
if PlayObject <> nil then begin
    if PlayObject.m_nGold > nCount then begin
      Dec(PlayObject.m_nGold, nCount);
    end else begin
      nCount := PlayObject.m_nGold;
      PlayObject.m_nGold := 0;
    end;
    PlayObject.GoldChanged();
    SysMsg(sHumName + '的金币已减少' + IntToStr(nCount) + '.', c_Green, t_Hint);

    if g_boGameLogGold then
      AddGameDataLog('5' + #9 +
      m_sMapName + #9 +
      IntToStr(m_nCurrX) + #9 +
      IntToStr(m_nCurrY) + #9 +
      m_sCharName + #9 +
      sSTRING_GOLDNAME + #9 +
      IntToStr(nCount) + #9 +
      '1' + #9 +
      sHumName);
end else begin
    if UserEngine.FindOtherServerUser(sHumName, nServerNumber) then begin
      SysMsg(sHumName + '现在' + IntToStr(nServerNumber) + '号服务器上', c_Green, t_Hint);
    end else begin
      SysMsg(sHumName + '现在不在线!!!', c_Green, t_Hint);
    end;
end;
end;

procedure TPlayObject.CmdDelGuild(Cmd: pTGameCmd; sGuildName: string);                              //004CEDEC
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if g_Config.nServerNumber <> 0 then begin
    SysMsg('只能在主服务器上才可以使用此命令删除行会!!!', c_Red, t_Hint);
    Exit;
end;
if sGuildName = '' then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 行会名称', c_Red, t_Hint);
    Exit;
end;
if g_GuildManager.DelGuild(sGuildName) then begin
    UserEngine.SendServerGroupMsg(SS_206, g_Config.nServerNumber, sGuildName);
end else begin
    SysMsg('没找到' + sGuildName + '这个行会!!!', c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdDelNpc(sCmd: string; nPermission: Integer; sParam1:
string);
var
BaseObject                            : TBaseObject;
i                                     : Integer;
resourcestring
sDelOK                              = '删除NPC成功...';
begin
if (m_btPermissionGM < nPermission) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if ((sParam1 <> '') and (sParam1 = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, ), c_Red, t_Hint);
    Exit;
end;
BaseObject := GetPoseCreate();
if BaseObject <> nil then begin
    for i := 0 to UserEngine.m_MerchantList.Count - 1 do begin
      if TBaseObject(UserEngine.m_MerchantList.Items) = BaseObject then begin
      BaseObject.m_boGhost := True;
      BaseObject.m_dwGhostTick := GetTickCount();
      BaseObject.SendRefMsg(RM_DISAPPEAR, 0, 0, 0, 0, '');
      SysMsg(sDelOK, c_Red, t_Hint);
      Exit;
      end;
    end;
    for i := 0 to UserEngine.QuestNPCList.Count - 1 do begin
      if TBaseObject(UserEngine.QuestNPCList.Items) = BaseObject then begin
      BaseObject.m_boGhost := True;
      BaseObject.m_dwGhostTick := GetTickCount();
      BaseObject.SendRefMsg(RM_DISAPPEAR, 0, 0, 0, 0, '');
      SysMsg(sDelOK, c_Red, t_Hint);
      Exit;
      end;
    end;
end;
SysMsg(g_sGameCommandDelNpcMsg, c_Red, t_Hint);
end;

procedure TPlayObject.CmdDelSkill(Cmd: pTGameCmd; sHumanName, sSkillName:
string);
var
i                                     : Integer;
PlayObject                            : TPlayObject;
boDelAll                              : Boolean;
UserMagic                           : pTUserMagic;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or (sSkillName = '') then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称 技能名称)', c_Red,
      t_Hint);
    Exit;
end;
if CompareText(sSkillName, 'All') = 0 then boDelAll := True
else boDelAll := False;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;

if boDelAll then begin
    for i := PlayObject.m_MagicList.Count - 1 downto 0 do begin
      UserMagic := PlayObject.m_MagicList.Items;
      if UserMagic.btType = MAG_STUDY then begin
      PlayObject.SendDelMagic(UserMagic);
      PlayObject.m_MagicList.Delete(i);
      Dispose(UserMagic);
      end;
    end;
end else begin
    if PlayObject.DelItemSkill(sSkillName) then begin
      PlayObject.SysMsg(Format('技能%s已删除。', ), c_Green, t_Hint);
      SysMsg(Format('%s的技能%s已删除。', ), c_Green, t_Hint);
    end;
end;

PlayObject.RecalcHitSpeed;
RecalcAbilitys();
SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
SendUpdateMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
end;

procedure TPlayObject.CmdDenyAccountLogon(Cmd: pTGameCmd; sAccount, sFixDeny:
string);
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if sAccount = '' then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 登录帐号 是否永久封(0,1)',
      c_Red, t_Hint);
    Exit;
end;
g_DenyAccountList.Lock;
try
    if (sFixDeny <> '') and (sFixDeny = '1') then begin
      g_DenyAccountList.AddObject(sAccount, TObject(1));
      SaveDenyAccountList();
      SysMsg(sAccount + '已加入禁止登录帐号列表', c_Green, t_Hint);
    end else begin
      g_DenyAccountList.AddObject(sAccount, TObject(0));
      SysMsg(sAccount + '已加入临时禁止登录帐号列表', c_Green,
      t_Hint);
    end;
finally
    g_DenyAccountList.UnLock;
end;
end;

procedure TPlayObject.CmdDenyCharNameLogon(Cmd: pTGameCmd; sCharName, sFixDeny:
string);
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if sCharName = '' then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称 是否永久封(0,1)',
      c_Red, t_Hint);
    Exit;
end;
g_DenyChrNameList.Lock;
try
    if (sFixDeny <> '') and (sFixDeny = '1') then begin
      g_DenyChrNameList.AddObject(sCharName, TObject(1));
      SaveDenyChrNameList();
      SysMsg(sCharName + '已加入禁止人物列表', c_Green, t_Hint);
    end else begin
      g_DenyChrNameList.AddObject(sCharName, TObject(0));
      SysMsg(sCharName + '已加入临时禁止人物列表', c_Green, t_Hint);
    end;
finally
    g_DenyChrNameList.UnLock;
end;
end;

procedure TPlayObject.CmdDenyIPaddrLogon(Cmd: pTGameCmd; sIPaddr, sFixDeny:
string);
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if sIPaddr = '' then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' IP地址 是否永久封(0,1)',
      c_Red, t_Hint);
    Exit;
end;
g_DenyIPAddrList.Lock;
try
    if (sFixDeny <> '') and (sFixDeny = '1') then begin
      g_DenyIPAddrList.AddObject(sIPaddr, TObject(1));
      SaveDenyIPAddrList();
      SysMsg(sIPaddr + '已加入禁止登录IP列表', c_Green, t_Hint);
    end else begin
      g_DenyIPAddrList.AddObject(sIPaddr, TObject(0));
      SysMsg(sIPaddr + '已加入临时禁止登录IP列表', c_Green, t_Hint);
    end;
finally
    g_DenyIPAddrList.UnLock;
end;
end;

procedure TPlayObject.CmdDisableFilter(sCmd, sParam1: string);
begin
if (m_btPermissionGM < 6) then Exit;
if (sParam1 <> '') and (sParam1 = '?') then begin
    SysMsg('启用/禁止文字过滤功能。', c_Red, t_Hint);
    Exit;
end;
boFilterWord := not boFilterWord;
if boFilterWord then begin
    SysMsg('已启用文字过滤。', c_Green, t_Hint);
end else begin
    SysMsg('已禁止文字过滤。', c_Green, t_Hint);
end;
end;

procedure TPlayObject.CmdDisableSendMsg(Cmd: pTGameCmd; sHumanName: string);
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if sHumanName = '' then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称', c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject <> nil then begin
    PlayObject.m_boFilterSendMsg := True;
end;
g_DisableSendMsgList.Add(sHumanName);
SaveDisableSendMsgList();
SysMsg(sHumanName + ' 已加入禁言列表。', c_Green, t_Hint);
end;

procedure TPlayObject.CmdDisableSendMsgList(Cmd: pTGameCmd);
var
i                                     : Integer;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if g_DisableSendMsgList.Count <= 0 then begin
    SysMsg('禁言列表为空!!!', c_Red, t_Hint);
    Exit;
end;

SysMsg('禁言列表:', c_Blue, t_Hint);
for i := 0 to g_DisableSendMsgList.Count - 1 do begin
    SysMsg(g_DisableSendMsgList.Strings, c_Green, t_Hint);
end;
end;

procedure TPlayObject.CmdEnableSendMsg(Cmd: pTGameCmd; sHumanName: string);
var
i                                     : Integer;
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if sHumanName = '' then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称', c_Red, t_Hint);
    Exit;
end;
for i := g_DisableSendMsgList.Count - 1 downto 0 do begin
    if CompareText(sHumanName, g_DisableSendMsgList.Strings) = 0 then begin
      PlayObject := UserEngine.GetPlayObject(sHumanName);
      if PlayObject <> nil then begin
      PlayObject.m_boFilterSendMsg := False;
      end;
      g_DisableSendMsgList.Delete(i);
      SaveDisableSendMsgList();
      SysMsg(sHumanName + ' 已从禁言列表中删除。', c_Green, t_Hint);
      Exit;
    end;
end;
SysMsg(sHumanName + ' 没有被禁言!!!', c_Red, t_Hint);
end;

procedure TPlayObject.CmdEndContest(Cmd: pTGameCmd; sParam1: string);                               //004CF364
var
i, ii                                 : Integer;
List10, List14                        : TList;
PlayObject, PlayObjectA               : TPlayObject;
bo19                                  : Boolean;
//s20:String;
Guild                                 : TGuild;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if ((sParam1 <> '') and (sParam1 = '?')) then begin
    SysMsg('结束行会争霸赛。', c_Red, t_Hint);
    SysMsg(Format('命令格式: @%s', ), c_Red, t_Hint);
    Exit;
end;

if not m_PEnvir.m_MapFlag.boFight3 then begin
    SysMsg('此命令不能在当前地图中使用!!!', c_Red, t_Hint);
    Exit;
end;
List10 := TList.Create;
List14 := TList.Create;
UserEngine.GetMapRageHuman(m_PEnvir, m_nCurrX, m_nCurrY, 1000, List10);
for i := 0 to List10.Count - 1 do begin
    PlayObject := TPlayObject(List10.Items);
    if not PlayObject.m_boObMode or not PlayObject.m_boAdminMode then begin
      if PlayObject.m_MyGuild = nil then Continue;
      bo19 := False;
      for ii := 0 to List14.Count - 1 do begin
      PlayObjectA := TPlayObject(List14.Items);
      if PlayObject.m_MyGuild = PlayObjectA.m_MyGuild then
          bo19 := True;
      end;
      if not bo19 then begin
      List14.Add(PlayObject.m_MyGuild);
      end;
    end;
end;
for i := 0 to List14.Count - 1 do begin
    Guild := TGuild(List14.Items);
    Guild.EndTeamFight();
    UserEngine.CryCry(RM_CRY, m_PEnvir, m_nCurrX, m_nCurrY, 1000,
      g_Config.btCryMsgFColor, g_Config.btCryMsgBColor,
      Format(' - %s 行会争霸赛已结束。', ));
end;
List10.free;
List14.free;
end;

procedure TPlayObject.CmdEndGuild;                                                                  //4D1A44
begin
if (m_MyGuild <> nil) then begin
    if (m_nGuildRankNo > 1) then begin
      if TGuild(m_MyGuild).IsMember(m_sCharName) and
      TGuild(m_MyGuild).DelMember(m_sCharName) then begin
      SysMsg('你已经退出行会。', c_Green, t_Hint);
      end;
    end else begin
      SysMsg('行会掌门人不能这样退出行会!!!', c_Red, t_Hint);
    end;
end else begin
    if g_Config.boOldClientShowHiLevel then
      SysMsg('你都没加入行会!!!', c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdFireBurn(nInt, nTime, nn: Integer);
var
FireBurnEvent                         : TFireBurnEvent;
begin
if (m_btPermissionGM < 6) then Exit;
if (nInt = 0) or (nTime = 0) or (nn = 0) then begin
    SysMsg('命令格式: @' + g_GameCommand.FIREBURN.sCmd + ' nInt nTime nN',
      c_Red, t_Hint);
    Exit;
end;
FireBurnEvent := TFireBurnEvent.Create(Self, m_nCurrX, m_nCurrY, nInt, nTime,
    nn);

g_EventManager.AddEvent(FireBurnEvent);
end;

procedure TPlayObject.CmdForcedWallconquestWar(Cmd: pTGameCmd; sCASTLENAME:
string);
var
Castle                              : TUserCastle;
s20                                 : string;
AttackerInfo                        : pTAttackerInfo;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;

if sCASTLENAME = '' then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 城堡名称', c_Red, t_Hint);
    Exit;
end;

Castle := g_CastleManager.Find(sCASTLENAME);
if Castle <> nil then begin
    if Castle.m_boUnderWar or (Castle.m_btForceStartWar <> 0) then
      Castle.m_btForceStartWar := 2
    else
      Castle.m_btForceStartWar := 1;
    l_dwRunTimeTick := 0;
end else begin
    SysMsg(Format(g_sGameCommandSbkGoldCastleNotFoundMsg, ), c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdFreePenalty(Cmd: pTGameCmd; sHumanName: string);
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandFreePKHelpMsg]), c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
PlayObject.m_nPkPoint := 0;
PlayObject.RefNameColor();
PlayObject.SysMsg(g_sGameCommandFreePKHumanMsg, c_Green, t_Hint);
SysMsg(Format(g_sGameCommandFreePKMsg, ), c_Green, t_Hint);
end;

procedure TPlayObject.CmdFriendRecall(sCmd, sParam: string);
var
i                                     : Integer;
human                                 : TPlayObject;
begin
if (sParam = '') or (sParam = '?') then begin
    SysMsg('命令格式: @' + sCmd +
      ' 好友名字(好友传送,可以把你的好友传送到自己身边,好友必须允许传送。)',
      c_Green, t_Hint);
    Exit;
end;

if m_FriendsList.Count = 0 then begin
    SysMsg('你还没有好友!!!', c_Red, t_Hint);
    Exit;
end;

if m_PEnvir.m_MapFlag.boNOFRIENDRECALL then begin
    SysMsg('本地图禁止好友传送!!!', c_Red, t_Hint);
    Exit;
end;

if GetTickCount - m_dwGroupRcallTick < 10000 then begin
    SysMsg('稍等伙才能再次使用此功能!!!', c_Red, t_Hint);
    Exit;
end;
if m_boArrow then begin
    SysMsg('您正在执行任务,目前无法使用此功能!!!',
      c_Red, t_Hint);
    Exit;
end;
for i := 0 to m_FriendsList.Count - 1 do begin
    if m_FriendsList = sParam then begin
      human := UserEngine.GetPlayObject(sParam);
      if human = nil then begin
      SysMsg('你的好友 ' + sParam + ' 不在线!!!', c_Red, t_Hint);
      Exit;
      end;
      if human = Self then begin
      SysMsg('你不能召唤自己!!!', c_Red, t_Hint);
      Exit;
      end;
      if human.m_boAllowGroupReCall then begin
      RecallHuman(human.m_sCharName, $1D);
      SendRefMsg(RM_510, 1, 0, $1D, 0, '');
      human.SendDelayMsg(Self, RM_510, 1, 0, $1D, 0, '', 100);
      end else begin
      SysMsg(human.m_sCharName + ' 不允许传送!!!', c_Red, t_Hint);
      end;
      Break;
    end;
end;
end;

//调整元宝数量

procedure TPlayObject.CmdGameGold(Cmd: pTGameCmd; sHumanName: string; sCtr: string; nGold: Integer);
var
PlayObject                            : TPlayObject;
Ctr                                 : Char;
resourcestring
sLogMsg                               = '[调整元宝] %s 给:%s %s %d 元宝';
begin
Ctr := '1';
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sCtr <> '') then begin
    Ctr := sCtr;
end;

if (sHumanName = '') or not (Ctr in ['=', '+', '-']) or (nGold < 0) or
    ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandGameGoldHelpMsg]), c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
case sCtr of
    '=': begin
      if nGold > g_Config.nHumanMaxGameGold then begin
          SysMsg(sHumanGameGoldLargeThenLimit, c_Red, t_Hint);
          Exit;
      end;
      PlayObject.m_nGameGold := nGold;
      end;
    '+': begin
      if nGold + PlayObject.m_nGameGold > g_Config.nHumanMaxGameGold then begin
          SysMsg(sHumanGameGoldLargeThenLimit, c_Red, t_Hint);
          Exit;
      end;
      Inc(PlayObject.m_nGameGold, nGold);
      end;
    '-': begin
      nGold := _Max(0, PlayObject.m_nGameGold - nGold);
      PlayObject.m_nGameGold := nGold;
      end;
end;
if g_boGameLogGameGold then begin
    AddGameDataLog(Format(g_sGameLogMsg, [LOG_GAMEGOLD,
      PlayObject.m_sMapName,
      PlayObject.m_nCurrX,
      PlayObject.m_nCurrY,
      PlayObject.m_sCharName,
      g_Config.sGameGoldName,
      nGold,
      sCtr,
      m_sCharName]));
end;
GameGoldChanged();
PlayObject.SysMsg(Format(g_sGameCommandGameGoldHumanMsg,
    [g_Config.sGameGoldName, nGold, PlayObject.m_nGameGold,
    g_Config.sGameGoldName]), c_Green, t_Hint);
SysMsg(Format(g_sGameCommandGameGoldGMMsg, [sHumanName,
    g_Config.sGameGoldName, nGold, PlayObject.m_nGameGold,
      g_Config.sGameGoldName]), c_Green, t_Hint);

if g_Config.boShowMakeItemMsg and (m_btPermissionGM >= 6) then
    MainOutMessage(Format(sLogMsg, [m_sCharName, PlayObject.m_sCharName,
      sCtr, nGold]));
end;

procedure TPlayObject.CmdGamePoint(Cmd: pTGameCmd; sHumanName, sCtr: string;
nPoint: Integer);
var
PlayObject                            : TPlayObject;
Ctr                                 : Char;
begin
Ctr := '1';
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sCtr <> '') then begin
    Ctr := sCtr;
end;

if (sHumanName = '') or not (Ctr in ['=', '+', '-']) or (nPoint < 0) or (nPoint
    > 100000000) or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandGamePointHelpMsg]), c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
case sCtr of
    '=': begin
      PlayObject.m_nGamePoint := nPoint;
      end;
    '+': Inc(PlayObject.m_nGamePoint, nPoint);
    '-': Dec(PlayObject.m_nGamePoint, nPoint);
end;
if g_boGameLogGamePoint then begin
    AddGameDataLog(Format(g_sGameLogMsg, [LOG_GAMEPOINT,
      PlayObject.m_sMapName,
      PlayObject.m_nCurrX,
      PlayObject.m_nCurrY,
      PlayObject.m_sCharName,
      g_Config.sGamePointName,
      nPoint,
      sCtr,
      m_sCharName]));
end;
GameGoldChanged();
PlayObject.SysMsg(Format(g_sGameCommandGamePointHumanMsg, [nPoint,
    PlayObject.m_nGamePoint]), c_Green, t_Hint);
SysMsg(Format(g_sGameCommandGamePointGMMsg, [sHumanName, nPoint,
    PlayObject.m_nGamePoint]), c_Green, t_Hint);
end;

procedure TPlayObject.CmdGroupRecall(sCmd: string; AllRecall: Boolean = False);
var
i                                     : Integer;
dwValue                               : LongWord;
PlayObject                            : TPlayObject;
begin
if m_boRecallSuite or (m_btPermissionGM >= 6) then begin
    if not m_PEnvir.m_MapFlag.boNORECALL then begin
      dwValue := (GetTickCount - m_dwGroupRcallTick) div 1000;
      m_dwGroupRcallTick := m_dwGroupRcallTick + dwValue * 1000;
      if m_btPermissionGM >= 6 then m_wGroupRcallTime := 0;

      if m_wGroupRcallTime > dwValue then begin
      Dec(m_wGroupRcallTime, dwValue);
      end else m_wGroupRcallTime := 0;
      if m_wGroupRcallTime = 0 then begin
      if m_boArrow then begin
          SysMsg('您正在执行任务,目前无法使用此功能!!!',
            c_Red, t_Hint);
          Exit;
      end;

      if m_wShopItemCount > 0 then begin
          SysMsg('您正在摆摊,目前无法使用此功能!!!',
            c_Red, t_Hint);
          Exit;
      end;

      if m_GroupOwner = Self then begin
          for i := 1 to m_GroupMembers.Count - 1 do begin
            PlayObject := TPlayObject(m_GroupMembers.Objects);
            if (PlayObject.m_boAllowGroupReCall = True) or (AllRecall = True) then begin
            if PlayObject.m_PEnvir.m_MapFlag.boNORECALL then begin
                SysMsg(Format('%s 所在的地图不允许传送。',
                  ), c_Red, t_Hint);
            end else begin
                RecallHuman(PlayObject.m_sCharName, 0);
                //PlayObject.SendDelayMsg(self,RM_510,1,0,$20,0,'',100);
            end;
            end else begin
            SysMsg(Format('%s 不允许天地合一!!!',
                ), c_Red, t_Hint);
            end;
          end;
          m_dwGroupRcallTick := GetTickCount();
          m_wGroupRcallTime := g_Config.nGroupRecallTime;
      end;
      end else begin
      SysMsg(Format('%d 秒之后才可以再使用此功能!!!',
          ), c_Red, t_Hint);
      end;
    end else begin
      SysMsg('此地图禁止使用此命令!!!', c_Red, t_Hint);
    end;
end else begin
    SysMsg('您现在还无法使用此功能!!!', c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdGuildRecall(sCmd, sParam: string);
var
i, ii                                 : Integer;
dwValue                               : LongWord;
PlayObject                            : TPlayObject;
GuildRank                           : pTGuildRank;
nRecallCount, nNoRecallCount          : Integer;
Castle                              : TUserCastle;
begin
if (sParam <> '') and (sParam = '?') then begin
    SysMsg('命令功能: 行会传送,行会掌门人可以将整个行会成员全部集中。', c_Red, t_Hint);
    Exit;
end;

if not m_boGuildMove and (m_btPermissionGM < 6) then begin
    SysMsg('您现在还无法使用此功能!!!', c_Red, t_Hint);
    Exit;
end;
if not IsGuildMaster then begin
    SysMsg('行会掌门人才可以使用此功能!!!', c_Red, t_Hint);
    Exit;
end;
if m_PEnvir.m_MapFlag.boNOGUILDRECALL then begin
    SysMsg('本地图不允许使用此功能!!!', c_Red, t_Hint);
    Exit;
end;
Castle := g_CastleManager.InCastleWarArea(Self);

//if UserCastle.m_boUnderWar and UserCastle.InCastleWarArea(m_PEnvir,m_nCurrX,m_nCurrY) then begin
if (Castle <> nil) and Castle.m_boUnderWar then begin
    SysMsg('攻城区域不允许使用此功能!!!', c_Red, t_Hint);
    Exit;
end;
nRecallCount := 0;
nNoRecallCount := 0;
dwValue := (GetTickCount - m_dwGroupRcallTick) div 1000;
m_dwGroupRcallTick := m_dwGroupRcallTick + dwValue * 1000;
if m_btPermissionGM >= 6 then m_wGroupRcallTime := 0;
if m_wGroupRcallTime > dwValue then begin
    Dec(m_wGroupRcallTime, dwValue);
end else m_wGroupRcallTime := 0;

if m_wGroupRcallTime > 0 then begin
    SysMsg(Format('%d 秒之后才可以再使用此功能!!!',
      ), c_Red, t_Hint);
    Exit;
end;
if m_boArrow then begin
    SysMsg('您正在执行任务,目前无法使用此功能!!!',
      c_Red, t_Hint);
    Exit;
end;
for i := 0 to TGuild(m_MyGuild).m_RankList.Count - 1 do begin
    GuildRank := TGuild(m_MyGuild).m_RankList.Items;
    for ii := 0 to GuildRank.MemberList.Count - 1 do begin
      PlayObject := TPlayObject(GuildRank.MemberList.GetValues(GuildRank.MemberList.Keys));
      if PlayObject <> nil then begin
      if PlayObject = Self then begin
          //          Inc(nNoRecallCount);
          Continue;
      end;
      if PlayObject.m_boAllowGuildReCall then begin
          if PlayObject.m_PEnvir.m_MapFlag.boNORECALL then begin
            SysMsg(Format('%s 所在的地图不允许传送。',
            ), c_Red, t_Hint);
          end else begin
            RecallHuman(PlayObject.m_sCharName, $1C);
            PlayObject.SendDelayMsg(Self, RM_510, 1, 0, $1C, 0, '', 100);
            Inc(nRecallCount);
          end;
      end else begin
          Inc(nNoRecallCount);
          SysMsg(Format('%s 不允许行会合一!!!',
            ), c_Red, t_Hint);
      end;
      end;
    end;
end;
//SysMsg('已传送' + IntToStr(nRecallCount) + '个成员,' + IntToStr(nNoRecallCount) + '个成员未被传送。',c_Green,t_Hint);
SysMsg(Format('已传送%d个成员,%d个成员未被传送。',
    ), c_Green, t_Hint);
m_dwGroupRcallTick := GetTickCount();
m_wGroupRcallTime := g_Config.nGuildRecallTime;
end;

procedure TPlayObject.CmdGuildWar(sCmd, sGuildName: string);                                        //004CE9F0
begin
if (m_btPermissionGM < 6) then Exit;
end;

procedure TPlayObject.CmdHair(Cmd: pTGameCmd; sHumanName: string; nHair:
Integer);
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or (nHair < 0) then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称 类型值', c_Red,
      t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject <> nil then begin
    PlayObject.m_btHair := nHair;
    PlayObject.FeatureChanged();
    SysMsg(sHumanName + ' 的头发已改变。', c_Green, t_Hint);
end else begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdHumanCount(Cmd: pTGameCmd; sMapName: string);
var
Envir                                 : TEnvirnoment;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sMapName = '') or ((sMapName <> '') and (sMapName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandHumanCountHelpMsg]), c_Red, t_Hint);
    Exit;
end;

if sMapName = 'SELF' then
    Envir := m_PEnvir
else
    Envir := g_MapManager.FindMap(sMapName);

if Envir = nil then begin
    SysMsg(g_sGameCommandMobCountMapNotFound, c_Red, t_Hint);
    Exit;
end;
SysMsg(Format(g_sGameCommandMobCountMonsterCount, ), c_Green, t_Hint);
end;

procedure TPlayObject.CmdHumanInfo(Cmd: pTGameCmd; sHumanName: string);
//004CFC98
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandInfoHelpMsg]), c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
SysMsg(PlayObject.GeTBaseObjectInfo(), c_Green, t_Hint);
end;

procedure TPlayObject.CmdHumanLocal(Cmd: pTGameCmd; sHumanName: string);
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandHumanLocalHelpMsg]), c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
SysMsg(Format(g_sGameCommandHumanLocalMsg, [sHumanName, m_sIPLocal
    {GetIPLocal(PlayObject.m_sIPaddr)}]), c_Green, t_Hint);
end;

procedure TPlayObject.CmdHunger(sCmd, sHumanName: string; nHungerPoint:
Integer);
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < 6) then Exit;
if (sHumanName = '') or (nHungerPoint < 0) then begin
    SysMsg('命令格式: @' + sCmd + ' 人物名称 能量值', c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject <> nil then begin
    PlayObject.m_nHungerStatus := nHungerPoint;
    PlayObject.SendMsg(PlayObject, RM_MYSTATUS, 0, 0, 0, 0, '');
    PlayObject.RefMyStatus();
    SysMsg(sHumanName + ' 的能量值已改变。', c_Green, t_Hint);
end else begin
    SysMsg(sHumanName + '没有在线!!!', c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdIncPkPoint(Cmd: pTGameCmd; sHumanName: string; nPoint:
Integer);                                                                                       //004BF4D4
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandIncPkPointHelpMsg]), c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
PlayObject.IncPkPoint(nPoint);
PlayObject.RefNameColor();
if nPoint > 0 then
    SysMsg(Format(g_sGameCommandIncPkPointAddPointMsg, ),
      c_Green, t_Hint)
else
    SysMsg(Format(g_sGameCommandIncPkPointDecPointMsg, ),
      c_Green, t_Hint);
end;

procedure TPlayObject.CmdKickHuman(Cmd: pTGameCmd; sHumName: string);
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumName = '') or ((sHumName <> '') and (sHumName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandKickHumanHelpMsg]), c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumName);
if PlayObject <> nil then begin
    PlayObject.m_boOfflineGetGamePoint := False;
    PlayObject.m_boKickFlag := True;
    PlayObject.m_boEmergencyClose := True;
end else begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdKill(Cmd: pTGameCmd; sHumanName: string);
var
BaseObject                            : TBaseObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if sHumanName <> '' then begin
    BaseObject := UserEngine.GetPlayObject(sHumanName);
    if BaseObject = nil then begin
      SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red,
      t_Hint);
      Exit;
    end;
end else begin
    BaseObject := GetPoseCreate();
    if BaseObject = nil then begin
      SysMsg('命令使用方法不正确,必须与角色面对面站好!!!', c_Red, t_Hint);
      Exit;
    end;
end;
BaseObject.m_WAbil.dwHP := 0;
BaseObject.Die;
end;

procedure TPlayObject.CmdLockLogin(Cmd: pTGameCmd);
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if not g_Config.boLockHumanLogin then begin
    SysMsg('本服务器还没有启用登录锁功能!!!', c_Red,
      t_Hint);
    Exit;
end;

if m_boLockLogon and not m_boLockLogoned then begin
    SysMsg('您还没有打开登录锁或还没有设置锁密码!!!',
      c_Red, t_Hint);
    Exit;
end;

m_boLockLogon := not m_boLockLogon;
if m_boLockLogon then begin
    SysMsg('已开启登录锁', c_Green, t_Hint);
end else begin
    SysMsg('已关闭登录锁', c_Green, t_Hint);
end;

end;

procedure TPlayObject.CmdLotteryTicket(sCmd: string; nPermission: Integer;
sParam1: string);
begin
if (m_btPermissionGM < nPermission) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sParam1 = '') or ((sParam1 <> '') and (sParam1 = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, ), c_Red, t_Hint);
    Exit;
end;
SysMsg(Format(g_sGameCommandLotteryTicketMsg, [g_Config.nWinLotteryCount,
    g_Config.nNoWinLotteryCount,
      g_Config.nWinLotteryLevel1,
      g_Config.nWinLotteryLevel2,
      g_Config.nWinLotteryLevel3,
      g_Config.nWinLotteryLevel4,
      g_Config.nWinLotteryLevel5,
      g_Config.nWinLotteryLevel6]), c_Green, t_Hint);
end;

procedure TPlayObject.CmdLuckPoint(sCmd: string; nPermission: Integer;
sHumanName, sCtr, sPoint: string);
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < nPermission) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [sCmd,
      g_sGameCommandLuckPointHelpMsg]), c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;

if sCtr = '' then begin
    SysMsg(Format(g_sGameCommandLuckPointMsg, [sHumanName,
      PlayObject.m_nBodyLuckLevel, PlayObject.m_dBodyLuck, PlayObject.m_nLuck]), c_Green, t_Hint);
    Exit;
end;

end;

//制造物品命令

procedure TPlayObject.CmdMakeItem(Cmd: pTGameCmd; sItemName: string; nCount:
Integer);                                                                                       //004CCE34
var
i, nMaxCount, nCurCount               : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
logStr                              : string;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sItemName = '') then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGamecommandMakeHelpMsg]), c_Red, t_Hint);
    Exit;
end;
if (nCount <= 0) then nCount := 1;
StdItem := UserEngine.GetStdItem(sItemName);
if (m_btPermissionGM < Cmd.nPerMissionMax) then begin
    if (StdItem <> nil) and CheckSPCode(StdItem.SPCode, SP_DISABLEMAKE) then begin
      SysMsg(g_sGamecommandMakeItemNameOrPerMissionNot, c_Red, t_Hint);
      Exit                                                                                          //物品控制-禁止制造
    end;
    if g_CastleManager.InCastleWarArea(Self) <> nil then begin
      SysMsg(g_sGamecommandMakeInCastleWarRange, c_Red, t_Hint);
      Exit;
    end;
    if not InSafeZone then begin
      SysMsg(g_sGamecommandMakeInSafeZoneRange, c_Red, t_Hint);
      Exit;
    end;
    nCount := 1;
end;
if StdItem = nil then Exit;

if CheckSPCode(StdItem.Reserved, RE_ALLOWPILE) then begin
    nMaxCount := _MAX(1, StdItem.Stock);
    if m_ItemList.Count >= m_nBagSize then Exit;
    while nCount > 0 do begin
      nCurCount := _MIN(nCount, nMaxCount);
      Dec(nCount, nCurCount);
      New(UserItem);
      if UserEngine.CopyToUserItemFromName(sItemName, UserItem) then begin
      UserItem^.Dura := nCurCount;
      UserItem^.DuraMax := nMaxCount;
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if (StdItem.Price >= 15000) and not g_Config.boTestServer and
          (m_btPermissionGM < 5) then begin
          Dispose(UserItem);
          Exit;
      end else begin
          if (g_Config.boTimeBackServer) or (g_Config.boMagicCityServer) then begin
            if g_Config.EnableGoodItemTimeBack = True then
            begin
            if (Random(g_Config.nMakeRandomAddValueTimeBack0) = 0) and (g_Config.nMakeRandomAddValueTimeBack0 > 0) then begin
                UserEngine.RandomTimeBackUpgradeItem(UserItem, 20);
            end;
            if (Random(g_Config.nMakeRandomAddValueTimeBack1) = 0) and (g_Config.nMakeRandomAddValueTimeBack0 > 1) then begin
                UserEngine.RandomTimeBackUpgradeItem(UserItem, 30);
            end;
            if (Random(g_Config.nMakeRandomAddValueTimeBack2) = 0) and (g_Config.nMakeRandomAddValueTimeBack0 > 2) then begin
                UserEngine.RandomTimeBackUpgradeItem(UserItem, 31);
            end;
            end;
          end else begin
            if Random(g_Config.nMakeRandomAddValue {10}) = 0 then
            UserEngine.RandomUpgradeItem(UserItem);
          end;
      end;
      if StdItem.StdMode in then begin
          if StdItem.Shape in then begin
            UserEngine.GetUnknowItemValue(UserItem);
          end;
      end;
      if m_btPermissionGM >= Cmd.nPerMissionMax then begin
          UserItem.MakeIndex := GetItemNumberEx();
          //制造的物品另行取得物品ID
      end;
      if IsEnoughBag then begin
          if AddItemToBag(UserItem) then begin
            SendAddItem(UserItem);
            if g_Config.boShowMakeItemMsg and (m_btPermissionGM >= 6) then begin
            logStr := '[制造物品] ' + m_sCharName + ' ' + sItemName + '(' + IntToStr(UserItem.MakeIndex) + ')';
            MainOutMessage(logStr);
            SysMsg(logStr, c_Red, t_Hint);
            end;
            if StdItem.boGameLog = 1 then
            AddGameDataLog('9' + #9 +
                m_sMapName + #9 +
                IntToStr(m_nCurrX) + #9 +
                IntToStr(m_nCurrY) + #9 +
                m_sCharName + #9 +
                sItemName + #9 +
                IntToStr(UserItem.MakeIndex) + #9 +
                IntToStr(nCurCount) + #9 +
                m_sCharName);
          end;
      end else begin
          Dispose(UserItem);
          Exit;
      end;
      end else begin
      Dispose(UserItem);
      SysMsg(Format(g_sGamecommandMakeItemNameNotFound, ), c_Red, t_Hint);
      Exit;
      end;
    end;
end else begin
    if (nCount > 10) then nCount := 10;
    for i := 0 to nCount - 1 do begin
      if m_ItemList.Count >= m_nBagSize then Exit;
      New(UserItem);
      if UserEngine.CopyToUserItemFromName(sItemName, UserItem) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if (StdItem.Price >= 15000) and not g_Config.boTestServer and
          (m_btPermissionGM < 5) then begin
          Dispose(UserItem);
          Exit;
      end else begin
          if (g_Config.boTimeBackServer) or (g_Config.boMagicCityServer) then begin
            if g_Config.EnableGoodItemTimeBack = True then
            begin
            if (Random(g_Config.nMakeRandomAddValueTimeBack0) = 0) and (g_Config.nMakeRandomAddValueTimeBack0 > 0) then begin
                UserEngine.RandomTimeBackUpgradeItem(UserItem, 20);
            end;
            if (Random(g_Config.nMakeRandomAddValueTimeBack1) = 0) and (g_Config.nMakeRandomAddValueTimeBack0 > 1) then begin
                UserEngine.RandomTimeBackUpgradeItem(UserItem, 30);
            end;
            if (Random(g_Config.nMakeRandomAddValueTimeBack2) = 0) and (g_Config.nMakeRandomAddValueTimeBack0 > 2) then begin
                UserEngine.RandomTimeBackUpgradeItem(UserItem, 31);
            end;
            end;
          end else begin
            if Random(g_Config.nMakeRandomAddValue {10}) = 0 then
            UserEngine.RandomUpgradeItem(UserItem);
          end;
      end;
      if StdItem.StdMode in then begin
          if StdItem.Shape in then begin
            UserEngine.GetUnknowItemValue(UserItem);
          end;
      end;
      if m_btPermissionGM >= Cmd.nPerMissionMax then begin
          UserItem.MakeIndex := GetItemNumberEx();
          //制造的物品另行取得物品ID
      end;
      if AddItemToBag(UserItem) then begin
          SendAddItem(UserItem);
          if g_Config.boShowMakeItemMsg and (m_btPermissionGM >= 6) then begin
            logStr := '[制造物品] ' + m_sCharName + ' ' + sItemName + '(' + IntToStr(UserItem.MakeIndex) + ')';
            MainOutMessage(logStr);
            SysMsg(logStr, c_Red, t_Hint);
          end;

          if StdItem.boGameLog = 1 then
            AddGameDataLog('5' + #9 +
            m_sMapName + #9 +
            IntToStr(m_nCurrX) + #9 +
            IntToStr(m_nCurrY) + #9 +
            m_sCharName + #9 +
            StdItem.Name + #9 +
            IntToStr(UserItem.MakeIndex) + #9 +
            '1' + #9 +
            '0');
      end else begin
          Dispose(UserItem);
          Break;
      end;
      end else begin
      Dispose(UserItem);
      SysMsg(Format(g_sGamecommandMakeItemNameNotFound, ), c_Red, t_Hint);
      Break;
      end;
    end;
end;
end;

procedure TPlayObject.CmdMapMove(Cmd: pTGameCmd; sMapName: string);
var
Envir                                 : TEnvirnoment;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sMapName = '') or ((sMapName <> '') and (sMapName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, ), c_Red, t_Hint);
    Exit;
end;
Envir := g_MapManager.FindMap(sMapName);
if (Envir = nil) then begin
    SysMsg(Format(g_sTheMapNotFound, ), c_Red, t_Hint);
    Exit;
end;
if (m_btPermissionGM >= Cmd.nPerMissionMax) or CanMoveMap(sMapName) then begin
    SendRefMsg(RM_SPACEMOVE_FIRE, 0, 0, 0, 0, '');
    MapRandomMove(sMapName, 0, nil);
end else begin
    SysMsg(Format(g_sTheMapDisableMove, ), c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdMapMoveHuman(Cmd: pTGameCmd; sSrcMap, sDenMap: string);
var
SrcEnvir, DenEnvir                  : TEnvirnoment;
HumanList                           : TList;
i, nMapIndex                        : Integer;
MoveHuman                           : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sDenMap = '') or (sSrcMap = '') or ((sSrcMap <> '') and (sSrcMap = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandMapMoveHelpMsg]), c_Red, t_Hint);
    Exit;
end;

SrcEnvir := g_MapManager.FindMap(sSrcMap);
DenEnvir := g_MapManager.FindMap(sDenMap);
if (SrcEnvir = nil) then begin
    SysMsg(Format(g_sGameCommandMapMoveMapNotFound, ), c_Red, t_Hint);
    Exit;
end;
if (DenEnvir = nil) then begin
    SysMsg(Format(g_sGameCommandMapMoveMapNotFound, ), c_Red, t_Hint);
    Exit;
end;

HumanList := TList.Create;
UserEngine.GetMapRageHuman(SrcEnvir, SrcEnvir.m_nWidth div 2,
    SrcEnvir.m_nHeight div 2, 1000, HumanList);
nMapIndex := -1;
for i := 0 to HumanList.Count - 1 do begin
    MoveHuman := TPlayObject(HumanList.Items);
    if MoveHuman <> Self then
      MoveHuman.MapRandomMove(sDenMap, 0, @nMapIndex);
end;
HumanList.free;
end;

procedure TPlayObject.CmdMasterRecall(sCmd, sParam: string);
var
i                                     : Integer;
MasterHuman                           : TPlayObject;
begin
if (sParam <> '') and (sParam = '?') then begin
    SysMsg('命令格式: @' + sCmd +
      ' (师徒传送,师父可以将徒弟传送到自己身边,徒弟必须允许传送。)',
      c_Green, t_Hint);
    Exit;
end;
if not m_boMaster then begin
    SysMsg('只能师父才能使用此功能!!!', c_Red, t_Hint);
    Exit;
end;
if m_MasterList.Count = 0 then begin
    SysMsg('你的徒弟一个都不在线!!!', c_Red, t_Hint);
    Exit;
end;
if m_PEnvir.m_MapFlag.boNOMASTERRECALL then begin
    SysMsg('本地图禁止师徒传送!!!', c_Red, t_Hint);
    Exit;
end;
if GetTickCount - m_dwMasterRecallTick < 10000 then begin
    SysMsg('稍等伙才能再次使用此功能!!!', c_Red, t_Hint);
    Exit;
end;
if m_boArrow then begin
    SysMsg('您正在执行任务,目前无法使用此功能!!!',
      c_Red, t_Hint);
    Exit;
end;
for i := 0 to m_MasterList.Count - 1 do begin
    MasterHuman := TPlayObject(m_MasterList.Items);
    if MasterHuman.m_boCanMasterRecall and not MasterHuman.m_boGhost and not
      MasterHuman.m_boDeath then begin
      RecallHuman(MasterHuman.m_sCharName, $1F);
      MasterHuman.SendDelayMsg(Self, RM_510, 1, 0, $1F, 0, '', 100);
    end else begin
      SysMsg(MasterHuman.m_sCharName + ' 不允许传送!!!', c_Red,
      t_Hint);
    end;
end;
SendRefMsg(RM_510, 1, 0, $1F, 0, '');
end;

procedure TPlayObject.CmdMemberFunction(sCmd, sParam: string);
begin
if (sParam <> '') and (sParam = '?') then begin
    SysMsg('打开会员功能窗口.', c_Red, t_Hint);
    Exit;
end;
ExecuteScript(g_ManageNPC, '@Member');
end;

procedure TPlayObject.CmdMemberFunctionEx(sCmd, sParam: string);
begin
if (sParam <> '') and (sParam = '?') then begin
    SysMsg('打开会员功能窗口.', c_Red, t_Hint);
    Exit;
end;
ExecuteScript(g_FunctionNPC, '@Member');
end;

procedure TPlayObject.CmdMission(Cmd: pTGameCmd; sX, sY: string);                                 //004CCA08
var
nX, nY                              : Integer;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sX = '') or (sY = '') then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' XY', c_Red, t_Hint);
    Exit;
end;
nX := Str_ToInt(sX, 0);
nY := Str_ToInt(sY, 0);
g_boMission := True;
g_sMissionMap := m_sMapName;
g_nMissionX := nX;
g_nMissionY := nY;
SysMsg('怪物集中目标已设定为: ' + m_sMapName + '(' +
    IntToStr(g_nMissionX) + ':' + IntToStr(g_nMissionY) + ')', c_Green, t_Hint);
end;

procedure TPlayObject.CmdMob(Cmd: pTGameCmd; sMonName: string; nCount, nLevel:
Integer; sShowName: string);                                                                      //004CC7F4
var
i                                     : Integer;
nX, nY                              : Integer;
Monster                               : TBaseObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sMonName = '') or ((sMonName <> '') and (sMonName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandMobHelpMsg]), c_Red, t_Hint);
    Exit;
end;

if nCount <= 0 then nCount := 1;
if not (nLevel in ) then nLevel := 0;

nCount := _MIN(64, nCount);
GetFrontPosition(nX, nY);
for i := 0 to nCount - 1 do begin
    Monster := UserEngine.RegenMonsterByName(m_PEnvir, nX, nY,
      sMonName, sShowName);
    if Monster <> nil then begin
      Monster.m_wSlaveMakeLevel := nLevel;
      Monster.m_wSlaveExpLevel := nLevel;
      Monster.RecalcAbilitys;
      Monster.RefNameColor;
    end else begin
      SysMsg(g_sGameCommandMobMsg, c_Red, t_Hint);
      Break;
    end;
end;
end;

procedure TPlayObject.CmdMobCount(Cmd: pTGameCmd; sMapName: string);
var
Envir                                 : TEnvirnoment;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sMapName = '') or ((sMapName <> '') and (sMapName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandMobCountHelpMsg]), c_Red, t_Hint);
    Exit;
end;
Envir := g_MapManager.FindMap(sMapName);
if Envir = nil then begin
    SysMsg(g_sGameCommandMobCountMapNotFound, c_Red, t_Hint);
    Exit;
end;
SysMsg(Format(g_sGameCommandMobCountMonsterCount,
    ), c_Green, t_Hint);
end;

procedure TPlayObject.CmdMobFireBurn(Cmd: pTGameCmd; sMAP, sX, sY, sType,
sTime, sPoint: string);
var
nX, nY, nType, nTime, nPoint          : Integer;
FireBurnEvent                         : TFireBurnEvent;
Envir                                 : TEnvirnoment;
OldEnvir                              : TEnvirnoment;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sMAP = '') or ((sMAP <> '') and (sMAP = '?')) then begin
    SysMsg(Format(g_sGameCommandMobFireBurnHelpMsg, [Cmd.sCmd, sMAP, sX, sY,
      sType, sTime, sPoint]), c_Red, t_Hint);
    Exit;
end;

if (CompareText(sMAP, 'SELF') = 0) or (CompareText(sMAP, 'HERE') = 0) then begin
    sMAP := m_PEnvir.m_sMapName;
    nX := m_nCurrX + Str_ToInt(sX, -1);
    nY := m_nCurrY + Str_ToInt(sY, -1);
end else begin
    nX := Str_ToInt(sX, -1);
    nY := Str_ToInt(sY, -1);
end;

nType := Str_ToInt(sType, -1);
nTime := Str_ToInt(sTime, -1);
nPoint := Str_ToInt(sPoint, -1);
if nPoint < 0 then nPoint := 1;

if (sMAP = '') or (nX < 0) or (nY < 0) or (nType < 0) or (nTime < 0) or (nPoint < 0) then begin
    SysMsg(Format(g_sGameCommandMobFireBurnHelpMsg, [Cmd.sCmd, sMAP, sX, sY,
      sType, sTime, sPoint]), c_Red, t_Hint);
    Exit;
end;
Envir := g_MapManager.FindMap(sMAP);
if Envir <> nil then begin
    OldEnvir := m_PEnvir;
    m_PEnvir := Envir;
    FireBurnEvent := TFireBurnEvent.Create(Self, nX, nY, nType, nTime * 1000, nPoint);
    g_EventManager.AddEvent(FireBurnEvent);
    m_PEnvir := OldEnvir;
    Exit;
end;
SysMsg(Format(g_sGameCommandMobFireBurnMapNotFountMsg, ), c_Red, t_Hint);
end;

procedure TPlayObject.CmdMobLevel(Cmd: pTGameCmd; Param: string);                                 //004CFD5C
var
i                                     : Integer;
BaseObjectList                        : TList;
BaseObject                            : TBaseObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if ((Param <> '') and (Param = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, ), c_Red, t_Hint);
    Exit;
end;

BaseObjectList := TList.Create;
m_PEnvir.GetRangeBaseObject(m_nCurrX, m_nCurrY, 2, True, BaseObjectList);
for i := 0 to BaseObjectList.Count - 1 do begin
    BaseObject := TBaseObject(BaseObjectList.Items);
    SysMsg(BaseObject.GeTBaseObjectInfo(), c_Green, t_Hint);
end;
BaseObjectList.free;
end;

procedure TPlayObject.CmdMobNpc(sCmd: string; nPermission: Integer; sParam1,
sParam2, sParam3, sParam4: string);
var
nAppr                                 : Integer;
boIsCastle                            : Boolean;
Merchant                              : TMerchant;
nX, nY                              : Integer;
begin
if (m_btPermissionGM < nPermission) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sParam1 = '') or (sParam2 = '') or ((sParam1 <> '') and (sParam1 = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [sCmd,
      g_sGameCommandMobNpcHelpMsg]), c_Red, t_Hint);
    Exit;
end;

nAppr := Str_ToInt(sParam3, 0);
boIsCastle := (Str_ToInt(sParam4, 0) = 1);
if sParam1 = '' then begin
    SysMsg('命令格式: @' + sCmd +
      ' NPC名称 脚本文件名 外形(数字) 属沙城(0,1)', c_Red, t_Hint);
    Exit;
end;
Merchant := TMerchant.Create;
Merchant.m_sCharName := sParam1;
Merchant.m_sMapName := m_sMapName;
Merchant.m_PEnvir := m_PEnvir;
Merchant.m_wAppr := nAppr;
Merchant.m_nFlag := 0;
Merchant.m_boCastle := boIsCastle;
Merchant.m_sScript := sParam2;
GetFrontPosition(nX, nY);
Merchant.m_nCurrX := nX;
Merchant.m_nCurrY := nY;
Merchant.Initialize();
UserEngine.AddMerchant(Merchant);
end;

procedure TPlayObject.CmdMobPlace(Cmd: pTGameCmd; sX, sY, sMonName, sCount:
string);                                                                                          //004CCBB4
var
i                                     : Integer;
nCount, nX, nY                        : Integer;
MEnvir                              : TEnvirnoment;
mon                                 : TBaseObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
nCount := _MIN(500, Str_ToInt(sCount, 0));
nX := Str_ToInt(sX, 0);
nY := Str_ToInt(sY, 0);
MEnvir := g_MapManager.FindMap(g_sMissionMap);
if (nX <= 0) or (nY <= 0) or (sMonName = '') or (nCount <= 0) then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' XY 怪物名称 怪物数量',
      c_Red, t_Hint);
    Exit;
end;
if not g_boMission or (MEnvir = nil) then begin
    SysMsg('还没有设定怪物集中点!!!', c_Red, t_Hint);
    SysMsg('请先用命令' + g_GameCommand.Mission.sCmd +
      '设置怪物的集中点。', c_Red, t_Hint);
    Exit;
end;

if (MEnvir.m_MapFlag.boCanMirror) then begin
    SysMsg('目标不能为镜像地图!!!', c_Red, t_Hint);
    Exit;
end;

for i := 0 to nCount - 1 do begin
    mon := UserEngine.RegenMonsterByName(MEnvir, nX, nY, sMonName);
    if mon <> nil then begin
      mon.m_boMission := True;
      mon.m_nMissionX := g_nMissionX;
      mon.m_nMissionY := g_nMissionY;
    end else Break;
end;
SysMsg(IntToStr(nCount) + ' 只 ' + sMonName + ' 已正在往地图 ' +
    g_sMissionMap + ' ' + IntToStr(g_nMissionX) + ':' + IntToStr(g_nMissionY) +
    ' 集中。', c_Green, t_Hint);
end;

procedure TPlayObject.CmdNpcScript(sCmd: string; nPermission: Integer; sParam1,
sParam2, sParam3: string);
var
BaseObject                            : TBaseObject;
nNPCType                              : Integer;
i                                     : Integer;
sScriptFileName                     : string;
Merchant                              : TMerchant;
NormNpc                               : TNormNpc;
LoadList                              : TStringList;
sScriptLine                           : string;
begin
if (m_btPermissionGM < nPermission) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sParam1 <> '') or ((sParam1 <> '') and (sParam1 = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [sCmd,
      g_sGameCommandNpcScriptHelpMsg]), c_Red, t_Hint);
    Exit;
end;

nNPCType := -1;
BaseObject := GetPoseCreate();
if BaseObject <> nil then begin
    for i := 0 to UserEngine.m_MerchantList.Count - 1 do begin
      if TBaseObject(UserEngine.m_MerchantList.Items) = BaseObject then begin
      nNPCType := 0;
      Break;
      end;
    end;
    for i := 0 to UserEngine.QuestNPCList.Count - 1 do begin
      if TBaseObject(UserEngine.QuestNPCList.Items) = BaseObject then begin
      nNPCType := 1;
      Break;
      end;
    end;
end;
if nNPCType < 0 then begin
    SysMsg('命令使用方法不正确,必须与NPC面对面,才能使用此命令!!!', c_Red, t_Hint);
    Exit;
end;

if sParam1 = '' then begin
    if nNPCType = 0 then begin
      Merchant := TMerchant(BaseObject);
      sScriptFileName := g_Config.sEnvirDir + sMarket_Def + Merchant.m_sScript +
      '-' + Merchant.m_sMapName + '.txt';
    end;
    if nNPCType = 1 then begin
      NormNpc := TNormNpc(BaseObject);
      sScriptFileName := g_Config.sEnvirDir + sNpc_def + NormNpc.m_sCharName +
      '-' + NormNpc.m_sMapName + '.txt';
    end;
    if FileExists(sScriptFileName) then begin
      LoadList := TStringList.Create;
      try
      LoadList.LoadFromFile(sScriptFileName);
      except
      SysMsg('读取脚本文件错误: ' + sScriptFileName, c_Red, t_Hint);
      end;
      for i := 0 to LoadList.Count - 1 do begin
      sScriptLine := Trim(LoadList.Strings);
      sScriptLine := ReplaceChar(sScriptLine, ' ', ',');
      SysMsg(IntToStr(i) + ',' + sScriptLine, c_Blue, t_Hint);
      end;
      LoadList.free;
    end;
end;
end;

procedure TPlayObject.CmdOPDeleteSkill(sHumanName, sSkillName: string);
//004CE938
begin
if (m_btPermissionGM < 6) then Exit;
end;

procedure TPlayObject.CmdOPTraining(sHumanName, sSkillName: string;
nLevel: Integer);                                                                                 //004CC468
begin
if (m_btPermissionGM < 6) then Exit;
end;

procedure TPlayObject.CmdPKpoint(Cmd: pTGameCmd; sHumanName: string);                               //004CC61C
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandPKPointHelpMsg]), c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
SysMsg(Format(g_sGameCommandPKPointMsg, ),
    c_Green, t_Hint);
end;

//004CDA38

procedure TPlayObject.CmdPositionMove(Cmd: pTGameCmd; sMapName, sX, sY: string);
var
Envir                                 : TEnvirnoment;
nX, nY                              : Integer;
begin
try
    if (m_btPermissionGM < Cmd.nPermissionMin) then begin
      SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
      Exit;
    end;
    if (sMapName = '') or (sX = '') or (sY = '') or ((sMapName <> '') and
      (sMapName = '?')) then begin
      SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandPositionMoveHelpMsg]), c_Red, t_Hint);
      Exit;
    end;
    if (m_btPermissionGM >= Cmd.nPerMissionMax) or CanMoveMap(sMapName) then begin
      Envir := g_MapManager.FindMap(sMapName);
      if Envir <> nil then begin
      nX := Str_ToInt(sX, 0);
      nY := Str_ToInt(sY, 0);
      if Envir.CanWalk(nX, nY, True) then begin
          SpaceMove(sMapName, nX, nY, 0, nil);
      end else begin
          SysMsg(Format(g_sGameCommandPositionMoveCanotMoveToMap, [sMapName, sX,
            sY]), c_Green, t_Hint);
      end;
      end;
    end else begin
      SysMsg(Format(g_sTheMapDisableMove, ), c_Red,
      t_Hint);
    end;
except
    on E: Exception do begin
      MainOutMessage(' TPlayObject.CmdPositionMove');
      MainOutMessage(E.Message);
    end;

end;
end;

procedure TPlayObject.CmdPrvMsg(sCmd: string; nPermission: Integer;
sHumanName: string);
var
i                                     : Integer;
begin
if (m_btPermissionGM < nPermission) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [sCmd,
      g_sGameCommandPrvMsgHelpMsg]), c_Red, t_Hint);
    Exit;
end;
for i := m_BlockWhisperList.Count - 1 downto 0 do begin
    if CompareText(m_BlockWhisperList.Strings, sHumanName) = 0 then begin
      m_BlockWhisperList.Delete(i);
      SysMsg(Format(g_sGameCommandPrvMsgUnLimitMsg, ), c_Green,
      t_Hint);
      Exit;
    end;
end;
m_BlockWhisperList.Add(sHumanName);
SysMsg(Format(g_sGameCommandPrvMsgLimitMsg, ), c_Green, t_Hint);

end;

procedure TPlayObject.CmdReAlive(Cmd: pTGameCmd; sHumanName: string);
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandReAliveHelpMsg]), c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
PlayObject.ReAlive;
PlayObject.m_WAbil.dwHP := PlayObject.m_WAbil.dwMaxHP;
PlayObject.RecalcAbilitys();
PlayObject.SendMsg(PlayObject, RM_ABILITY, 0, 0, 0, 0, '');
SysMsg(Format(g_sGameCommandReAliveMsg, ), c_Green, t_Hint);
end;

procedure TPlayObject.CmdRecallHuman(Cmd: pTGameCmd; sHumanName: string);
//004CE250
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandRecallHelpMsg]), c_Red, t_Hint);
    Exit;
end;
RecallHuman(sHumanName, 0);
end;

procedure TPlayObject.CmdRecallMob(Cmd: pTGameCmd; sMonName: string; nCount,
nLevel, nAutoChangeColor, nFixColor: Integer);                                                    //004CC8C4
var
i                                     : Integer;
N10, n14                              : Integer;
mon                                 : TBaseObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sMonName = '') or ((sMonName <> '') and (sMonName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandRecallMobHelpMsg]), c_Red, t_Hint);
    Exit;
end;

if nLevel >= 10 then nLevel := 0;
if nCount <= 0 then nCount := 1;
for i := 0 to nCount - 1 do begin
    if m_SlaveList.Count >= 20 then Break;
    GetFrontPosition(N10, n14);
    mon := UserEngine.RegenMonsterByName(m_PEnvir, N10, n14, sMonName);
    if mon <> nil then begin
      mon.m_wSlaveMakeLevel := 3;
      mon.m_wSlaveExpLevel := nLevel;
      mon.m_Master := Self;
      mon.m_dwMasterRoyaltyTick := GetTickCount + 24 * 60 * 60 * 1000;
      if nAutoChangeColor = 1 then begin
      mon.m_boAutoChangeColor := True;
      end else
      if nFixColor > 0 then begin
          mon.m_boFixColor := True;
          mon.m_nFixColorIdx := nFixColor - 1;
      end;
      mon.RecalcAbilitys();
      mon.RefNameColor();
      m_SlaveList.Add(mon);
    end;
end;
end;

procedure TPlayObject.CmdReconnection(sCmd, sIPaddr, sPort: string);
begin
if (m_btPermissionGM < 6) then Exit;
if (sIPaddr <> '') and (sIPaddr = '?') then begin
    SysMsg('此命令用于改变客户端连接网关的IP及端口。',
      c_Blue, t_Hint);
    Exit;
end;

if (sIPaddr = '') or (sPort = '') then begin
    SysMsg('命令格式: @' + sCmd + ' IP地址 端口', c_Red, t_Hint);
    Exit;
end;
if (sIPaddr <> '') and (sPort <> '') then begin
    SendMsg(Self, RM_RECONNECTION, 0, 0, 0, 0, sIPaddr + '/' + sPort);
end;
end;

procedure TPlayObject.CmdRefineWeapon(Cmd: pTGameCmd; nDc, nMc, nSc, nHit:
Integer);                                                                                       //004CD1C4
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (nDc + nMc + nSc) > 10 then Exit;
if m_UseItems.wIndex <= 0 then Exit;
m_UseItems.btValue := nDc;
m_UseItems.btValue := nMc;
m_UseItems.btValue := nSc;
m_UseItems.btValue := nHit;
SendUpdateItem(@m_UseItems);
RecalcAbilitys();
SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
MainOutMessage('[武器调整]' + m_sCharName + ' DC:' + IntToStr(nDc) + ' MC'
    + IntToStr(nMc) + ' SC' + IntToStr(nSc) + ' HIT:' + IntToStr(nHit));
end;

procedure TPlayObject.CmdReGotoHuman(Cmd: pTGameCmd; sHumanName: string);
var
PlayObject                            : TPlayObject;
nMapIndex                           : Integer;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandReGotoHelpMsg]), c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
nMapIndex := PlayObject.m_PEnvir.Index;
SpaceMove(PlayObject.m_PEnvir.m_sMapName, PlayObject.m_nCurrX,
    PlayObject.m_nCurrY, 0, @nMapIndex);

end;

procedure TPlayObject.CmdReloadAbuse(sCmd: string; nPermission: Integer;
sParam1: string);
begin
if (m_btPermissionGM < nPermission) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if ((sParam1 <> '') and (sParam1 = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, ), c_Red, t_Hint);
    Exit;
end;
end;

procedure TPlayObject.CmdReLoadAdmin(sCmd: string);
begin
if (m_btPermissionGM < 6) then Exit;
FrmDB.LoadAdminList();
UserEngine.SendServerGroupMsg(213, g_Config.nServerNumber, '');
SysMsg('管理员列表重新加载成功...', c_Green, t_Hint);
end;

procedure TPlayObject.CmdReloadGuild(sCmd: string; nPermission: Integer;
sParam1: string);
var
Guild                                 : TGuild;
begin
if (m_btPermissionGM < nPermission) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sParam1 = '') or ((sParam1 <> '') and (sParam1 = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [sCmd,
      g_sGameCommandReloadGuildHelpMsg]), c_Red, t_Hint);
    Exit;
end;
if g_Config.nServerNumber <> 0 then begin
    SysMsg(g_sGameCommandReloadGuildOnMasterserver, c_Red, t_Hint);
    Exit;
end;

Guild := g_GuildManager.FindGuild(sParam1);
if Guild = nil then begin
    SysMsg(Format(g_sGameCommandReloadGuildNotFoundGuildMsg, ), c_Red,
      t_Hint);
    Exit;
end;
//Guild.LoadGuild();
//SysMsg(Format(g_sGameCommandReloadGuildSuccessMsg, ), c_Red, t_Hint);
//UserEngine.SendServerGroupMsg(SS_207, g_Config.nServerNumber, sParam1);
end;

procedure TPlayObject.CmdReloadGuildAll;                                                            //004CE530
begin
if (m_btPermissionGM < 6) then Exit;
end;

procedure TPlayObject.CmdReloadLineNotice(sCmd: string;
nPermission: Integer; sParam1: string);
begin
if (m_btPermissionGM < nPermission) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if ((sParam1 <> '') and (sParam1 = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, ), c_Red, t_Hint);
    Exit;
end;
if LoadLineNotice(g_Config.sNoticeDir + 'LineNotice.txt') then begin
    SysMsg(g_sGameCommandReloadLineNoticeSuccessMsg, c_Green, t_Hint);
end else begin
    SysMsg(g_sGameCommandReloadLineNoticeFailMsg, c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdReloadManage(Cmd: pTGameCmd; sParam: string);
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if ((sParam <> '') and (sParam = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, ), c_Red, t_Hint);
    Exit;
end;
if sParam = '' then begin
    if g_ManageNPC <> nil then begin
      g_ManageNPC.ClearScript();
      g_ManageNPC.LoadNPCScript();
      SysMsg('重新加载登录脚本完成...', c_Green, t_Hint);
    end else begin
      SysMsg('重新加载登录脚本失败...', c_Green, t_Hint);
    end;
end else begin
    if g_FunctionNPC <> nil then begin
      g_FunctionNPC.ClearScript();
      g_FunctionNPC.LoadNPCScript();
      SysMsg('重新加载功能脚本完成...', c_Green, t_Hint);
    end else begin
      SysMsg('重新加载功能脚本失败...', c_Green, t_Hint);
    end;
    if g_WolShopNPC <> nil then begin
      g_WolShopNPC.ClearScript();
      g_WolShopNPC.LoadNPCScript();
      SysMsg('重新加载商城脚本完成...', c_Green, t_Hint);
    end else begin
      SysMsg('重新加载商城脚本失败...', c_Green, t_Hint);
    end;
end;
end;

procedure TPlayObject.CmdReloadMonItems;                                                            //
//var
//i                              : Integer;
//Monster                        : pTMonInfo;
begin
if (m_btPermissionGM < 6) then Exit;
SysMsg('该命令已经取消,请使用重新加载怪物数据库命令...', c_Green, t_Hint);
//EnterCriticalSection(ProcessHumanCriticalSection);
//try
//    for i := 0 to UserEngine.MonsterList.Count - 1 do begin
//      Monster := pTMonInfo(UserEngine.MonsterList.Values]);
      //FrmDB.LoadMonitems(UserEngine.MonsterList.Keys, Monster.ItemList);
//    end;
//    SysMsg('怪物爆物品列表重加载完成...', c_Green, t_Hint);
//finally
//    LeaveCriticalSection(ProcessHumanCriticalSection);
//end;
end;

procedure TPlayObject.CmdReloadNpc(sParam: string);                                                 //004CFFF8
var
i                                     : Integer;
tmpList                               : TList;
Merchant                              : TMerchant;
NPC                                 : TNormNpc;
begin
if (m_btPermissionGM < 6) then Exit;
if CompareText('all', sParam) = 0 then begin
    FrmDB.ReLoadMerchants();
    UserEngine.ReloadMerchantList();
    SysMsg('交易NPC重新加载完成!!!', c_Red, t_Hint);
    UserEngine.ReloadNpcList();
    SysMsg('管理NPC重新加载完成!!!', c_Red, t_Hint);
    Exit;
end;                                                                                              //004D0136
tmpList := TList.Create;
if UserEngine.GetMerchantList(m_PEnvir, m_nCurrX, m_nCurrY, 9, tmpList) > 0 then begin
    for i := 0 to tmpList.Count - 1 do begin
      Merchant := TMerchant(tmpList.Items);
      Merchant.ClearScript;
      Merchant.LoadNPCScript;
      SysMsg(Merchant.m_sCharName + '重新加载成功...', c_Green, t_Hint);
    end;                                                                                          // for
end else begin
    SysMsg('附近未发现任何交易NPC!!!', c_Red, t_Hint);
end;
tmpList.Clear;
if UserEngine.GetNpcList(m_PEnvir, m_nCurrX, m_nCurrY, 9, tmpList) > 0 then begin
    for i := 0 to tmpList.Count - 1 do begin
      NPC := TNormNpc(tmpList.Items);
      NPC.ClearScript;
      NPC.LoadNPCScript;
      SysMsg(NPC.m_sCharName + '重新加载成功...', c_Green, t_Hint);
    end;                                                                                          // for
end else begin
    SysMsg('附近未发现任何管理NPC!!!', c_Red, t_Hint);
end;
tmpList.free;
end;

procedure TPlayObject.CmdReloadRobot;
begin
RobotManage.RELOADROBOT();
SysMsg('重新加载机器人配置完成...', c_Green, t_Hint);
end;

procedure TPlayObject.CmdReloadRobotManage;
begin
if (m_btPermissionGM < 6) then Exit;
if g_RobotNPC <> nil then begin
    g_RobotNPC.ClearScript();
    g_RobotNPC.LoadNPCScript();
    SysMsg('重新加载机器人专用脚本完成...', c_Green, t_Hint);
end else begin
    SysMsg('重新加载机器人专用脚本失败...', c_Green, t_Hint);
end;
end;

procedure TPlayObject.CmdReNewLevel(Cmd: pTGameCmd; sHumanName, sLevel: string);
var
PlayObject                            : TPlayObject;
nLevel                              : Integer;
begin
if (m_btPermissionGM < 6) then Exit;
if (sHumanName = '') or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg('命令格式: @' + Cmd.sCmd +
      ' 人物名称 点数(为空则查看)', c_Red, t_Hint);
    Exit;
end;
nLevel := Str_ToInt(sLevel, -1);
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject <> nil then begin
    if (nLevel >= 0) and (nLevel <= 255) then begin
      PlayObject.m_btReLevel := nLevel;
      PlayObject.RefShowName();
    end;
    SysMsg(sHumanName + ' 的转生等级为 ' +
      IntToStr(PlayObject.m_btReLevel), c_Green, t_Hint);
end else begin
    SysMsg(sHumanName + ' 没在线上!!!', c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdRestBonuPoint(Cmd: pTGameCmd; sHumName: string);
var
PlayObject                            : TPlayObject;
nTotleUsePoint                        : Integer;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if sHumName = '' then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称', c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumName);
if PlayObject <> nil then begin
    nTotleUsePoint := PlayObject.m_BonusAbil.DC +
      PlayObject.m_BonusAbil.MC +
      PlayObject.m_BonusAbil.SC +
      PlayObject.m_BonusAbil.AC +
      PlayObject.m_BonusAbil.MAC +
      PlayObject.m_BonusAbil.HP +
      PlayObject.m_BonusAbil.MP +
      PlayObject.m_BonusAbil.Hit +
      PlayObject.m_BonusAbil.Speed +
      PlayObject.m_BonusAbil.X2;
    FillChar(PlayObject.m_BonusAbil, SizeOf(TNakedAbility), #0);

    Inc(PlayObject.m_nBonusPoint, nTotleUsePoint);
    PlayObject.SendMsg(PlayObject, RM_ADJUST_BONUS, 0, 0, 0, 0, '');
    PlayObject.HasLevelUp(0);
    PlayObject.SysMsg('分配点数已复位!!!', c_Red, t_Hint);
    SysMsg(sHumName + ' 的分配点数已复位.', c_Green, t_Hint);
end else begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdSbkDoorControl(sCmd, sParam: string);
begin

end;

procedure TPlayObject.CmdSearchDear(sCmd, sParam: string);
begin
if (sParam <> '') and (sParam = '?') then begin
    SysMsg('此命令用于查询配偶当前所在位置。', c_Red, t_Hint);
    Exit;
end;
if m_sDearName = '' then begin
    SysMsg(g_sYouAreNotMarryedMsg {'你都没结婚查什么?'}, c_Red,
      t_Hint);
    Exit;
end;
if m_DearHuman = nil then begin
    if m_btGender = 0 then begin
      SysMsg(g_sYourWifeNotOnlineMsg {'你的老婆还没有上线!!!'},
      c_Red, t_Hint);
    end else begin
      SysMsg(g_sYourHusbandNotOnlineMsg
      {'你的老公还没有上线!!!'}, c_Red, t_Hint);
    end;
    Exit;
end;

if m_btGender = 0 then begin
    SysMsg(g_sYourWifeNowLocateMsg {'你的老婆现在位于:'}, c_Green,
      t_Hint);
    SysMsg(m_DearHuman.m_sCharName + ' ' + m_DearHuman.m_PEnvir.m_sMapDesc + '(' +
      IntToStr(m_DearHuman.m_nCurrX) + ':' + IntToStr(m_DearHuman.m_nCurrY) + ')',
      c_Green, t_Hint);
    m_DearHuman.SysMsg(g_sYourHusbandSearchLocateMsg
      {'你的老公正在找你,他现在位于:'}, c_Green, t_Hint);
    m_DearHuman.SysMsg(m_sCharName + ' ' + m_PEnvir.m_sMapDesc + '(' +
      IntToStr(m_nCurrX) + ':' + IntToStr(m_nCurrY) + ')', c_Green, t_Hint);
end else begin
    SysMsg(g_sYourHusbandNowLocateMsg {'你的老公现在位于:'}, c_Red,
      t_Hint);
    SysMsg(m_DearHuman.m_sCharName + ' ' + m_DearHuman.m_PEnvir.m_sMapDesc + '(' +
      IntToStr(m_DearHuman.m_nCurrX) + ':' + IntToStr(m_DearHuman.m_nCurrY) + ')',
      c_Green, t_Hint);
    m_DearHuman.SysMsg(g_sYourWifeSearchLocateMsg
      {'你的老婆正在找你,她现在位于:'}, c_Green, t_Hint);
    m_DearHuman.SysMsg(m_sCharName + ' ' + m_PEnvir.m_sMapDesc + '(' +
      IntToStr(m_nCurrX) + ':' + IntToStr(m_nCurrY) + ')', c_Green, t_Hint);
end;

end;

procedure TPlayObject.CmdSearchHuman(sCmd, sHumanName: string);
var
PlayObject                            : TPlayObject;
begin
if m_boProbeNecklace or (m_btPermissionGM >= 6) then begin
    if (sHumanName = '') then begin
      SysMsg('命令格式: @' + sCmd + ' 人物名称', c_Red, t_Hint);
      Exit;
    end;
    if ((GetTickCount - m_dwProbeTick) > 10000) or (m_btPermissionGM >= 3) then begin
      m_dwProbeTick := GetTickCount();
      PlayObject := UserEngine.GetPlayObject(sHumanName);
      if PlayObject <> nil then begin
      SysMsg(sHumanName + ' 现在位于 ' + PlayObject.m_PEnvir.m_sMapDesc + ' '
          + IntToStr(PlayObject.m_nCurrX) + ':' + IntToStr(PlayObject.m_nCurrY),
          c_Blue, t_Hint);
      end else begin
      SysMsg(sHumanName +
          ' 现在不在线,或位于其它服务器上!!!', c_Red,
          t_Hint);
      end;
    end else begin
      SysMsg(IntToStr((GetTickCount - m_dwProbeTick) div 1000 - 10) +
      ' 秒之后才可以再使用此功能!!!', c_Red, t_Hint);
    end;
end else begin
    SysMsg('您现在还无法使用此功能!!!', c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdSearchMaster(sCmd, sParam: string);
var
i                                     : Integer;
human                                 : TPlayObject;
begin
if (sParam <> '') and (sParam = '?') then begin
    SysMsg('此命令用于查询师徒当前所在位置。', c_Red, t_Hint);
    Exit;
end;
if m_sMasterName = '' then begin
    SysMsg(g_sYouAreNotMasterMsg, c_Red, t_Hint);
    Exit;
end;
if m_boMaster then begin
    if m_MasterList.Count <= 0 then begin
      SysMsg(g_sYourMasterListNotOnlineMsg, c_Red, t_Hint);
      Exit;
    end;
    SysMsg(g_sYourMasterListNowLocateMsg, c_Green, t_Hint);
    for i := 0 to m_MasterList.Count - 1 do begin
      human := TPlayObject(m_MasterList.Items);
      SysMsg(human.m_sCharName + ' ' + human.m_PEnvir.m_sMapDesc + '(' +
      IntToStr(human.m_nCurrX) + ':' + IntToStr(human.m_nCurrY) + ')', c_Green,
      t_Hint);
      human.SysMsg(g_sYourMasterSearchLocateMsg, c_Green, t_Hint);
      human.SysMsg(m_sCharName + ' ' + m_PEnvir.m_sMapDesc + '(' +
      IntToStr(m_nCurrX) + ':' + IntToStr(m_nCurrY) + ')', c_Green, t_Hint);
    end;
end else begin
    if m_MasterHuman = nil then begin
      SysMsg(g_sYourMasterNotOnlineMsg, c_Red, t_Hint);
      Exit;
    end;
    SysMsg(g_sYourMasterNowLocateMsg, c_Red, t_Hint);
    SysMsg(m_MasterHuman.m_sCharName + ' ' + m_MasterHuman.m_PEnvir.m_sMapDesc +
      '(' + IntToStr(m_MasterHuman.m_nCurrX) + ':' +
      IntToStr(m_MasterHuman.m_nCurrY) + ')', c_Green, t_Hint);
    m_MasterHuman.SysMsg(g_sYourMasterListSearchLocateMsg, c_Green, t_Hint);
    m_MasterHuman.SysMsg(m_sCharName + ' ' + m_PEnvir.m_sMapDesc + '(' +
      IntToStr(m_nCurrX) + ':' + IntToStr(m_nCurrY) + ')', c_Green, t_Hint);
end;
end;

procedure TPlayObject.CmdSetMapMode(sCmd, sMapName, sMapMode, sParam1,
sParam2: string);
var
Envir                                 : TEnvirnoment;
sMsg                                  : string;
begin
if (m_btPermissionGM < 6) then Exit;
if (sMapName = '') or (sMapMode = '') then begin
    SysMsg('命令格式: @' + sCmd + ' 地图号 模式', c_Red, t_Hint);
    Exit;
end;
Envir := g_MapManager.FindMap(sMapName);
if (Envir = nil) then begin
    SysMsg(sMapName + ' 不存在!!!', c_Red, t_Hint);
    Exit;
end;
if CompareText(sMapMode, 'SAFE') = 0 then begin
    if (sParam1 <> '') then begin
      Envir.m_MapFlag.boSAFE := True;
    end else begin
      Envir.m_MapFlag.boSAFE := False;
    end;
end else
    if CompareText(sMapMode, 'DARK') = 0 then begin
      if (sParam1 <> '') then begin
      Envir.m_MapFlag.boDARK := True;
      end else begin
      Envir.m_MapFlag.boDARK := False;
      end;
    end else
      if CompareText(sMapMode, 'DARK') = 0 then begin
      if (sParam1 <> '') then begin
          Envir.m_MapFlag.boDARK := True;
      end else begin
          Envir.m_MapFlag.boDARK := False;
      end;
      end else
      if CompareText(sMapMode, 'FIGHT') = 0 then begin
          if (sParam1 <> '') then begin
            Envir.m_MapFlag.boFight := True;
          end else begin
            Envir.m_MapFlag.boFight := False;
          end;
      end else
          if CompareText(sMapMode, 'FIGHT3') = 0 then begin
            if (sParam1 <> '') then begin
            Envir.m_MapFlag.boFight3 := True;
            end else begin
            Envir.m_MapFlag.boFight3 := False;
            end;
          end else
            if CompareText(sMapMode, 'DAY') = 0 then begin
            if (sParam1 <> '') then begin
                Envir.m_MapFlag.boDAY := True;
            end else begin
                Envir.m_MapFlag.boDAY := False;
            end;
            end else
            if CompareText(sMapMode, 'QUIZ') = 0 then begin
                if (sParam1 <> '') then begin
                  Envir.m_MapFlag.boQUIZ := True;
                end else begin
                  Envir.m_MapFlag.boQUIZ := False;
                end;
            end else
                if CompareText(sMapMode, 'NORECONNECT') = 0 then begin
                  if (sParam1 <> '') then begin
                  Envir.m_MapFlag.boNORECONNECT := True;
                  Envir.m_MapFlag.sReConnectMap := sParam1;
                  end else begin
                  Envir.m_MapFlag.boNORECONNECT := False;
                  end;
                end else
                  if CompareText(sMapMode, 'MUSIC') = 0 then begin
                  if (sParam1 <> '') then begin
                      Envir.m_MapFlag.boMUSIC := True;
                      Envir.m_MapFlag.nMUSICID := Str_ToInt(sParam1, -1);
                  end else begin
                      Envir.m_MapFlag.boMUSIC := False;
                  end;
                  end else
                  if CompareText(sMapMode, 'EXPRATE') = 0 then begin
                      if (sParam1 <> '') then begin
                        Envir.m_MapFlag.boEXPRATE := True;
                        Envir.m_MapFlag.nEXPRATE := Str_ToInt(sParam1, -1);
                      end else begin
                        Envir.m_MapFlag.boEXPRATE := False;
                      end;
                  end else
                      if CompareText(sMapMode, 'PKWINLEVEL') = 0 then begin
                        if (sParam1 <> '') then begin
                        Envir.m_MapFlag.boPKWINLEVEL := True;
                        Envir.m_MapFlag.nPKWINLEVEL := Str_ToInt(sParam1, -1);
                        end else begin
                        Envir.m_MapFlag.boPKWINLEVEL := False;
                        end;
                      end else
                        if CompareText(sMapMode, 'PKWINEXP') = 0 then begin
                        if (sParam1 <> '') then begin
                            Envir.m_MapFlag.boPKWINEXP := True;
                            Envir.m_MapFlag.nPKWINEXP := Str_ToInt(sParam1, -1);
                        end else begin
                            Envir.m_MapFlag.boPKWINEXP := False;
                        end;
                        end else
                        if CompareText(sMapMode, 'PKLOSTLEVEL') = 0 then begin
                            if (sParam1 <> '') then begin
                              Envir.m_MapFlag.boPKLOSTLEVEL := True;
                              Envir.m_MapFlag.nPKLOSTLEVEL := Str_ToInt(sParam1, -1);
                            end else begin
                              Envir.m_MapFlag.boPKLOSTLEVEL := False;
                            end;
                        end else
                            if CompareText(sMapMode, 'PKLOSTEXP') = 0 then begin
                              if (sParam1 <> '') then begin
                              Envir.m_MapFlag.boPKLOSTEXP := True;
                              Envir.m_MapFlag.nPKLOSTEXP := Str_ToInt(sParam1, -1);
                              end else begin
                              Envir.m_MapFlag.boPKLOSTEXP := False;
                              end;
                            end else
                              if CompareText(sMapMode, 'DECHP') = 0 then begin
                              if (sParam1 <> '') and (sParam2 <> '') then begin
                                  Envir.m_MapFlag.boDECHP := True;
                                  Envir.m_MapFlag.nDECHPTIME := Str_ToInt(sParam1, -1);
                                  Envir.m_MapFlag.nDECHPPOINT := Str_ToInt(sParam2, -1);
                              end else begin
                                  Envir.m_MapFlag.boDECHP := False;
                              end;
                              end else
                              if CompareText(sMapMode, 'DECGAMEGOLD') = 0 then begin
                                  if (sParam1 <> '') and (sParam2 <> '') then begin
                                    Envir.m_MapFlag.boDecGameGold := True;
                                    Envir.m_MapFlag.nDECGAMEGOLDTIME :=
                                    Str_ToInt(sParam1, -1);
                                    Envir.m_MapFlag.nDecGameGold := Str_ToInt(sParam2,
                                    -1);
                                  end else begin
                                    Envir.m_MapFlag.boDecGameGold := False;
                                  end;
                              end else
                                  if CompareText(sMapMode, 'INCGAMEGOLD') = 0 then begin
                                    if (sParam1 <> '') and (sParam2 <> '') then begin
                                    Envir.m_MapFlag.boIncGameGold := True;
                                    Envir.m_MapFlag.nINCGAMEGOLDTIME :=
                                        Str_ToInt(sParam1, -1);
                                    Envir.m_MapFlag.nIncGameGold := Str_ToInt(sParam2,
                                        -1);
                                    end else begin
                                    Envir.m_MapFlag.boIncGameGold := False;
                                    end;
                                  end else
                                    if CompareText(sMapMode, 'INCGAMEPOINT') = 0 then begin
                                    if (sParam1 <> '') and (sParam2 <> '') then begin
                                        Envir.m_MapFlag.boINCGAMEPOINT := True;
                                        Envir.m_MapFlag.nINCGAMEPOINTTIME :=
                                          Str_ToInt(sParam1, -1);
                                        Envir.m_MapFlag.nINCGAMEPOINT :=
                                          Str_ToInt(sParam2, -1);
                                    end else begin
                                        Envir.m_MapFlag.boIncGameGold := False;
                                    end;
                                    end else
                                    if CompareText(sMapMode, 'RUNHUMAN') = 0 then begin
                                        if (sParam1 <> '') then begin
                                          Envir.m_MapFlag.boRUNHUMAN := True;
                                        end else begin
                                          Envir.m_MapFlag.boRUNHUMAN := False;
                                        end;
                                    end else
                                        if CompareText(sMapMode, 'RUNMON') = 0 then begin
                                          if (sParam1 <> '') then begin
                                          Envir.m_MapFlag.boRUNMON := True;
                                          end else begin
                                          Envir.m_MapFlag.boRUNMON := False;
                                          end;
                                        end else
                                          if CompareText(sMapMode, 'NEEDHOLE') =
                                          0 then begin
                                          if (sParam1 <> '') then begin
                                              Envir.m_MapFlag.boNEEDHOLE := True;
                                          end else begin
                                              Envir.m_MapFlag.boNEEDHOLE := False;
                                          end;
                                          end else
                                          if CompareText(sMapMode, 'NORECALL')
                                              = 0 then begin
                                              if (sParam1 <> '') then begin
                                                Envir.m_MapFlag.boNORECALL := True;
                                              end else begin
                                                Envir.m_MapFlag.boNORECALL := False;
                                              end;
                                          end else
                                              if CompareText(sMapMode,
                                                'NOGUILDRECALL') = 0 then begin
                                                if (sParam1 <> '') then begin
                                                Envir.m_MapFlag.boNOGUILDRECALL :=
                                                    True;
                                                end else begin
                                                Envir.m_MapFlag.boNOGUILDRECALL :=
                                                    False;
                                                end;
                                              end else
                                                if CompareText(sMapMode,
                                                'NODEARRECALL') = 0 then begin
                                                if (sParam1 <> '') then begin
                                                    Envir.m_MapFlag.boNODEARRECALL :=
                                                      True;
                                                end else begin
                                                    Envir.m_MapFlag.boNODEARRECALL :=
                                                      False;
                                                end;
                                                end else
                                                if CompareText(sMapMode,
                                                    'NOMASTERRECALL') = 0 then begin
                                                    if (sParam1 <> '') then begin
                                                      Envir.m_MapFlag.boNOMASTERRECALL
                                                      := True;
                                                    end else begin
                                                      Envir.m_MapFlag.boNOMASTERRECALL
                                                      := False;
                                                    end;
                                                end else
                                                    if CompareText(sMapMode,
                                                      'NORANDOMMOVE') = 0 then begin
                                                      if (sParam1 <> '') then begin
                                                      Envir.m_MapFlag.boNORANDOMMOVE
                                                          := True;
                                                      end else begin
                                                      Envir.m_MapFlag.boNORANDOMMOVE
                                                          := False;
                                                      end;
                                                    end else
                                                      if CompareText(sMapMode,
                                                      'NODRUG') = 0 then begin
                                                      if (sParam1 <> '') then begin
                                                          Envir.m_MapFlag.boNODRUG :=
                                                            True;
                                                      end else begin
                                                          Envir.m_MapFlag.boNODRUG :=
                                                            False;
                                                      end;
                                                      end else
                                                      if CompareText(sMapMode,
                                                          'MINE') = 0 then begin
                                                          if (sParam1 <> '') then begin
                                                            Envir.m_MapFlag.boMINE :=
                                                            True;
                                                          end else begin
                                                            Envir.m_MapFlag.boMINE :=
                                                            False;
                                                          end;
                                                      end else
                                                          if
                                                            CompareText(sMapMode,
                                                            'NOPOSITIONMOVE') = 0 then begin
                                                            if (sParam1 <> '') then begin
                                                            Envir.m_MapFlag.boNOPOSITIONMOVE
                                                                := True;
                                                            end else begin
                                                            Envir.m_MapFlag.boNOPOSITIONMOVE
                                                                := False;
                                                            end;
                                                          end else                                  //
                                                            if
                                                            CompareText(sMapMode,
                                                            'NOSTOREMOVE') = 0 then begin
                                                            if (sParam1 <> '') then begin
                                                                Envir.m_MapFlag.boNOSTOREMOVE
                                                                  := True;
                                                            end else begin
                                                                Envir.m_MapFlag.boNOSTOREMOVE
                                                                  := False;
                                                            end;
                                                            end;
sMsg := '地图模式: ' + Envir.GetEnvirInfo;
SysMsg(sMsg, c_Blue, t_Hint);
end;

procedure TPlayObject.CmdSetPermission(Cmd: pTGameCmd; sHumanName, sPermission:
string);
var
nPerission                            : Integer;
PlayObject                            : TPlayObject;
resourcestring
sOutFormatMsg                         = '[权限调整] %s (%s %d -> %d)';
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
nPerission := Str_ToInt(sPermission, 0);
if (sHumanName = '') or not (nPerission in ) then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称 权限等级(0 - 10)',
      c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
if g_Config.boShowMakeItemMsg then
    MainOutMessage(Format(sOutFormatMsg, [m_sCharName, PlayObject.m_sCharName,
      PlayObject.m_btPermissionGM, nPerission]));
PlayObject.m_btPermissionGM := nPerission;
SysMsg(sHumanName + ' 当前权限为: ' +
    IntToStr(PlayObject.m_btPermissionGM), c_Red, t_Hint);
end;

procedure TPlayObject.CmdShowDenyAccountLogon(Cmd: pTGameCmd; sAccount,
sFixDeny: string);
var
i                                     : Integer;
begin
if (m_btPermissionGM < 6) then Exit;
g_DenyAccountList.Lock;
try
    if g_DenyAccountList.Count <= 0 then begin
      SysMsg('禁止登录帐号列表为空。', c_Green, t_Hint);
      Exit;
    end;
    for i := 0 to g_DenyAccountList.Count - 1 do begin
      SysMsg(g_DenyAccountList.Strings, c_Green, t_Hint);
    end;
finally
    g_DenyAccountList.UnLock;
end;
end;

procedure TPlayObject.CmdShowDenyCharNameLogon(Cmd: pTGameCmd; sCharName,
sFixDeny: string);
var
i                                     : Integer;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
g_DenyChrNameList.Lock;
try
    if g_DenyChrNameList.Count <= 0 then begin
      SysMsg('禁止登录角色列表为空。', c_Green, t_Hint);
      Exit;
    end;
    for i := 0 to g_DenyChrNameList.Count - 1 do begin
      SysMsg(g_DenyChrNameList.Strings, c_Green, t_Hint);
    end;
finally
    g_DenyChrNameList.UnLock;
end;
end;

procedure TPlayObject.CmdShowDenyIPaddrLogon(Cmd: pTGameCmd; sIPaddr,
sFixDeny: string);
var
i                                     : Integer;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
g_DenyIPAddrList.Lock;
try
    if g_DenyIPAddrList.Count <= 0 then begin
      SysMsg('禁止登录角色列表为空。', c_Green, t_Hint);
      Exit;
    end;
    for i := 0 to g_DenyIPAddrList.Count - 1 do begin
      SysMsg(g_DenyIPAddrList.Strings, c_Green, t_Hint);
    end;
finally
    g_DenyIPAddrList.UnLock;
end;
end;

procedure TPlayObject.CmdShowHumanFlag(sCmd: string; nPermission: Integer;
sHumanName, sFlag: string);
var
PlayObject                            : TPlayObject;
nFlag                                 : Integer;
begin
if (m_btPermissionGM < nPermission) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [sCmd,
      g_sGameCommandShowHumanFlagHelpMsg]), c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
nFlag := Str_ToInt(sFlag, 0);
if PlayObject.GetQuestFalgStatus(nFlag) = 1 then begin
    SysMsg(Format(g_sGameCommandShowHumanFlagONMsg, [PlayObject.m_sCharName,
      nFlag]), c_Green, t_Hint);
end else begin
    SysMsg(Format(g_sGameCommandShowHumanFlagOFFMsg, [PlayObject.m_sCharName,
      nFlag]), c_Green, t_Hint);
end;
end;

procedure TPlayObject.CmdShowHumanUnit(sCmd: string; nPermission: Integer;
sHumanName, sUnit: string);
var
PlayObject                            : TPlayObject;
nUnit                                 : Integer;
begin
if (m_btPermissionGM < nPermission) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [sCmd,
      g_sGameCommandShowHumanUnitHelpMsg]), c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
nUnit := Str_ToInt(sUnit, 0);
if PlayObject.GetQuestUnitStatus(nUnit) = 1 then begin
    SysMsg(Format(g_sGameCommandShowHumanUnitONMsg, [PlayObject.m_sCharName,
      nUnit]), c_Green, t_Hint);
end else begin
    SysMsg(Format(g_sGameCommandShowHumanUnitOFFMsg, [PlayObject.m_sCharName,
      nUnit]), c_Green, t_Hint);
end;
end;

procedure TPlayObject.CmdShowHumanUnitOpen(sCmd: string; nPermission: Integer;
sHumanName, sUnit: string);
var
PlayObject                            : TPlayObject;
nUnit                                 : Integer;
begin
if (m_btPermissionGM < nPermission) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [sCmd,
      g_sGameCommandShowHumanUnitHelpMsg]), c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
nUnit := Str_ToInt(sUnit, 0);
if PlayObject.GetQuestUnitOpenStatus(nUnit) = 1 then begin
    SysMsg(Format(g_sGameCommandShowHumanUnitONMsg, [PlayObject.m_sCharName,
      nUnit]), c_Green, t_Hint);
end else begin
    SysMsg(Format(g_sGameCommandShowHumanUnitOFFMsg, [PlayObject.m_sCharName,
      nUnit]), c_Green, t_Hint);
end;
end;

procedure TPlayObject.CmdShowMapInfo(Cmd: pTGameCmd; sParam1: string);
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if ((sParam1 <> '') and (sParam1 = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, ), c_Red, t_Hint);
    Exit;
end;
SysMsg(Format(g_sGameCommandMapInfoMsg, [m_PEnvir.m_sMapName,
    m_PEnvir.m_sMapDesc]), c_Green, t_Hint);
SysMsg(Format(g_sGameCommandMapInfoSizeMsg, [m_PEnvir.m_nWidth,
    m_PEnvir.m_nHeight]), c_Green, t_Hint);
end;

procedure TPlayObject.CmdShowMapMode(sCmd, sMapName: string);
var
Envir                                 : TEnvirnoment;
sMsg                                  : string;
begin
if (m_btPermissionGM < 6) then Exit;
if (sMapName = '') then begin
    SysMsg('命令格式: @' + sCmd + ' 地图号', c_Red, t_Hint);
    Exit;
end;
Envir := g_MapManager.FindMap(sMapName);
if (Envir = nil) then begin
    SysMsg(sMapName + ' 不存在!!!', c_Red, t_Hint);
    Exit;
end;
sMsg := '地图模式: ' + Envir.GetEnvirInfo;
SysMsg(sMsg, c_Blue, t_Hint);
end;

procedure TPlayObject.CmdShowSbkGold(Cmd: pTGameCmd; sCASTLENAME, sCtr, sGold:
string);
var
i                                     : Integer;
Ctr                                 : Char;
nGold                                 : Integer;
Castle                              : TUserCastle;
List                                  : TStringList;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if ((sCASTLENAME <> '') and (sCASTLENAME = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, ), c_Red, t_Hint);
    Exit;
end;
if sCASTLENAME = '' then begin
    List := TStringList.Create;
    g_CastleManager.GetCastleGoldInfo(List);
    for i := 0 to List.Count - 1 do begin
      SysMsg(List.Strings, c_Green, t_Hint);
    end;
    List.free;
    Exit;
end;
Castle := g_CastleManager.Find(sCASTLENAME);
if Castle = nil then begin
    SysMsg(Format(g_sGameCommandSbkGoldCastleNotFoundMsg, ), c_Red,
      t_Hint);
    Exit;
end;

Ctr := sCtr;
nGold := Str_ToInt(sGold, -1);
if not (Ctr in ['=', '-', '+']) or (nGold < 0) or (nGold > 100000000) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandSbkGoldHelpMsg]), c_Red, t_Hint);
    Exit;
end;

case Ctr of
    '=': Castle.m_nTotalGold := nGold;
    '-': Dec(Castle.m_nTotalGold);
    '+': Inc(Castle.m_nTotalGold, nGold);
end;
if Castle.m_nTotalGold < 0 then Castle.m_nTotalGold := 0;

end;

procedure TPlayObject.CmdShowUseItemInfo(Cmd: pTGameCmd;
sHumanName: string);
var
i                                     : Integer;
PlayObject                            : TPlayObject;
UserItem                              : pTUserItem;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandShowUseItemInfoHelpMsg]), c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
for i := Low(PlayObject.m_UseItems) to High(PlayObject.m_UseItems) do begin
    UserItem := @PlayObject.m_UseItems;
    if UserItem.wIndex = 0 then Continue;
    SysMsg(Format('%s[%s]IDX[%d]系列号[%d]持久[%d-%d]',
      [GetUseItemName(i),
      UserEngine.GetStdItemName(UserItem.wIndex),
      UserItem.wIndex,
      UserItem.MakeIndex,
      UserItem.Dura,
      UserItem.DuraMax]),
      c_Blue, t_Hint);
end;
end;

procedure TPlayObject.CmdShutup(Cmd: pTGameCmd; sHumanName, sTime: string);
var
dwTime                              : LongWord;
nIndex                              : Integer;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sTime = '') or (sHumanName = '') or ((sHumanName <> '') and (sHumanName
    = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandShutupHelpMsg]), c_Red, t_Hint);
    Exit;
end;

dwTime := Str_ToInt(sTime, 5);
g_DenySayMsgList.Lock;
try
    nIndex := g_DenySayMsgList.GetIndex(sHumanName);
    if nIndex >= 0 then begin
      g_DenySayMsgList.Objects := TObject(GetTickCount + dwTime * 60 *
      1000);
    end else begin
      g_DenySayMsgList.AddRecord(sHumanName, GetTickCount + dwTime * 60 * 1000);
    end;
finally
    g_DenySayMsgList.UnLock;
end;
SysMsg(Format(g_sGameCommandShutupHumanMsg, ), c_Red,
    t_Hint);
end;

procedure TPlayObject.CmdShutupList(Cmd: pTGameCmd; sParam1: string);
var
i                                     : Integer;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if ((sParam1 <> '') and (sParam1 = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, ), c_Red, t_Hint);
    Exit;
end;

if (m_btPermissionGM < 6) then Exit;
g_DenySayMsgList.Lock;
try
    if g_DenySayMsgList.Count <= 0 then begin
      SysMsg(g_sGameCommandShutupListIsNullMsg, c_Green, t_Hint);
      Exit;
    end;
    for i := 0 to g_DenySayMsgList.Count - 1 do begin
      SysMsg(g_DenySayMsgList.Strings + ' ' +
      IntToStr((LongWord(g_DenySayMsgList.Objects) - GetTickCount) div
      60000), c_Green, t_Hint);
    end;
finally
    g_DenySayMsgList.UnLock;
end;
end;

procedure TPlayObject.CmdShutupRelease(Cmd: pTGameCmd; sHumanName: string;
boAll: Boolean);
var
i                                     : Integer;
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandShutupReleaseHelpMsg]), c_Red, t_Hint);
    Exit;
end;
g_DenySayMsgList.Lock;
try
    i := g_DenySayMsgList.GetIndex(sHumanName);
    if i >= 0 then begin
      g_DenySayMsgList.Delete(i);
      PlayObject := UserEngine.GetPlayObject(sHumanName);
      if PlayObject <> nil then begin
      PlayObject.SysMsg(g_sGameCommandShutupReleaseCanSendMsg, c_Red, t_Hint);
      end;
      if boAll then begin
      UserEngine.SendServerGroupMsg(SS_210, g_Config.nServerNumber, sHumanName);
      end;
      SysMsg(Format(g_sGameCommandShutupReleaseHumanCanSendMsg, ),
      c_Green, t_Hint);
    end;
finally
    g_DenySayMsgList.UnLock;
end;
end;

procedure TPlayObject.CmdSmakeItem(Cmd: pTGameCmd; nWhere, nValueType: Integer;
sOpCode: string; nValue: Integer);
var
sShowMsg                              : string;
nValType, nPoint, nAddPoint         : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
nOldOverLap                           : DWORD;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;

nValType := nValueType;
nAddPoint := nValue;

if (nWhere >= 0) and (nWhere <= High(THumItems)) then
    UserItem := @m_UseItems
else
    GetUserItemByMakeIndex(nWhere, UserItem);

if (UserItem = nil) or (UserItem.wIndex = 0) then
    StdItem := nil
else
    StdItem := UserEngine.GetStdItem(UserItem.wIndex);

if (StdItem = nil) or (sOpCode = '') or ((sOpCode <> '') and (not (sOpCode in ['+', '-', '=']))) then begin
    SysMsg(g_sGamecommandSuperMakeHelpMsg, c_Red, t_Hint);
    SysMsg('命令格式: @' + Cmd.sCmd + ' 物品(位置: 0..14)编号 属性类型(0..72) 操作符号(+、-、=) 调整数值', c_Red, t_Hint);
    Exit;
end;

case nValType of
    0..12, 15..19: begin                                                                            //极品属性,扩展属性
      nAddPoint := _MIN(High(byte), nAddPoint);
      case sOpCode of
          '+': begin
            if UserItem.btValue + nAddPoint > High(byte) then begin
                nAddPoint := High(byte) - UserItem.btValue
            end;
            UserItem.btValue := UserItem.btValue +
                nAddPoint;
            end;
          '-': begin
            if UserItem.btValue - nAddPoint < 0 then
                UserItem.btValue := 0
            else
                UserItem.btValue := UserItem.btValue -
                  nAddPoint;
            end;
          '=': begin
            UserItem.btValue := nAddPoint;
            end;
      end;
      end;
    13: ;                                                                                           //自定义装备名称
    20: begin
      case sOpCode of
          '+': begin
            if UserItem.Dura + nAddPoint > High(word) then begin
                nAddPoint := High(word) - UserItem.Dura;
            end;
            UserItem.Dura := UserItem.Dura + nAddPoint;
            end;
          '-': begin
            if UserItem.Dura - nAddPoint < 0 then begin
                nAddPoint := UserItem.Dura;
            end;
            UserItem.Dura := UserItem.Dura - nAddPoint;
            end;
          '=': begin
            UserItem.Dura := nAddPoint;
            end;
      end;
      end;
    21: begin
      case sOpCode of
          '+': begin
            if UserItem.DuraMax + nAddPoint > High(word) then begin
                nAddPoint := High(word) - UserItem.DuraMax;
            end;
            UserItem.DuraMax := UserItem.DuraMax + nAddPoint;
            end;
          '-': begin
            if UserItem.DuraMax - nAddPoint < 0 then begin
                nAddPoint := UserItem.DuraMax;
            end;
            UserItem.DuraMax := UserItem.DuraMax - nAddPoint;
            end;
          '=': begin
            UserItem.DuraMax := nAddPoint;
            end;
      end;
      end;
    22: begin                                                                                       //黑暗魔力
      case sOpCode of
          '+': begin
            if MakeWord(UserItem.btItemExt, UserItem.btItemExt) +
                nAddPoint > High(word) then
                nAddPoint := High(word)
            else
                nAddPoint := MakeWord(UserItem.btItemExt,
                  UserItem.btItemExt) + nAddPoint;
            UserItem.btItemExt := LoByte(nAddPoint);
            UserItem.btItemExt := HiByte(nAddPoint);
            end;
          '-': begin
            if MakeWord(UserItem.btItemExt, UserItem.btItemExt) -
                nAddPoint < 0 then
                nAddPoint := 0
            else
                nAddPoint := MakeWord(UserItem.btItemExt,
                  UserItem.btItemExt) - nAddPoint;
            UserItem.btItemExt := LoByte(nAddPoint);
            UserItem.btItemExt := HiByte(nAddPoint);
            end;
          '=': begin
            UserItem.btItemExt := LoByte(nAddPoint);
            UserItem.btItemExt := HiByte(nAddPoint);
            end;
      end;
      end;
    23..38: begin                                                                                 //黑暗属性下限
      nValType := nValType - 23;
      case sOpCode of
          '+': begin
            if _Hi(UserItem.btItemExt) + nAddPoint > $0F then
                nAddPoint := $0F
            else
                nAddPoint := _Hi(UserItem.btItemExt) + nAddPoint;
            UserItem.btItemExt :=
                _SetHi(UserItem.btItemExt, nAddPoint);
            end;
          '-': begin
            if _Hi(UserItem.btItemExt) < nAddPoint then
                nAddPoint := $00
            else
                nAddPoint := _Hi(UserItem.btItemExt) - nAddPoint;
            UserItem.btItemExt :=
                _SetHi(UserItem.btItemExt, nAddPoint);
            end;
          '=': begin
            UserItem.btItemExt :=
                _SetHi(UserItem.btItemExt, nAddPoint);
            end;
      end;
      end;
    39..54: begin                                                                                 //黑暗属性上限
      nValType := nValType - 39;
      case sOpCode of
          '+': begin
            if _Lo(UserItem.btItemExt) + nAddPoint > $0F then
                nAddPoint := $0F
            else
                nAddPoint := _Lo(UserItem.btItemExt) + nAddPoint;
            UserItem.btItemExt :=
                _SetLo(UserItem.btItemExt, nAddPoint);
            end;
          '-': begin
            if _Lo(UserItem.btItemExt) < nAddPoint then
                nAddPoint := $00
            else
                nAddPoint := _Lo(UserItem.btItemExt) - nAddPoint;
            UserItem.btItemExt :=
                _SetLo(UserItem.btItemExt, nAddPoint);
            end;
          '=': begin
            UserItem.btItemExt :=
                _SetLo(UserItem.btItemExt, nAddPoint);
            end;
      end;
      end;
    66: begin
      nValType := nValType - 55;
      case sOpCode of
          '+': begin
            if UserItem.btItemExt + nAddPoint > $FF then
                nAddPoint := $FF
            else
                nAddPoint := UserItem.btItemExt + nAddPoint;
            UserItem.btItemExt := nAddPoint + StdItem.NeedLevel;
            end;
          '-': begin
            if UserItem.btItemExt < nAddPoint then
                nAddPoint := $00
            else
                nAddPoint := UserItem.btItemExt - nAddPoint;
            UserItem.btItemExt := nAddPoint;
            end;
          '=': begin
            UserItem.btItemExt := nAddPoint;
            end;
      end;
      end;
    55..65, 67..70: begin
      nValType := nValType - 55;
      case sOpCode of
          '+': begin
            if UserItem.btItemExt + nAddPoint > $FF then
                nAddPoint := $FF
            else
                nAddPoint := UserItem.btItemExt + nAddPoint;
            UserItem.btItemExt := nAddPoint;
            end;
          '-': begin
            if UserItem.btItemExt < nAddPoint then
                nAddPoint := $00
            else
                nAddPoint := UserItem.btItemExt - nAddPoint;
            UserItem.btItemExt := nAddPoint;
            end;
          '=': begin
            UserItem.btItemExt := nAddPoint;
            end;
      end;
      end;
    71: begin                                                                                       //重叠物品、神秘符石
      nOldOverLap := MakeLong(MakeWord(UserItem.btValue, UserItem.btValue), MakeWord(UserItem.btValue, UserItem.btValue));
      case sOpCode of
          '+': begin
            if nOldOverLap + nAddPoint > High(DWORD) then
                nAddPoint := High(DWORD)
            else
                nAddPoint := nOldOverLap + nAddPoint;
            UserItem.btValue := LoByte(LoWord(nAddPoint));
            UserItem.btValue := HiByte(LoWord(nAddPoint));
            UserItem.btValue := LoByte(HiWord(nAddPoint));
            UserItem.btValue := HiByte(HiWord(nAddPoint));
            end;
          '-': begin
            if nOldOverLap - nAddPoint < 0 then
                nAddPoint := 0
            else
                nAddPoint := nOldOverLap - nAddPoint;
            UserItem.btValue := LoByte(LoWord(nAddPoint));
            UserItem.btValue := HiByte(LoWord(nAddPoint));
            UserItem.btValue := LoByte(HiWord(nAddPoint));
            UserItem.btValue := HiByte(HiWord(nAddPoint));
            end;
          '=': begin
            UserItem.btValue := LoByte(LoWord(nAddPoint));
            UserItem.btValue := HiByte(LoWord(nAddPoint));
            UserItem.btValue := LoByte(HiWord(nAddPoint));
            UserItem.btValue := HiByte(HiWord(nAddPoint));
            end;
      end;
      end;
    72: begin                                                                                       //魂珠积累经验
      nOldOverLap := MakeLong(MakeWord(UserItem.btItemExt, UserItem.btItemExt), MakeWord(UserItem.btItemExt, UserItem.btItemExt));
      case sOpCode of
          '+': begin
            nAddPoint := nOldOverLap + nAddPoint;
            UserItem.btItemExt := LoByte(LoWord(nAddPoint));
            UserItem.btItemExt := HiByte(LoWord(nAddPoint));
            UserItem.btItemExt := LoByte(HiWord(nAddPoint));
            UserItem.btItemExt := HiByte(HiWord(nAddPoint));
            end;
          '-': begin
            if nOldOverLap - nAddPoint < 0 then
                nAddPoint := 0
            else
                nAddPoint := nOldOverLap - nAddPoint;
            UserItem.btItemExt := LoByte(LoWord(nAddPoint));
            UserItem.btItemExt := HiByte(LoWord(nAddPoint));
            UserItem.btItemExt := LoByte(HiWord(nAddPoint));
            UserItem.btItemExt := HiByte(HiWord(nAddPoint));
            end;
          '=': begin
            UserItem.btItemExt := LoByte(LoWord(nAddPoint));
            UserItem.btItemExt := HiByte(LoWord(nAddPoint));
            UserItem.btItemExt := LoByte(HiWord(nAddPoint));
            UserItem.btItemExt := HiByte(HiWord(nAddPoint));
            end;
      end;
      end;

end;
RecalcAbilitys();
SendUpdateItem(UserItem);
sShowMsg := IntToStr(UserItem.wIndex) + '-' + IntToStr(UserItem.MakeIndex) +
    ' ' +
    IntToStr(UserItem.Dura) + '/' + IntToStr(UserItem.DuraMax) + ' ' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue) + '/' +
    IntToStr(UserItem.btValue);
SysMsg(sShowMsg, c_Blue, t_Hint);
if g_Config.boShowMakeItemMsg then
    MainOutMessage('[物品调整] ' + m_sCharName + '(' + StdItem.Name + ' -> '
      + sShowMsg + ')');
end;

procedure TPlayObject.CmdSpirtStart(sCmd, sParam1: string);
var
nTime                                 : Integer;
dwTime                              : LongWord;
begin
if (m_btPermissionGM < 6) then Exit;
if (sParam1 <> '') and (sParam1 = '?') then begin
    SysMsg('此命令用于开始祈祷生效宝宝叛变。', c_Red, t_Hint);
    Exit;
end;
nTime := Str_ToInt(sParam1, -1);
if nTime > 0 then begin
    dwTime := LongWord(nTime) * 1000;
end else begin
    dwTime := g_Config.dwSpiritMutinyTime;
end;

g_dwSpiritMutinyTick := GetTickCount + dwTime;
SysMsg('祈祷叛变已开始。持续时长 ' + IntToStr(dwTime div 1000) + ' 秒。', c_Green, t_Hint);
end;

procedure TPlayObject.CmdSpirtStop(sCmd, sParam1: string);
begin
if (m_btPermissionGM < 6) then Exit;
if (sParam1 <> '') and (sParam1 = '?') then begin
    SysMsg('此命令用于停止祈祷生效导致宝宝叛变。', c_Red,
      t_Hint);
    Exit;
end;
g_dwSpiritMutinyTick := 0;
SysMsg('祈祷叛变已停止。', c_Green, t_Hint);

end;

procedure TPlayObject.CmdStartContest(Cmd: pTGameCmd; sParam1: string);
//004CF008
var
i, ii                                 : Integer;
List10, List14                        : TList;
PlayObject, PlayObjectA               : TPlayObject;
bo19                                  : Boolean;
s20                                 : string;
Guild                                 : TGuild;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if ((sParam1 <> '') and (sParam1 = '?')) then begin
    SysMsg('开始行会争霸赛。', c_Red, t_Hint);
    SysMsg(Format('命令格式: @%s', ), c_Red, t_Hint);
    Exit;
end;

if not m_PEnvir.m_MapFlag.boFight3 then begin
    SysMsg('此命令不能在当前地图中使用!!!', c_Red, t_Hint);
    Exit;
end;
List10 := TList.Create;
List14 := TList.Create;
UserEngine.GetMapRageHuman(m_PEnvir, m_nCurrX, m_nCurrY, 1000, List10);
for i := 0 to List10.Count - 1 do begin
    PlayObject := TPlayObject(List10.Items);
    if not PlayObject.m_boObMode or not PlayObject.m_boAdminMode then begin
      PlayObject.m_nFightZoneDieCount := 0;
      if PlayObject.m_MyGuild = nil then Continue;
      bo19 := False;
      for ii := 0 to List14.Count - 1 do begin
      PlayObjectA := TPlayObject(List14.Items);
      if PlayObject.m_MyGuild = PlayObjectA.m_MyGuild then
          bo19 := True;
      end;
      if not bo19 then begin
      List14.Add(PlayObject.m_MyGuild);
      end;
    end;
end;
SysMsg('行会争霸赛已经开始。', c_Green, t_Hint);
UserEngine.CryCry(RM_CRY, m_PEnvir, m_nCurrX, m_nCurrY, 1000, g_Config.btCryMsgFColor, g_Config.btCryMsgBColor, '- 行会战争已爆发。');
s20 := '';
for i := 0 to List14.Count - 1 do begin
    Guild := TGuild(List14.Items);
    Guild.StartTeamFight();
    for ii := 0 to List10.Count - 1 do begin
      PlayObject := TPlayObject(List10.Items);
      if PlayObject.m_MyGuild = Guild then begin
      Guild.AddTeamFightMember(PlayObject.m_sCharName);
      end;
    end;
    s20 := s20 + Guild.sGuildName + ' ';
end;
UserEngine.CryCry(RM_CRY, m_PEnvir, m_nCurrX, m_nCurrY, 1000,
    g_Config.btCryMsgFColor, g_Config.btCryMsgBColor, ' -参加的门派:' + s20);
List10.free;
List14.free;
end;

procedure TPlayObject.CmdStartQuest(Cmd: pTGameCmd; sQuestName, sMapName: string);
var
Map                                 : TEnvirnoment;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sQuestName = '') then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 问答名称 地图名称', c_Red, t_Hint);
    Exit;
end;
if (sMapName <> '') then
    Map := g_MapManager.FindMap(sMapName)
else
    Map := nil;
UserEngine.SendQuestMsg(sQuestName, Map);
end;

procedure TPlayObject.CmdSuperTing(Cmd: pTGameCmd; sHumanName, sRange: string);
var
i                                     : Integer;
PlayObject                            : TPlayObject;
MoveHuman                           : TPlayObject;
nRange                              : Integer;
HumanList                           : TList;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sRange = '') or (sHumanName = '') or ((sHumanName <> '') and (sHumanName
    = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandSuperTingHelpMsg]), c_Red, t_Hint);
    Exit;
end;

nRange := _Max(10, Str_ToInt(sRange, 2));
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject <> nil then begin
    HumanList := TList.Create;
    UserEngine.GetMapRageHuman(PlayObject.m_PEnvir, PlayObject.m_nCurrX,
      PlayObject.m_nCurrY, nRange, HumanList);
    for i := 0 to HumanList.Count - 1 do begin
      MoveHuman := TPlayObject(HumanList.Items);
      if MoveHuman <> Self then
      MoveHuman.MapRandomMove(MoveHuman.m_sHomeMap, 0, nil);
    end;
    HumanList.free;
end else begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
end;

end;

procedure TPlayObject.CmdTakeOffHorse(sCmd, sParam: string);
begin
if (sParam <> '') and (sParam = '?') then begin
    SysMsg('下马命令,在骑马状态输入此命令下马。', c_Red,
      t_Hint);
    SysMsg(Format('命令格式: @%s', ), c_Red, t_Hint);
    Exit;
end;
if m_boRideOn then ClientRideOff;
FeatureChanged();
end;

procedure TPlayObject.CmdTakeOnHorse(sCmd, sParam: string);
begin
if (sParam <> '') and (sParam = '?') then begin
    SysMsg('上马命令,在戴好马牌后输入此命令就可以骑上马。', c_Red, t_Hint);
    SysMsg(Format('命令格式: @%s', ), c_Red, t_Hint);
    Exit;
end;
if (m_btHorseType = 0) then begin
    SysMsg('骑马必须先戴上马牌!!!', c_Red, t_Hint);
    Exit;
end;
FeatureChanged();
end;

procedure TPlayObject.CmdTestFire(sCmd: string; nRange, nType, nTime, nPoint:
Integer);
var
nX, nY                              : Integer;
FireBurnEvent                         : TFireBurnEvent;
nMinX, nMaxX, nMinY, nMaxY            : Integer;
begin
nMinX := m_nCurrX - nRange;
nMaxX := m_nCurrX + nRange;
nMinY := m_nCurrY - nRange;
nMaxY := m_nCurrY + nRange;
for nX := nMinX to nMaxX do begin
    for nY := nMinY to nMaxY do begin
      if ((nX < nMaxX) and (nY = nMinY)) or
      ((nY < nMaxY) and (nX = nMinX)) or
      (nX = nMaxX) or (nY = nMaxY) then begin
      FireBurnEvent := TFireBurnEvent.Create(Self, nX, nY, nType, nTime *
          1000, nPoint);
      g_EventManager.AddEvent(FireBurnEvent);
      end;
    end;
end;
end;

procedure TPlayObject.CmdTestGetBagItems(Cmd: pTGameCmd; sParam: string);
var
btDc, btSc, btMc, btDura            : byte;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sParam <> '') and (sParam = '?') then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandTestGetBagItemsHelpMsg]), c_Red, t_Hint);
    Exit;
end;
btDc := 0;
btSc := 0;
btMc := 0;
btDura := 0;
GetBagUseItems(btDc, btSc, btMc, btDura);
SysMsg(Format('DC:%d SC:%d MC:%d DURA:%d', ),
    c_Blue, t_Hint);
end;

procedure TPlayObject.CmdTestSpeedMode(Cmd: pTGameCmd; nWhere, nType: Integer);
var
CharStatus                            : TCharStatus;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;

m_boTestSpeedMode := not m_boTestSpeedMode;
if m_boTestSpeedMode then begin
    SysMsg('开启速度测试模式', c_Red, t_Hint);
end else begin
    SysMsg('关闭速度测试模式', c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdTestStatus(sCmd: string; nType, nTime: Integer);
begin
if (m_btPermissionGM < 6) then Exit;
if (not (nType in )) or (nTime < 0) then begin
    SysMsg('命令格式: @' + sCmd + ' 类型(0..11) 时长', c_Red, t_Hint);
    Exit;
end;
m_wStatusTimeArr := _MIN(60, nTime) * 1000;
m_dwStatusArrTick := GetTickCount();
m_nCharStatus := GetCharStatus();
StatusChanged();
if g_Config.boShowScriptActionMsg then
    SysMsg(Format('状态编号:%d 时间长度: %d 秒', ), c_Green, t_Hint);
end;

procedure TPlayObject.CmdTing(Cmd: pTGameCmd; sHumanName: string);
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or ((sHumanName <> '') and (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandTingHelpMsg]), c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject <> nil then begin
    PlayObject.MapRandomMove(m_sHomeMap, 0, nil);
end else begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdTraining(sSkillName: string; nLevel: Integer);
//004CC414
begin
if (m_btPermissionGM < 6) then Exit;
end;

//GM命令TrainingSkill 人物 技能名称 修炼等级

procedure TPlayObject.CmdTrainingMagic(Cmd: pTGameCmd; sHumanName, sSkillName:
string;
nLevel: Integer);
var
Magic                                 : pTMagic;
PlayObject                            : TPlayObject;
btLevel                               : byte;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;

if ((sHumanName <> '') and (sHumanName = '?')) or (sHumanName = '') or
    (sSkillName = '') or (nLevel < 0) or not (nLevel in ) then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称技能名称 修炼等级(0-' + IntToStr(SKILLMAXLEVEL), c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;

Magic := UserEngine.FindMagic(sSkillName);
if Magic = nil then begin
    SysMsg(Format('%s 技能名称不正确!!!', ), c_Red, t_Hint);
    Exit;
end;

if PlayObject.IsTrainingSkill(Magic.wMagicID) then begin
    SysMsg(Format('%s的%s 技能已修炼过了!!!', ), c_Red, t_Hint);
    Exit;
end;

if (Magic.wMagicID in ) and (nLevel = 0) then
    btLevel := _Max(1, nLevel)
else
    btLevel := nLevel;
PlayObject.AddItemSkill(Magic, nLevel, 0, 0);
PlayObject.RecalcAbilitys;
SysMsg(Format('%s 的 %s 技能修炼成功!!!', ), c_Green, t_Hint);
end;

//调整人物技能等级

procedure TPlayObject.CmdTrainingSkill(Cmd: pTGameCmd; sHumanName, sSkillName:
string;
nLevel: Integer);
var
i                                     : Integer;
UserMagic                           : pTUserMagic;
PlayObject                            : TPlayObject;
Found                                 : Boolean;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sHumanName = '') or (sSkillName = '') or (nLevel < 0) or (nLevel > SKILLMAXLEVEL) then begin
    SysMsg('命令格式: @' + Cmd.sCmd + ' 人物名称技能名称 修炼等级(0-' + IntToStr(SKILLMAXLEVEL) + ')', c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format('%s不在线,或在其它服务器上!!', ), c_Red, t_Hint);
    Exit;
end;

Found := False;
for i := 0 to PlayObject.m_MagicList.Count - 1 do begin
    UserMagic := PlayObject.m_MagicList.Items;
    if (CompareText(UserMagic.MagicInfo.sMagicName, sSkillName) = 0) and (UserMagic.btType < MAG_AMALGAMATION) then begin
      if UserMagic.GetMagIdx in then nLevel := _Max(1, nLevel);
      UserMagic.btLevel := nLevel;
      PlayObject.SendMagic_LvExp_Msg(UserMagic, 100);

      PlayObject.SysMsg(Format('%s的修炼等级为%d', ), c_Green, t_Hint);
      SysMsg(Format('%s的技能%s修炼等级为%d', ), c_Green, t_Hint);
      Found := True;
      Break;
    end;
end;
if not Found then
    SysMsg(Format('%s的技能%s尚未修炼', ), c_Green, t_Hint);
end;

procedure TPlayObject.CmdUnBindUseItem(Cmd: pTGameCmd; sHumanName, sItem,
sType: string);
var
i                                     : Integer;
PlayObject                            : TPlayObject;
UserItem                              : pTUserItem;
nItem, nBind                        : Integer;
ItemBind                              : pTItemBind;
nItemIdx, nMakeIdex                   : Integer;
sBindName                           : string;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
nBind := -1;
nItem := GetUseItemIdx(sItem);
if CompareText(sType, '帐号') = 0 then nBind := 0;
if CompareText(sType, '人物') = 0 then nBind := 1;
if CompareText(sType, 'IP') = 0 then nBind := 2;

if (nItem < 0) or (nBind < 0) or (sHumanName = '') or ((sHumanName <> '') and
    (sHumanName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandBindUseItemHelpMsg]), c_Red, t_Hint);
    Exit;
end;

PlayObject := UserEngine.GetPlayObject(sHumanName);
if PlayObject = nil then begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
    Exit;
end;
UserItem := @PlayObject.m_UseItems;
if UserItem.wIndex = 0 then begin
    SysMsg(Format(g_sGameCommandBindUseItemNoItemMsg, ),
      c_Red, t_Hint);
    Exit;
end;
nItemIdx := UserItem.wIndex;
nMakeIdex := UserItem.MakeIndex;
case nBind of                                                                                     //
    0: begin
      sBindName := PlayObject.m_sUserID;

      for i := 0 to g_ItemBindAccount.Count - 1 do begin
          ItemBind := g_ItemBindAccount.Items;
          if (ItemBind.nItemIdx = nItemIdx) and (ItemBind.nMakeIdex = nMakeIdex) then begin
            SysMsg(Format(g_sGameCommandBindUseItemAlreadBindMsg, [sHumanName,
            sItem]), c_Red, t_Hint);
            Exit;
          end;
      end;
      New(ItemBind);
      ItemBind.nItemIdx := nItemIdx;
      ItemBind.nMakeIdex := nMakeIdex;
      ItemBind.sBindName := sBindName;
      g_ItemBindAccount.Insert(0, ItemBind);

      SaveItemBindAccount();
      SysMsg(Format('%s[%s]IDX[%d]系列号[%d]持久[%d-%d],绑定到%s成功。',
          [GetUseItemName(nItem),
          UserEngine.GetStdItemName(UserItem.wIndex),
            UserItem.wIndex,
            UserItem.MakeIndex,
            UserItem.Dura,
            UserItem.DuraMax,
            sBindName]),
            c_Blue, t_Hint);
      PlayObject.SysMsg(Format('你的%s[%s]已经绑定到%s[%s]上了。',
          [GetUseItemName(nItem),
          UserEngine.GetStdItemName(UserItem.wIndex),
            sType,
            sBindName
            ]), c_Blue, t_Hint);
      end;
    1: begin
      sBindName := PlayObject.m_sCharName;

      for i := 0 to g_ItemBindCharName.Count - 1 do begin
          ItemBind := g_ItemBindCharName.Items;
          if (ItemBind.nItemIdx = nItemIdx) and (ItemBind.nMakeIdex = nMakeIdex) then begin
            SysMsg(Format(g_sGameCommandBindUseItemAlreadBindMsg, [sHumanName,
            sItem]), c_Red, t_Hint);
            Exit;
          end;
      end;
      New(ItemBind);
      ItemBind.nItemIdx := nItemIdx;
      ItemBind.nMakeIdex := nMakeIdex;
      ItemBind.sBindName := sBindName;
      g_ItemBindCharName.Insert(0, ItemBind);

      SaveItemBindCharName();
      SysMsg(Format('%s[%s]IDX[%d]系列号[%d]持久[%d-%d],绑定到%s成功。',
          [GetUseItemName(nItem),
          UserEngine.GetStdItemName(UserItem.wIndex),
            UserItem.wIndex,
            UserItem.MakeIndex,
            UserItem.Dura,
            UserItem.DuraMax,
            sBindName]),
            c_Blue, t_Hint);
      PlayObject.SysMsg(Format('你的%s[%s]已经绑定到%s[%s]上了。',
          [GetUseItemName(nItem),
          UserEngine.GetStdItemName(UserItem.wIndex),
            sType,
            sBindName
            ]), c_Blue, t_Hint);
      end;
    2: begin
      sBindName := PlayObject.m_sIPaddr;

      for i := 0 to g_ItemBindIPaddr.Count - 1 do begin
          ItemBind := g_ItemBindIPaddr.Items;
          if (ItemBind.nItemIdx = nItemIdx) and (ItemBind.nMakeIdex = nMakeIdex) then begin
            SysMsg(Format(g_sGameCommandBindUseItemAlreadBindMsg, [sHumanName,
            sItem]), c_Red, t_Hint);
            Exit;
          end;
      end;
      New(ItemBind);
      ItemBind.nItemIdx := nItemIdx;
      ItemBind.nMakeIdex := nMakeIdex;
      ItemBind.sBindName := sBindName;
      g_ItemBindIPaddr.Insert(0, ItemBind);

      SaveItemBindIPaddr();
      SysMsg(Format('%s[%s]IDX[%d]系列号[%d]持久[%d-%d],绑定到%s成功。',
          [GetUseItemName(nItem),
          UserEngine.GetStdItemName(UserItem.wIndex),
            UserItem.wIndex,
            UserItem.MakeIndex,
            UserItem.Dura,
            UserItem.DuraMax,
            sBindName]),
            c_Blue, t_Hint);
      PlayObject.SysMsg(Format('你的%s[%s]已经绑定到%s[%s]上了。',
          [GetUseItemName(nItem),
          UserEngine.GetStdItemName(UserItem.wIndex),
            sType,
            sBindName
            ]), c_Blue, t_Hint);
      end;
end;
end;

procedure TPlayObject.CmdUserMoveXY(sCmd, sX, sY: string);
var
nX, nY                              : Integer;
begin
if m_boTeleport then begin
    nX := Str_ToInt(sX, -1);
    nY := Str_ToInt(sY, -1);
    if not m_PEnvir.m_MapFlag.boNOPOSITIONMOVE then begin
      if m_PEnvir.CanWalkOfItem(nX, nY, g_Config.boUserMoveCanDupObj,
      g_Config.boUserMoveCanOnItem) then begin
      if (GetTickCount - m_dwTeleportTick) > g_Config.dwUserMoveTime * 1000
          {10000}then begin
          m_dwTeleportTick := GetTickCount();
          SendRefMsg(RM_SPACEMOVE_FIRE, 0, 0, 0, 0, '');
          //BaseObjectMove('',sX,sY);
          SpaceMove(m_sMapName, nX, nY, 0, nil);
      end else begin
          SysMsg(IntToStr(g_Config.dwUserMoveTime - (GetTickCount -
            m_dwTeleportTick) div 1000) +
            '秒之后才可以再使用此功能!!!', c_Red, t_Hint);
      end;
      end else begin
      SysMsg(Format(g_sGameCommandPositionMoveCanotMoveToMap, [m_sMapName, sX,
          sY]), c_Green, t_Hint);
      end;
    end else begin
      SysMsg('此地图禁止使用此命令!!!', c_Red, t_Hint);
    end;
end else begin
    SysMsg('您现在还无法使用此功能!!!', c_Red, t_Hint);
end;
end;

procedure TPlayObject.CmdViewDiary(sCmd: string; nFlag: Integer);
begin

end;

procedure TPlayObject.CmdViewWhisper(Cmd: pTGameCmd; sCharName, sParam2:
string);
var
PlayObject                            : TPlayObject;
begin
if (m_btPermissionGM < Cmd.nPermissionMin) then begin
    SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
    Exit;
end;
if (sCharName = '') or ((sCharName <> '') and (sCharName = '?')) then begin
    SysMsg(Format(g_sGameCommandParamUnKnow, [Cmd.sCmd,
      g_sGameCommandViewWhisperHelpMsg]), c_Red, t_Hint);
    Exit;
end;
PlayObject := UserEngine.GetPlayObject(sCharName);
if PlayObject <> nil then begin
    if PlayObject.m_GetWhisperHuman = Self then begin
      PlayObject.m_GetWhisperHuman := nil;
      SysMsg(Format(g_sGameCommandViewWhisperMsg1, ), c_Green,
      t_Hint);
    end else begin
      PlayObject.m_GetWhisperHuman := Self;
      SysMsg(Format(g_sGameCommandViewWhisperMsg2, ), c_Green,
      t_Hint);
    end;
end else begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
end;
end;

{元神创建结束}

procedure TPlayObject.CreatePneumaEnd(btFlag: Integer; sNewName: string; nSex, btHumKind: byte);
begin
if btFlag = 1 then begin
    if btHumKind = 1 then begin
      m_sPneumaName := sNewName;
      if m_PneumaObject = nil then
      m_btPneumaSex := nSex + 1;
    end;
    Inc(m_btCurPneumaCount);
    RecalcAbilitys();
    SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
    if not ExecuteScript(g_FunctionNPC, '@元神创建成功') then
      SysMsg('元神创建成功!', c_Red, t_Hint);
end else begin
    if not ExecuteScript(g_FunctionNPC, '@元神创建失败') then
      SysMsg('元神创建失败,名字可能被占用,请换一个名字!', c_Red, t_Hint);
end;
m_boCreatePneuma := False;
end;

function TPlayObject.DayBright: byte;
begin
Result := 0;
if m_PEnvir.m_boDarkness then
    Result := 1
else if m_PEnvir.m_boDayLight then Result := 0;
end;

procedure TPlayObject.DealCancel;
begin
if not m_boDealing then Exit;
m_boDealing := False;
SendDefMessage(SM_DEALCANCEL, 0, 0, 0, 0, '');
if m_DealCreat <> nil then begin
    TPlayObject(m_DealCreat).DealCancel;
end;
m_DealCreat := nil;
GetBackDealItems();
SysMsg(g_sDealActionCancelMsg {'交易取消'}, c_Green, t_Hint);
m_DealLastTick := GetTickCount();
end;

procedure TPlayObject.DealCancelA;
begin
m_Abil.dwHP := m_WAbil.dwHP;
DealCancel();
end;

procedure TPlayObject.DelFromFriendList(FriendName: string);
var
i                                     : Integer;
begin
i := m_FriendsList.IndexOf(FriendName);
if i < 0 then Exit;
//在我的好友名单中删除
m_FriendsList.Delete(i);
SendDefMessage(SM_DelFriend, 2, 0, 0, 0, FriendName);
end;

procedure TPlayObject.DelPneuma(nIdx: Integer);
var
pDelPneuma                            : PTSwitchPneuma;
begin
if m_boPneuma then Exit;                                                                        //你就是元神!怎么能删除?
if (nIdx > m_btCurPneumaCount) then begin
    SysMsg('你选择的元神以经被删除了!!!', c_Red, t_Hint);
    Exit;                                                                                           //以经没有元神了! 不能删除
end;

if m_PneumaObject <> nil then begin
    SysMsg('请先收起元神,再执行删除', c_Red, t_Hint);
    Exit;
end;
if nIdx in then begin
    g_LargePacketManage.Init();
    pDelPneuma := g_LargePacketManage.GetMemRecord(SizeOf(TSwitchPneuma));

    pDelPneuma^.dwPlayObject := Integer(Self);
    pDelPneuma^.sChrName := m_sPneumaName;
    pDelPneuma^.dwDBIndex := nIdx;
    FrontEngine.SendGameWorkMsg(WK_DelPneuma, 0, g_LargePacketManage.GetMsg, False, True);
end;

//if (nIdx = 1) then begin
//    if m_PneumaObject <> nil then begin
//      SysMsg('请先收起元神,再执行删除', c_Red, t_Hint);
//      Exit;
//    end;
//    if m_sPneumaName = '' then Exit;
//    SendDelPneuma(m_sUserID, m_sPneumaName);
//    m_btPneumaSex := 0;
////    m_btPneumaJob := 0;
////    m_wPneumaLevel := 0;
//    m_sPneumaName := '';
//    SendDefMessage(SM_MENU_OK, 0, 0, 0, 0, '你的元神已经删除成功');
//end else begin
////    if m_btIntrovertSex = 0 then Exit;
////    m_btIntrovertSex := 0;
////    m_btIntrovertJob := 0;
////    m_wIntrovertLevel := 0;
////    FillChar(m_IntrovertAbil, SizeOf(TAbility), #0);
////    FillChar(m_IntrovertMagic, SizeOf(THumMagic), #0);
//    if m_PneumaObject <> nil then begin
//      m_PneumaObject.m_btPneumaKind := 1;
//    end;
//end;

end;

procedure TPlayObject.DelPneumaEnd(nIdx, btSex, btCount: byte);
var
sMsg                                  : string;
begin
if m_boPneuma then Exit;

if (nIdx > 0) then begin
    m_btCurPneumaCount := btCount;
    m_btPneumaSex := btSex + 1;

    if m_btCurPneumaCount = 0 then begin
      m_sPneumaName := '';
      m_btPneumaSex := 0;
      sMsg := '你的元神已经删除成功!!'
    end else if nIdx = 1 then
      sMsg := '你的外现元神已经删除成功,内敛元神以切换成了外现元神.'
    else sMsg := '你的内敛元神已经删除成功.';
    SendDefMessage(SM_MENU_OK, 0, 0, 0, 0, sMsg);

    RecalcAbilitys();
    SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
end else
    SendDefMessage(SM_MENU_OK, 0, 0, 0, 0, '你选择的元神删除失败');
end;

//从地图上消失

procedure TPlayObject.Disappear;
resourcestring
sExceptionMsg                         = ' TPlayObject::Disappear';
var
i                                     : Integer;
nCheck                              : Integer;
begin
nCheck := 0;
try
    if m_boReadyRun then DisappearA;
    nCheck := 1;
    if m_boTransparent and m_boHideMode then
      m_wStatusTimeArr := 0;

    nCheck := 2;
    if m_GroupOwner <> nil then begin
      m_GroupOwner.DelMember(Self);
    end;
    nCheck := 3;
    if m_MyGuild <> nil then begin
      TGuild(m_MyGuild).DelHumanObj(Self);
    end;
    nCheck := 4;
    if m_MyClan <> nil then begin
      TClan(m_MyClan).DelHumanObj(Self);
    end;
    nCheck := 5;
    //删除马
    HorseHide;
    nCheck := 6;
    //删除踏云豹
    if (m_Pet <> nil) then PetHide(m_PetInfo.nMakeIndex);
    nCheck := 7;
    LogonTimcCost();
    nCheck := 8;
except
    on E: Exception do begin
      MainOutMessage(Format(sExceptionMsg, ));
      MainOutMessage(E.Message);
    end;
end;

inherited;
end;

//人物死亡后掉落物品

procedure TPlayObject.DropUseItems(BaseObject: TBaseObject; AttackBaseObject: TBaseObject = nil);
var
i                                     : Integer;
nRate                                 : Integer;
StdItem                               : pTStdItem;
DelList                               : TStringList;
boCon, boDrop                         : Boolean;
resourcestring
sExceptionMsg                         = ' TPlayObject::DropUseItems';
begin
boDrop := False;
DelList := nil;
try
    if m_boAngryRing or m_boNoDropUseItem then Exit;

    for i := Low(THumItems) to High(THumItems) do begin
      StdItem := UserEngine.GetStdItem(m_UseItems.wIndex);
      if StdItem <> nil then begin
      if CheckSPCode(StdItem.Reserved, RE_DIRCLEAR) then begin                                    //物品控制-死亡消失
          if DelList = nil then DelList := TStringList.Create;
          DelList.AddObject('', TObject(m_UseItems.MakeIndex));
          m_UseItems.wIndex := 0;
          boDrop := True;
          if StdItem.boGameLog = 1 then
            AddGameDataLog('16' + #9 +
            m_sMapName + #9 +
            IntToStr(m_nCurrX) + #9 +
            IntToStr(m_nCurrY) + #9 +
            m_sCharName + #9 +
            StdItem.Name + #9 +
            IntToStr(m_UseItems.MakeIndex) + #9 +
            BoolToIntStr(m_btRaceServer = RC_PLAYOBJECT) + #9 +
            '0');
      end;
      end;
    end;

    for i := Low(THumItems) to High(THumItems) do begin
      if PKLevel > 2 then
      nRate := g_Config.nDieRedDropUseItemRate
      else
      nRate := g_Config.nDieDropUseItemRate;

      if AttackBaseObject <> nil then begin
      if (g_Config.boAttachedSoulAbil) then
          nRate := _MAX(0, nRate - AttackBaseObject.m_HumDropUserItemAddRate);                      //附魂
      end;

      StdItem := UserEngine.GetStdItem(m_UseItems.wIndex);
      if StdItem <> nil then begin
      boCon := CheckSPCode(StdItem.SPCode, SP_DISABLEDIEDROP) and (CheckSPCode(StdItem.Reserved, RE_DIEDROP));
      if (not boCon) and (CheckSPCode(StdItem.Reserved, RE_DIEDROP)) then
          nRate := 0;                                                                               //物品控制-死亡身上爆出
      if (Random(nRate) <> 0) and (boCon) then Continue;
      if (not boCon) and ((Random(nRate) <> 0) or (CheckSPCode(StdItem.SPCode, SP_DISABLEDIEDROP))) then Continue; //物品控制-禁止身上爆出

      if ((m_UseItems.btItemExt and EX_BIND) = EX_BIND) then Continue;                      //绑定物品

      if DropItemDown(@m_UseItems, 5, True, BaseObject, Self) then begin
          //if StdItem.Reserved and 10 = 0 then begin
          if m_btRaceServer = RC_PLAYOBJECT then begin
            if DelList = nil then DelList := TStringList.Create;
            DelList.AddObject(UserEngine.GetStdItemName(m_UseItems.wIndex),
            TObject(m_UseItems.MakeIndex));
          end;
          m_UseItems.wIndex := 0;
          //end;
          boDrop := True;
      end;
      end;
    end;
    RecalcAbilitys(boDrop);

    if DelList <> nil then
      SendMsg(Self, RM_SENDDELITEMLIST, 0, Integer(DelList), 0, 0, '');
except
    MainOutMessage(sExceptionMsg);
end;
end;

function TPlayObject.EatItems(StdItem: pTStdItem): Boolean;
var
bo06                                  : Boolean;
nOldStatus                            : Integer;
nHP, nMP, nTime                     : Integer;
Magic                                 : pTMagic;
begin
Result := False;
if m_PEnvir.m_MapFlag.boNODRUG then begin
    SysMsg(sCanotUseDrugOnThisMap, c_Red, t_Hint);
    Exit;
end;
if GetTickCount - m_dwEatItemTick >= g_Config.nEatItemTime then begin
    m_dwEatItemTick := GetTickCount;
end else
    Exit;
case StdItem.StdMode of
    0: begin
      nHP := _MIN(High(word), LoWord(StdItem.AC)) * _Max(1, HiWord(StdItem.AC));
      nMP := _MIN(High(word), LoWord(StdItem.MAC)) * _Max(1, HiWord(StdItem.MAC));
      case StdItem.Shape of
          0, 202: begin                                                                           //普通药品
            if (StdItem.AC > 0) then begin
                Inc(m_nIncHealth, nHP);
                Inc(m_nIncHealth, m_nAllIncReply);
            end;
            if (StdItem.MAC > 0) then begin
                Inc(m_nIncSpell, nMP);
                Inc(m_nIncSpell, m_nAllIncReply);
            end;
            Result := True;
            end;
          1: begin                                                                                  //瞬间加血物品,太阳神水
            Inc(nHP, m_nAllIncReply);
            Inc(nMP, m_nAllIncReply);
            IncHealthSpell(nHP, nMP);
            Result := True;
            end;
          201: begin                                                                              //治疗神水
            if CheckEatItems(StdItem) then begin
                Inc(nHP, m_nAllIncReply);
                Inc(nMP, m_nAllIncReply);
                IncHealthSpell(nHP, nMP);
                SendRefMsg(RM_510, 1, 0, 3, 0, '');
                Result := True;
            end;
            end;
          2: begin
            m_boUserUnLockDurg := True;
            Result := True;
            end;
          3: begin
            if m_boPneuma and m_boPneumaEffMode then begin
                IncHealthSpell(nHP, nMP);
                Result := True;
            end;
            end;
          4: begin
            if m_PEnvir.m_MapFlag.boDECHP then begin
                if m_dwEatTalismanTick > 0 then
                  m_dwEatTalismanTick := m_dwEatTalismanTick + LoWord(StdItem.DC) * 60000
                else
                  m_dwEatTalismanTick := GetTickCount + LoWord(StdItem.DC) * 60000;
                SendDefMessage(SM_510, Integer(Self), (m_dwEatTalismanTick - GetTickCount) mod 1000, 0, 79, '');
                SysMsg(StdItem.FilterName + '可以让你在天魔宝藏中不受魔气侵袭而损失生命值,效果持续20分钟', c_Red, t_Hint);
                ExecuteScript(g_FunctionNPC, '@使用辟邪丹');
                Result := True;
            end else begin
                SysMsg(StdItem.FilterName + '在此地图使用没有什么效果。', c_Red, t_Hint);
            end;
            end;
          5: begin                                                                                  //强化技能灵丹
            Magic := UserEngine.FindMagic(Str_ToInt(m_sScriptParam, -1));
            if Magic <> nil then begin
                m_sScriptParam := Magic^.sMagicName;
                m_sScriptParam := IntToStr(Magic^.wMagicID);
            end else
                m_sScriptParam := '';
            UseStdmodeFunItem(StdItem);
            Result := True;
            end;
          200: begin
            if CheckEatItems(StdItem) then begin
                Inc(nHP, m_nAllIncReply * 10);
                Inc(nMP, m_nAllIncReply * 10);
                nTime := LoWord(StdItem.DC);
                if nTime = 0 then nTime := 10;

                if (StdItem.AC > 0) then begin
                  m_nSuperIncHealth := nHP;
                  m_dwSuperIncHealthTick := GetTickCount + nTime * 60 * 1000;
                  SendDefMessage(SM_510, Integer(Self), 1, 0, 1, '');
                end;
                if (StdItem.MAC > 0) then begin
                  m_nSuperIncSpell := nMP;
                  m_dwSuperIncSpellTick := GetTickCount + nTime * 60 * 1000;
                  SendDefMessage(SM_510, Integer(Self), 1, 0, 2, '');
                end;
                Result := True;
            end;
            end;
          206: begin
            if (m_Tiger <> nil) and (not m_Tiger.m_boGhost) and (not m_Tiger.m_boDeath) then begin
                Inc(m_Tiger.m_WAbil.dwHP, nHP);
                m_Tiger.HealthSpellChanged();
                Result := True;
            end;
            end;
          207: begin
            if m_btJob <> 3 then begin                                                            //妖士是没有虎王盾的
                if (m_TorDDM.Tiger.DB.Dragon = 0) and (m_TorDDM.Tiger.DB.level > 0) and (m_TorDDM.Tiger.Abil.MaxHP > 0) then begin
                  m_TorDDM.Tiger.DB.ReCallTick := 0;
                  SendTigerInfo;
                  SysMsg('你的虎灵值已经恢复了。', c_Red, t_Hint);
                  Result := True;
                end;
            end;
            end;
          219: begin
            if m_btJob <> 3 then begin
                if (m_TorDDM.Tiger.DB.Dragon > 0) and (m_TorDDM.Tiger.DB.level > 0) and (m_TorDDM.Tiger.Abil.MaxHP > 0) then begin
                  m_TorDDM.Tiger.DB.ReCallTick := 0;
                  SendTigerInfo;
                  SysMsg('你的龙灵值已经恢复了。', c_Red, t_Hint);
                  Result := True;
                end;
            end;
            end;
          208: begin
            if m_btMentalLevel > 0 then begin
                if m_nMentalPoint < m_nMentalPointMax then begin
                  nHP := StdItem.NeedLevel * 100;
                  Inc(m_nMentalPoint, nHP);
                  SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
                  Result := True;
                end;
                bo06 := False;
                if (m_nMentalPoint >= m_nMentalPointMax) then begin
                  while True do begin
                  if (UserEngine.GetMentalAbil(m_btJob, m_btMentalLevel + 1) <> nil) then begin
                      if (m_nMentalPoint >= m_nMentalPointMax) and (m_nMentalPointMax > 0) then begin
                        Dec(m_nMentalPoint, m_nMentalPointMax);
                        Inc(m_btMentalLevel);
                        RecalcAbilitys();
                        bo06 := True;
                      end else
                        Break;
                  end else
                      Break;
                  end;
                  if bo06 then begin
                  ClientQueryMentalAbilitys(Self);
                  SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
                  FeatureChanged();
                  end;
                end;
            end else begin
                SysMsg('你还未领悟天元心法,不能使用该道具。请到魔法阵祭祀那领悟天元心法。', c_Red, t_Hint);
            end;
            end;
          211: begin                                                                              //海神生命神水
            if m_WAbil.dwHP < m_WAbil.dwMaxHP then begin
                if GetTickCount - m_dwEatDurgHPTick >= StdItem.NeedLevel * 1000 then begin
                  m_dwEatDurgHPTick := GetTickCount;
                  Result := True;
                end else begin
                  SysMsg(Format('此神水%d秒后才能使用!', [(StdItem.NeedLevel * 1000 - (GetTickCount - m_dwEatDurgHPTick)) div 1000]), c_Red, t_Hint);
                end;
            end;
            end;
          212: begin                                                                              //海神魔法神水
            if m_WAbil.dwMP < m_WAbil.dwMaxMP then begin
                if GetTickCount - m_dwEatDurgMPTick >= StdItem.NeedLevel * 1000 then begin
                  m_dwEatDurgMPTick := GetTickCount;
                  Result := True;
                end else begin
                  SysMsg(Format('此神水%d秒后才能使用!', [(StdItem.NeedLevel * 1000 - (GetTickCount - m_dwEatDurgMPTick)) div 1000]), c_Red, t_Hint);
                end;
            end;
            end;
      else begin
            UseStdmodeFunItem(StdItem);
          end;
      end;
      end;
    1: begin
      nOldStatus := GetMyStatus();
      Inc(m_nHungerStatus, StdItem.DuraMax div 10);
      m_nHungerStatus := _MIN(5000, m_nHungerStatus);
      if nOldStatus <> GetMyStatus() then RefMyStatus();
      Result := True;
      end;
    2: Result := True;
    3: begin
      case StdItem.Shape of
          12: begin
            bo06 := False;
            if LoWord(StdItem.DC) > 0 then begin
                m_wStatusArrValue := LoWord(StdItem.DC);
                m_dwStatusArrTimeOutTick := GetTickCount + HiWord(StdItem.MAC) * 1000;
                SysMsg('攻击力增加' + IntToStr(HiWord(StdItem.MAC)) + '秒', c_Green, t_Hint);
                bo06 := True;
            end;
            if LoWord(StdItem.MC) > 0 then begin
                m_wStatusArrValue := LoWord(StdItem.MC);
                m_dwStatusArrTimeOutTick := GetTickCount + HiWord(StdItem.MAC) * 1000;
                SysMsg('魔法力增加' + IntToStr(HiWord(StdItem.MAC)) + '秒', c_Green, t_Hint);
                bo06 := True;
            end;
            if LoByte(StdItem.SC) > 0 then begin
                m_wStatusArrValue := LoWord(StdItem.SC);
                m_dwStatusArrTimeOutTick := GetTickCount + HiWord(StdItem.MAC) * 1000;
                SysMsg('道术增加' + IntToStr(HiWord(StdItem.MAC)) + '秒', c_Green, t_Hint);
                bo06 := True;
            end;
            if HiWord(StdItem.AC) > 0 then begin
                m_wStatusArrValue := HiWord(StdItem.AC);
                m_dwStatusArrTimeOutTick := GetTickCount + HiWord(StdItem.MAC) * 1000;
                SysMsg('攻击速度增加' + IntToStr(HiWord(StdItem.MAC)) + '秒', c_Green, t_Hint);
                bo06 := True;
            end;
            if LoWord(StdItem.AC) > 0 then begin
                m_wStatusArrValue := LoWord(StdItem.AC);
                m_dwStatusArrTimeOutTick := GetTickCount + HiWord(StdItem.MAC) * 1000;
                SysMsg('生命值增加' + IntToStr(HiWord(StdItem.MAC)) + '秒', c_Green, t_Hint);
                bo06 := True;
            end;
            if LoWord(StdItem.MAC) > 0 then begin
                m_wStatusArrValue := LoWord(StdItem.MAC);
                m_dwStatusArrTimeOutTick := GetTickCount + HiWord(StdItem.MAC) * 1000;
                SysMsg('魔法值增加' + IntToStr(HiWord(StdItem.MAC)) + '秒', c_Green, t_Hint);
                bo06 := True;
            end;
            if bo06 then begin
                RecalcAbilitys();
                SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
                Result := True;
            end;
            end;
          16: begin                                                                                 //摊位样式
            m_wShopKind := StdItem.AC;
            SysMsg('您改变了摊位类型', c_Red, t_Hint);
            Result := True;
            end;
          17: begin
            if StdItem.AniCount = 0 then begin
                m_btShopBanner := StdItem.AC;
                m_nBannerColor := MakeLong(MakeWord(LoWord(StdItem.MAC), HiWord(StdItem.MAC)),
                  MakeWord(LoWord(StdItem.DC), HiWord(StdItem.DC)));
                SysMsg('您改变了摊位旗帜颜色', c_Red, t_Hint);
                Result := True;
            end else begin
                Result := UseStdmodeFunItem(StdItem);
            end;
            end;
          201: begin                                                                              //百变披风
            if StdItem.AniCount > 0 then begin                                                    //次数物品
                Result := UseStdmodeFunItem(StdItem);
                Exit;
            end;
            if m_boRideOn or m_boCatapultMode then begin
                SysMsg('你现在不可以使用变身披风', c_Red, t_Hint);
                Exit;
            end;
            if (StdItem.AC = m_wBianshenImg) and (StdItem.MAC = m_wBianshenAppr) then begin       //取消变身
                m_wBianshenImg := 0;
                m_wBianshenAppr := 0;
            end else begin
                m_wBianshenImg := StdItem.AC;
                m_wBianshenAppr := StdItem.MAC;
            end;
            if m_wExtraLevel > 0 then begin
                if m_wBianshenAppr = 0 then
                  SendMsg(Self, RM_FENGHAO, MakeWord(8, LoByte(m_wExtraLevel)), GetPneumaAmbit, HiByte(m_wExtraLevel), 0, GetExtraLevelName)
                else
                  SendMsg(Self, RM_FENGHAO, MakeWord(8, 0), 0, 0, 0, GetExtraLevelName);
            end;
            SendRefMsg(RM_FENGHAO, 64, m_wBianshenImg, m_wBianshenAppr, 0, '');
            Result := True;
            end;
      else begin
            Result := EatUseItems(StdItem.Shape);
            if not Result then Result := UseStdmodeFunItem(StdItem);
          end;
      end;
      end;
end;
end;

function TPlayObject.EatUseItems(nShape: Integer): Boolean;                                       //004BD1BC
var
Castle                              : TUserCastle;
begin
Result := False;
if m_boArrow and (nShape in ) then Exit;
case nShape of                                                                                    //
    1: begin
      SendRefMsg(RM_SPACEMOVE_FIRE, 0, 0, 0, 0, '');
      BaseObjectMove(m_sHomeMap, '', '');
      Result := True;
      end;
    2: begin
      if not m_PEnvir.m_MapFlag.boNORANDOMMOVE then begin
          SendRefMsg(RM_SPACEMOVE_FIRE, 0, 0, 0, 0, '');
          BaseObjectMove(m_sMapName, '', '');
          Result := True;
      end;
      end;
    3: begin
      SendRefMsg(RM_SPACEMOVE_FIRE, 0, 0, 0, 0, '');
      if PKLevel < 2 then begin
          BaseObjectMove(m_sHomeMap, IntToStr(m_nHomeX), IntToStr(m_nHomeY));
      end else begin
          BaseObjectMove(g_Config.sRedHomeMap, IntToStr(g_Config.nRedHomeX),
            IntToStr(g_Config.nRedHomeY));
      end;
      Result := True;
      end;
    4: begin
      if WeaptonMakeLuck() then Result := True;
      end;
    5: begin
      if m_MyGuild <> nil then begin
          if not m_boInFreePKArea then begin
            Castle := g_CastleManager.IsCastleMember(Self);
            {
            if UserCastle.IsMasterGuild(TGuild(m_MyGuild)) then begin
            BaseObjectMove(UserCastle.m_sHomeMap,IntToStr(UserCastle.GetHomeX),IntToStr(UserCastle.GetHomeY));
            }
            if (Castle <> nil) and Castle.IsMasterGuild(TGuild(m_MyGuild)) then begin
            BaseObjectMove(Castle.m_sHomeMap, IntToStr(Castle.GetHomeX),
                IntToStr(Castle.GetHomeY));
            end else begin
            SysMsg('无效', c_Red, t_Hint);
            end;
            Result := True;
          end else begin                                                                            //004BD3F7
            SysMsg('此处无法使用', c_Red, t_Hint);
          end;
      end;
      end;
    9: begin
      if RepairWeapon() then Result := True;
      end;
    10: begin
      if SuperRepairWeapon() then Result := True;
      end;
    11: begin
      if WinLottery() then Result := True;
      end;
end;
end;

function TPlayObject.ExecuteScript(ScriptObj: TObject; sLabel: string): Boolean;
resourcestring
sScriptExcept                         = ' TPlayObject::ExecuteScript %s';
begin
Result := False;
if ScriptObj <> nil then begin
    try
      m_nScriptGotoCount := 0;
      m_sScriptCurrLable := '';
      m_sScriptGoBackLable := '';
      Result := TNormNpc(ScriptObj).GotoLable(Self, sLabel, False);
    except
      MainOutMessage(Format(sScriptExcept, ));
    end;
end;
end;

function TPlayObject.FindViewHum(PlayObject: TObject): TPlayObject;
var
i                                     : Integer;
begin
Result := nil;
try
    for i := 0 to m_VisibleHumanList.Count - 1 do
      if PlayObject = TObject(m_VisibleHumanList) then begin
      Result := TPlayObject(m_VisibleHumanList);
      Break;
      end;
except

end;
end;

//和组队玩家分配经验值

procedure TPlayObject.GainExp(dwExp: LongWord; dwMilitaryExp: LongWord; dwRepressDemonExp: LongWord);
var
i, n, sumlv                           : Integer;
PlayObject                            : TPlayObject;
nCheckCode                            : Integer;
resourcestring
sExceptionMsg                         = ' TPlayObject::GainExp(%s,checkcode=%d)';
const
bonus                                 : array of real = (1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.1, 2.2);
begin
try
    nCheckCode := 0;
    if m_GroupOwner <> nil then begin                                                               //组队经验分配
      sumlv := 0;
      n := 0;
      nCheckCode := 1;
      for i := 0 to m_GroupOwner.m_GroupMembers.Count - 1 do begin
      PlayObject := TPlayObject(m_GroupOwner.m_GroupMembers.Objects);
      nCheckCode := 2;
      if not PlayObject.m_boDeath and (m_PEnvir = PlayObject.m_PEnvir) and
          (abs(m_nCurrX - PlayObject.m_nCurrX) <= 12) and (abs(m_nCurrX -
          PlayObject.m_nCurrX) <= 12) then begin
          sumlv := sumlv + PlayObject.m_Abil.level;
          Inc(n);
      end;
      end;
      nCheckCode := 3;
      if (sumlv > 0) and (n > 1) then begin
      nCheckCode := 31;
      if n in then begin
          dwExp := Round(dwExp * bonus);
          dwMilitaryExp := Round(dwMilitaryExp * bonus);
          dwRepressDemonExp := Round(dwRepressDemonExp * bonus);
      end;
      for i := 0 to m_GroupOwner.m_GroupMembers.Count - 1 do begin
          PlayObject := TPlayObject(m_GroupOwner.m_GroupMembers.Objects);
          if not PlayObject.m_boDeath and (m_PEnvir = PlayObject.m_PEnvir) and
            (abs(m_nCurrX - PlayObject.m_nCurrX) <= 12) and (abs(m_nCurrX -
            PlayObject.m_nCurrX) <= 12) then begin
            if g_Config.boHighLevelKillMonFixExp then begin                                       //02/08 增加,在高等级经验不变时,把组队的经验平均分配
            nCheckCode := 4;
            PlayObject.WinExp(Round(dwExp / n), dwMilitaryExp, dwRepressDemonExp);
            nCheckCode := 5;
            if (m_MyGuild <> nil) and (PlayObject.m_MyGuild <> nil) then begin
                if (TGuild(m_MyGuild).sGuildName = TGuild(PlayObject.m_MyGuild).sGuildName) then
                  TGuild(m_MyGuild).dwGuildExp := TGuild(m_MyGuild).dwGuildExp + Round(dwExp / n);//05.06 增加组队行会经验
            end;
            end else begin
            nCheckCode := 6;
            PlayObject.WinExp(Round(dwExp / sumlv * PlayObject.m_Abil.level), dwMilitaryExp, dwRepressDemonExp);
            nCheckCode := 7;
            if (m_MyGuild <> nil) and (PlayObject.m_MyGuild <> nil) then begin
                if (TGuild(m_MyGuild).sGuildName = TGuild(PlayObject.m_MyGuild).sGuildName) then
                  TGuild(m_MyGuild).dwGuildExp := TGuild(m_MyGuild).dwGuildExp + Round(dwExp / sumlv * PlayObject.m_Abil.level); //05.06 增加组队行会经验
            end;
            end;
          end;
      end;
      end else WinExp(dwExp, dwMilitaryExp, dwRepressDemonExp);
    end else WinExp(dwExp, dwMilitaryExp, dwRepressDemonExp);
except
    MainOutMessage(Format(sExceptionMsg, ));
end;
end;

procedure TPlayObject.GameTimeChanged;
begin
if m_nBright <> g_nGameTime then begin
    m_nBright := g_nGameTime;
    SendMsg(Self, RM_DAYCHANGING, 0, 0, 0, 0, '');
end;
end;

//取回交易的物品

procedure TPlayObject.GetBackDealItems;                                                             //004DD270
var
i                                     : Integer;
begin
if m_DealItemList.Count > 0 then begin
    for i := 0 to m_DealItemList.Count - 1 do begin
      m_ItemList.Add(m_DealItemList.Items);
    end;
end;
m_DealItemList.Clear;
IncGold(m_nDealGolds);
Inc(m_nGameGold, m_nDealGameGolds);
m_nDealGolds := 0;
m_nDealGameGolds := 0;
m_boDealOK := False;
end;

procedure TPlayObject.GetBagUseItems(var btDc, btSc, btMc, btDura: byte);
var
i, ii                                 : Integer;
DuraList                              : TList;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
StdItem80                           : TStdItem;
DelItemList                           : TStringList;
nDc, nSc, nMc, nDcMin, nDcMax, nScMin, nScMax, nMcMin, nMcMax, nDura,
    nItemCount                        : Integer;
begin
nDcMin := 0;
nDcMax := 0;
nScMin := 0;
nScMax := 0;
nMcMin := 0;
nMcMax := 0;
nDura := 0;
nItemCount := 0;
DelItemList := nil;
DuraList := TList.Create;
for i := m_ItemList.Count - 1 downto 0 do begin
    UserItem := m_ItemList.Items;
    if UserEngine.GetStdItemName(UserItem.wIndex) = g_Config.sBlackStone then begin
      DuraList.Add(Pointer(Round(UserItem.Dura / 1.0E3)));
      if DelItemList = nil then DelItemList := TStringList.Create;
      DelItemList.AddObject(g_Config.sBlackStone, TObject(UserItem.MakeIndex));
      Dispose(UserItem);
      m_ItemList.Delete(i);
    end else begin
      if IsUseItem(UserItem.wIndex) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem <> nil then begin
          StdItem80 := StdItem^;
          ItemUnit.GetItemAddValue(UserItem, StdItem80);
          nDc := 0;
          nSc := 0;
          nMc := 0;
          case StdItem80.StdMode of
            19, 20, 21: begin                                                                     //004A0421
                nDc := HiWord(StdItem80.DC) + LoWord(StdItem80.DC);
                nSc := HiWord(StdItem80.SC) + LoWord(StdItem80.SC);
                nMc := HiWord(StdItem80.MC) + LoWord(StdItem80.MC);
            end;
            22, 23: begin                                                                           //004A046E
                nDc := HiWord(StdItem80.DC) + LoWord(StdItem80.DC);
                nSc := HiWord(StdItem80.SC) + LoWord(StdItem80.SC);
                nMc := HiWord(StdItem80.MC) + LoWord(StdItem80.MC);
            end;
            24, 26: begin
                nDc := HiWord(StdItem80.DC) + LoWord(StdItem80.DC) + 1;
                nSc := HiWord(StdItem80.SC) + LoWord(StdItem80.SC) + 1;
                nMc := HiWord(StdItem80.MC) + LoWord(StdItem80.MC) + 1;
            end;
          end;
          if nDcMin < nDc then begin
            nDcMax := nDcMin;
            nDcMin := nDc;
          end else begin
            if nDcMax < nDc then nDcMax := nDc;
          end;
          if nScMin < nSc then begin
            nScMax := nScMin;
            nScMin := nSc;
          end else begin
            if nScMax < nSc then nScMax := nSc;
          end;
          if nMcMin < nMc then begin
            nMcMax := nMcMin;
            nMcMin := nMc;
          end else begin
            if nMcMax < nMc then nMcMax := nMc;
          end;
          if DelItemList = nil then DelItemList := TStringList.Create;
          DelItemList.AddObject(StdItem.Name, TObject(UserItem.MakeIndex));
          //004A06DB
          if StdItem.boGameLog = 1 then
            AddGameDataLog('26' + #9 +
            m_sMapName + #9 +
            IntToStr(m_nCurrX) + #9 +
            IntToStr(m_nCurrY) + #9 +
            m_sCharName + #9 +
            StdItem.Name + #9 +
            IntToStr(UserItem.MakeIndex) + #9 +
            '1' + #9 +
            '0');
          Dispose(UserItem);
          m_ItemList.Delete(i);
      end;
      end;
    end;
end;                                                                                              // for
for i := 0 to DuraList.Count - 1 do begin
    for ii := DuraList.Count - 1 downto i + 1 do begin
      if Integer(DuraList.Items) > Integer(DuraList.Items) then
      DuraList.Exchange(ii, ii - 1);
    end;                                                                                          // for
end;                                                                                              // for
for i := 0 to DuraList.Count - 1 do begin
    nDura := nDura + Integer(DuraList.Items);
    Inc(nItemCount);
    if nItemCount >= 5 then Break;
end;
btDura := Round(_MIN(5, nItemCount) + _MIN(5, nItemCount) * ((nDura /
    nItemCount) / 5.0));
btDc := nDcMin div 5 + nDcMax div 3;
btSc := nScMin div 5 + nScMax div 3;
btMc := nMcMin div 5 + nMcMax div 3;
if DelItemList <> nil then
    SendMsg(Self, RM_SENDDELITEMLIST, 0, Integer(DelItemList), 0, 0, '');

if DuraList <> nil then DuraList.free;

end;

function TPlayObject.GeTBaseObjectInfo: string;
var
perm                                  : Integer;
begin
if m_btPermissionGM > 10 then perm := 0 else perm := m_btPermissionGM;
Result := m_sCharName +
    ' 标识:' + IntToHex(Integer(Self), 2) +
    ' 权限等级: ' + IntToStr(perm) +
    ' 管理模式: ' + BoolToCStr(m_boAdminMode) +
    ' 隐身模式: ' + BoolToCStr(m_boObMode) +
    ' 无敌模式: ' + BoolToCStr(m_boSuperMan) +
    ' 地图:' + m_sMapName + '(' + m_PEnvir.m_sMapDesc + ')' +
    ' 座标:' + IntToStr(m_nCurrX) + ':' + IntToStr(m_nCurrY) +
    ' 等级:' + IntToStr(m_Abil.level) +
    ' 转生等级:' + IntToStr(m_btReLevel) +
    ' 经验:' + IntToStr(m_Abil.Exp) +
    ' 生命值: ' + IntToStr(m_WAbil.dwHP) + '-' + IntToStr(m_WAbil.dwMaxHP) +
    ' 魔法值: ' + IntToStr(m_WAbil.dwMP) + '-' + IntToStr(m_WAbil.dwMaxMP) +
    ' 攻击力: ' + IntToStr(loword(m_WAbil.DC)) + '-' +
    IntToStr(hiword(m_WAbil.DC)) +
    ' 魔法力: ' + IntToStr(loword(m_WAbil.MC)) + '-' +
    IntToStr(hiword(m_WAbil.MC)) +
    ' 道术: ' + IntToStr(loword(m_WAbil.SC)) + '-' +
    IntToStr(hiword(m_WAbil.SC)) +
    ' 防御力: ' + IntToStr(loword(m_WAbil.AC)) + '-' +
    IntToStr(hiword(m_WAbil.AC)) +
    ' 魔防力: ' + IntToStr(loword(m_WAbil.MAC)) + '-' +
    IntToStr(hiword(m_WAbil.MAC)) +
    ' 命中:' + IntToStr(m_dwHitPoint) +
    ' 躲避:' + IntToStr(m_dwSpeedPoint) +
    ' 速度:' + IntToStr(m_nHitSpeed) +
    ' 仓库密码:' + m_sStoragePwd +
    ' 登录IP:' + m_sIPaddr + '(' + m_sIPLocal {GetIPLocal(m_sIPaddr)} + ')' +
    ' 登录帐号:' + m_sUserID +
    ' 登录时间:' + DateToChStr(m_dLogonTime, True) +
    ' 在线时长(分钟):' + IntToStr((GetTickCount - m_dwLogonTick) div 60000)
    +
    ' 登录模式:' + IntToStr(m_nPayMent) +
    ' ' + g_Config.sGameGoldName + ':' + IntToStr(m_nGameGold) +
    ' ' + g_Config.sGamePointName + ':' + IntToStr(m_nGamePoint) +
    ' ' + g_Config.sPayMentPointName + ':' + IntToStr(m_nPayMentPoint) +
    ' 会员类型:' + IntToStr(m_nMemberType) +
    ' 会员等级:' + IntToStr(m_nMemberLevel) +
    ' 经验倍数:' + CurrToStr(m_nKillMonExpRate / 100) +
    ' 攻击倍数:' + CurrToStr(m_nPowerRate / 100) +
    ' 防御倍数:' + CurrToStr(m_nDefenceRate / 100) +
    ' 杀怪爆率:' + CurrToStr(m_nKillMonBurstRate / 100) +
    ' 声望值:' + IntToStr(m_wCreditPoint);
end;

//获取包裹中指定物品某属性的总和

function TPlayObject.GetItemValueSum(sItemName: string; sValName: string): Integer;
var
UserItem                              : pTUserItem;
i, nIdx, nValue                     : Integer;
sValue                              : string;
begin
Result := 0;
nIdx := UserEngine.GetStdItemIdx(sItemName);
if nIdx > 0 then begin
    for i := 0 to m_ItemList.Count - 1 do begin
      UserItem := m_ItemList.Items;
      if UserItem.wIndex = nIdx then begin
      sValue := GetCheckItemValue(UserItem.MakeIndex, sValName);
      if sValue <> '' then begin
          nValue := Str_ToInt(sValue, 0);
          Inc(Result, nValue);
      end;
      end;
    end;
end;
end;

//获取包裹中指定物品指定属性在一定数值以上的物品总数

function TPlayObject.GetItemCountWithValue(sItemName: string; sValName: string; nValue: Integer): Integer;
var
UserItem                              : pTUserItem;
i, nIdx, nPoint                     : Integer;
sValue                              : string;
begin
Result := 0;
nIdx := UserEngine.GetStdItemIdx(sItemName);
if nIdx > 0 then begin
    for i := 0 to m_ItemList.Count - 1 do begin
      UserItem := m_ItemList.Items;
      if UserItem.wIndex = nIdx then begin
      sValue := GetCheckItemValue(UserItem.MakeIndex, sValName);
      if sValue <> '' then begin
          nPoint := Str_ToInt(sValue, 0);
          if nPoint >= nValue then Inc(Result);
      end;
      end;
    end;
end;

end;

function TPlayObject.GetCheckItemValue(nMakeIndex: Integer; sName: string): string;
var
UserItem                              : pTUserItem;
i, p, n18                           : Integer;
pStdItem, StdStone                  : pTStdItem;
StdItem                               : TStdItem;
s18, s19                              : string;
boFind                              : Boolean;
tm                                    : DWORD;
nExp                                  : Int64;
nSoulExp                              : UInt64;
NPC                                 : TNormNpc;
begin
Result := '';
if (nMakeIndex = 0) then Exit;

boFind := False;
if (nMakeIndex >= 0) and (nMakeIndex <= High(THumItems)) then begin
    UserItem := @m_UseItems;
    if (UserItem.wIndex <> 0) then begin
      pStdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if pStdItem = nil then Exit;
      StdItem := pStdItem^;
      boFind := True;
    end;
end else begin
    for i := 0 to m_ItemList.Count - 1 do begin
      UserItem := m_ItemList.Items;
      if UserItem.MakeIndex = nMakeIndex then begin
      pStdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if pStdItem = nil then Exit;
      StdItem := pStdItem^;
      boFind := True;
      Break;
      end;
    end;

    if not boFind then for i := Low(THumItems) to High(THumItems) do begin
      UserItem := @m_UseItems;
      if (UserItem.wIndex <> 0) and (UserItem.MakeIndex = nMakeIndex) then begin
          pStdItem := UserEngine.GetStdItem(UserItem.wIndex);
          if pStdItem = nil then Exit;
          StdItem := pStdItem^;
          boFind := True;
          Break;
      end;
      end;

    if not boFind then for i := Low(TTigerItems) to High(TTigerItems) do begin
      UserItem := @m_TorDDM.Tiger.Items;
      if (UserItem.wIndex <> 0) and (UserItem.MakeIndex = nMakeIndex) then begin
          pStdItem := UserEngine.GetStdItem(UserItem.wIndex);
          if pStdItem = nil then Exit;
          StdItem := pStdItem^;
          boFind := True;
          Break;
      end;
      end;

end;

if boFind then begin
    ItemUnit.GetItemAddValue(UserItem, StdItem);

    if sName = 'MAKEINDEX' then Result := IntToStr(UserItem.MakeIndex)
    else if sName = 'IDX' then Result := IntToStr(UserItem.wIndex)
    else if sName = 'NAME' then Result := StdItem.FilterName
    else if sName = 'STDNAME' then Result := StdItem.Name
    else if sName = 'STDMODE' then Result := IntToStr(StdItem.StdMode)
    else if sName = 'SHAPE' then Result := IntToStr(StdItem.Shape)
    else if sName = 'WEIGHT' then Result := IntToStr(StdItem.Weight)
    else if sName = 'ANICOUNT' then Result := IntToStr(StdItem.AniCount)
    else if sName = 'SOURCE' then Result := IntToStr(StdItem.Source)
    else if sName = 'RESERVED' then Result := IntToStr(StdItem.Reserved)
    else if sName = 'NEEDAMBIT' then Result := IntToStr(StdItem.NeedAmbit)
    else if sName = 'LOOKS' then Result := IntToStr(StdItem.Looks)
    else if sName = 'DURAMAX' then Result := IntToStr(UserItem.DuraMax)
    else if sName = 'DURA' then Result := IntToStr(UserItem.Dura)
    else if sName = 'AC' then Result := IntToStr(StdItem.AC)
    else if sName = 'AC1' then Result := IntToStr(LoWord(StdItem.AC))
    else if sName = 'AC2' then Result := IntToStr(HiWord(StdItem.AC))
    else if sName = 'MAC' then Result := IntToStr(StdItem.MAC)
    else if sName = 'MAC1' then Result := IntToStr(LoWord(StdItem.MAC))
    else if sName = 'MAC2' then Result := IntToStr(HiWord(StdItem.MAC))
    else if sName = 'DC' then Result := IntToStr(StdItem.DC)
    else if sName = 'DC1' then Result := IntToStr(LoWord(StdItem.DC))
    else if sName = 'DC2' then Result := IntToStr(HiWord(StdItem.DC))
    else if sName = 'MC' then Result := IntToStr(StdItem.MC)
    else if sName = 'MC1' then Result := IntToStr(LoWord(StdItem.MC))
    else if sName = 'MC2' then Result := IntToStr(HiWord(StdItem.MC))
    else if sName = 'SC' then Result := IntToStr(StdItem.SC)
    else if sName = 'SC1' then Result := IntToStr(LoWord(StdItem.SC))
    else if sName = 'SC2' then Result := IntToStr(HiWord(StdItem.SC))
    else if sName = 'GC1' then Result := IntToStr(LoWord(StdItem.GC))
    else if sName = 'GC2' then Result := IntToStr(HiWord(StdItem.GC))
    else if sName = 'NEED' then Result := IntToStr(StdItem.Need)
    else if sName = 'NEEDLEVEL' then Result := IntToStr(StdItem.NeedLevel)
    else if sName = 'FEATURE' then Result := IntToStr(StdItem.Feature)
    else if sName = 'NEEDRACE' then Result := IntToStr(StdItem.NeedRace)
    else if sName = 'THUMP' then Result := IntToStr(StdItem.StdItemAdd.btThump)
    else if sName = 'THUMP2' then Result := IntToStr(StdItem.StdItemAdd.btThump2)
    else if sName = 'MAGICNICETY' then Result := IntToStr(StdItem.StdItemAdd.btMagicNicety)
    else if sName = 'HEROIC' then Result := IntToStr(StdItem.StdItemAdd.wHeroic)
    else if sName = 'MAXHOLE' then Result := IntToStr(StdItem.StdItemAdd.btHole)
    else if sName = 'PRICE' then Result := IntToStr(StdItem.Price)
    else if sName = 'STOCK' then Result := IntToStr(StdItem.Stock)
    else if sName = 'CLIAN1ATTRIB' then Result := IntToStr(StdItem.StdItemAdd.btCLianAttrib)
    else if sName = 'CLIAN1VAL' then Result := IntToStr(StdItem.StdItemAdd.dwCLianVal)
    else if sName = 'CLIAN1VAL1' then Result := IntToStr(LoWord(StdItem.StdItemAdd.dwCLianVal))
    else if sName = 'CLIAN1VAL2' then Result := IntToStr(HiWord(StdItem.StdItemAdd.dwCLianVal))
    else if sName = 'CLIAN1EXP' then Result := IntToStr(StdItem.StdItemAdd.dwCLianExp)
    else if sName = 'CLIAN2ATTRIB' then Result := IntToStr(StdItem.StdItemAdd.btCLianAttrib)
    else if sName = 'CLIAN2VAL' then Result := IntToStr(StdItem.StdItemAdd.dwCLianVal)
    else if sName = 'CLIAN2VAL1' then Result := IntToStr(LoWord(StdItem.StdItemAdd.dwCLianVal))
    else if sName = 'CLIAN2VAL2' then Result := IntToStr(HiWord(StdItem.StdItemAdd.dwCLianVal))
    else if sName = 'CLIAN2EXP' then Result := IntToStr(StdItem.StdItemAdd.dwCLianExp)
    else if sName = 'CLIAN3ATTRIB' then Result := IntToStr(StdItem.StdItemAdd.btCLianAttrib)
    else if sName = 'CLIAN3VAL' then Result := IntToStr(StdItem.StdItemAdd.dwCLianVal)
    else if sName = 'CLIAN3VAL1' then Result := IntToStr(LoWord(StdItem.StdItemAdd.dwCLianVal))
    else if sName = 'CLIAN3VAL2' then Result := IntToStr(HiWord(StdItem.StdItemAdd.dwCLianVal))
    else if sName = 'CLIAN3EXP' then Result := IntToStr(StdItem.StdItemAdd.dwCLianExp)
    else if sName = 'SEAL' then Result := IntToStr(_Lo(UserItem.btValue))
    else if sName = 'LONGLEVEL' then Result := IntToStr(UserItem.btItemExt + 1)
    else if sName = 'LONGCUREXP' then Result := UInt64ToStr(PUInt64(@UserItem.btItemExt)^)
    else if sName = 'LONGALLEXP' then begin
      nExp := PUInt64(@UserItem.btItemExt)^;
      i := _MIN(UserItem.btItemExt, 200);
      while i > 0 do begin
      Dec(i);
      Inc(nExp, g_Config.LongLevelUpExp);
      end;
      Result := UInt64ToStr(nExp);
    end else if Pos('VALUE', sName) = 1 then begin
      ArrestStringEx(sName, '(', ')', s18);
      p := Str_ToInt(s18, -1);
      if (p in ) then
      Result := IntToStr(UserItem.btValue)
      else
      Result := '0';
    end else if Pos('CUSTOM', sName) = 1 then begin
      ArrestStringEx(sName, '(', ')', s18);
      p := Str_ToInt(s18, -1);
      if (p in ) then
      Result := IntToStr(UserItem.btExtra.btCustomValue)
      else
      Result := '0';
    end else if Pos('ITEMEXTEX', sName) = 1 then begin
      if Pos('ITEMEXTEX(', sName) = 1 then
      ArrestStringEx(sName, '(', ')', s18)
      else
      ArrestStringEx(sName, '[', ']', s18);
      if g_FunctionNPC = nil then Exit;
      s18 := g_FunctionNPC.GetPlayObjectInfo(TPlayObject(Self), s18);
      p := Str_ToInt(s18, -1);
      case p of
      0..9: Result := IntToStr(UserItem.btExtra.Shield.sEx);
      147..148: Result := IntToStr(UserItem.btExtra.Shield.sEx);
      end;
    end else if Pos('ITEMEXT', sName) = 1 then begin
      if Pos('ITEMEXT(', sName) = 1 then
      ArrestStringEx(sName, '(', ')', s18)
      else
      ArrestStringEx(sName, '[', ']', s18);
      if g_FunctionNPC = nil then Exit;
      s18 := g_FunctionNPC.GetPlayObjectInfo(TPlayObject(Self), s18);
      p := Str_ToInt(s18, -1);
      case p of
      21: Result := IntToStr(UserItem.DuraMax);
      22: Result := IntToStr(MakeWord(UserItem.btItemExt, UserItem.btItemExt));
      23..38: Result := IntToStr(_Hi(UserItem.btItemExt));
      39..54: Result := IntToStr(_Lo(UserItem.btItemExt));
      55..70: Result := IntToStr(UserItem.btItemExt);
      71: Result := IntToStr(MakeLong(MakeWord(UserItem.btValue, UserItem.btValue), MakeWord(UserItem.btValue, UserItem.btValue)));
      72: Result := IntToStr(MakeLong(MakeWord(UserItem.btItemExt, UserItem.btItemExt), MakeWord(UserItem.btItemExt, UserItem.btItemExt)));
      73..79: Result := '0';
      80..92: Result := IntToStr(UserItem.btItemExt);
      100: Result := IntToStr(UserItem.btItemExt);
      101: Result := IntToStr(MakeLong(MakeWord(UserItem.btItemExt2, UserItem.btItemExt2), MakeWord(UserItem.btItemExt2, UserItem.btItemExt2)));
      120..149: Result := IntToStr(UserItem.btItemExt);
      169: Result := IntToStr(PWORD(@UserItem.btItemExt)^);
      170: Result := IntToStr(PDWORD(@UserItem.btItemExt)^);
      216: Result := IntToStr(UserItem.btExtra.Shield.dwHP);
      217..218: Result := IntToStr(UserItem.btExtra.Shield.btValue);
      219: Result := IntToStr(UserItem.btExtra.Shield.wStrengHP);
      220: Result := IntToStr(UserItem.btExtra.Shield.wStrengDC);
      221: Result := IntToStr(UserItem.btExtra.Shield.wStrengAC);
      222: Result := IntToStr(UserItem.btExtra.Shield.wStrengMAC);
      223: Result := IntToStr(UserItem.btExtra.Shield.wAwaken);
      224: Result := IntToStr(UserItem.btExtra.Shield.btValue);
      225: Result := IntToStr(UserItem.btExtra.Shield.wAwakenVal1);
      226: Result := IntToStr(UserItem.btExtra.Shield.wAwakenVal2);
      227..228: Result := IntToStr(UserItem.btExtra.Shield.btValue);
      229: Result := IntToStr(UserItem.btExtra.Shield.wDivineVal1);
      230: Result := IntToStr(UserItem.btExtra.Shield.wDivineVal2);
      231: Result := IntToStr(UserItem.btExtra.Shield.wNowExp);
      232: Result := IntToStr(UserItem.btExtra.Shield.wMaxExp);
      233: Result := IntToStr(UserItem.btExtra.Shield.nStrengGold);
      234: Result := IntToStr(UserItem.btExtra.Shield.wStrengMaterial);
      235: Result := IntToStr(UserItem.btExtra.Shield.nAwakenGold);
      236: Result := IntToStr(UserItem.btExtra.Shield.wAwakenMaterial);
      237: Result := IntToStr(UserItem.GetItemPunch(1));
      238: Result := IntToStr(UserItem.GetItemPunch(2));
      239: Result := IntToStr(UserItem.GetItemPunch(3));
      240: Result := IntToStr(UserItem.btItemExt2);
      241: Result := IntToStr(UserItem.btExtra.Spirit.btLevel);
      242: Result := IntToStr(UserItem.btExtra.Spirit.btPosition);
      243: Result := IntToStr(UserItem.btExtra.Spirit.nValue1);
      244: Result := IntToStr(UserItem.btExtra.Spirit.nValue2);
      245: Result := IntToStr(UserItem.btExtra.Spirit.btLevel);
      246: Result := IntToStr(UserItem.btExtra.Spirit.btPosition);
      247: Result := IntToStr(UserItem.btExtra.Spirit.nValue1);
      248: Result := IntToStr(UserItem.btExtra.Spirit.nValue2);
      249: Result := IntToStr(UserItem.btExtra.Shield.wVampirePoint);
      250: Result := IntToStr(PDWORD(@UserItem.btItemExt2)^);
      251: Result := IntToStr(PDWORD(@UserItem.btItemExt2)^);
      252: Result := IntToStr(PDWORD(@UserItem.btItemExt2)^);
      253: Result := IntToStr(PDWORD(@UserItem.btItemExt2)^);
      254: Result := IntToStr(PDWORD(@UserItem.btItemExt2)^);
      255: Result := IntToStr(PDWORD(@UserItem.btItemExt2)^);
      256: Result := IntToStr(PDWORD(@UserItem.btItemExt2)^);
      257: Result := IntToStr(PDWORD(@UserItem.btItemExt2)^);
      258: Result := IntToStr(PDWORD(@UserItem.btItemExt2)^);
      267: Result := IntToStr(PDWORD(@UserItem.btItemExt)^);
      268: begin
            SetLength(s18, 15);
            Move(UserItem^.btItemExt2, PChar(s18)^, 15);
            Result := s18;
          end;
      269: begin
            SetLength(s18, 15);
            Move(UserItem^.btItemExt2, PChar(s18)^, 15);
            Result := s18;
          end;
      270: begin
            SetLength(s18, 15);
            Move(UserItem^.btItemExt2, PChar(s18)^, 15);
            Result := s18;
          end;
      271: begin
            SetLength(s18, 15);
            Move(UserItem^.btItemExt2, PChar(s18)^, 15);
            Result := s18;
          end;
      274: Result := IntToStr(MakeLong(MakeWord(UserItem.btItemExt, UserItem.btItemExt), MakeWord(UserItem.btItemExt, UserItem.btItemExt)));
      275: Result := IntToStr(MakeLong(MakeWord(UserItem.btItemExt, UserItem.btItemExt), MakeWord(UserItem.btItemExt, UserItem.btItemExt)));

      end;
    end else if sName = 'GLOOMPOINT' then
      Result := IntToStr(MakeWord(UserItem.btItemExt, UserItem.btItemExt))

    else if Pos('LOGLOOM', sName) = 1 then begin
      ArrestStringEx(sName, '(', ')', s18);
      p := Str_ToInt(s18, -1);
      if (p in ) then
      Result := IntToStr(_Hi(UserItem.btItemExt))
      else
      Result := '0';
    end else if Pos('HIGLOOM', sName) = 1 then begin
      ArrestStringEx(sName, '(', ')', s18);
      p := Str_ToInt(s18, -1);
      if (p in ) then
      Result := IntToStr(_Lo(UserItem.btItemExt))
      else
      Result := '0';
    end else if sName = 'OVERLAP' then
      Result := IntToStr(MakeLong(MakeWord(UserItem.btValue,
      UserItem.btValue), MakeWord(UserItem.btValue, UserItem.btValue)))
    else if Pos('EVIL', sName) = 1 then begin
      if UserItem.Evil.MakeIndex = 0 then Result := ''
      else if sName = 'EVILNAME' then
      Result := UserItem.Evil.sName
      else if sName = 'EVILJOB' then
      Result := IntToJob(UserItem.Evil.btJob)
      else if sName = 'EVILAMBIT' then
      Result := IntToStr(UserItem.Evil.btAmbit)
      else if sName = 'EVILDC' then
      Result := IntToStr(LoByte(UserItem.Evil.wDC))
      else if sName = 'EVILDC2' then
      Result := IntToStr(HiByte(UserItem.Evil.wDC))
      else if sName = 'EVILMC' then
      Result := IntToStr(LoByte(UserItem.Evil.wMC))
      else if sName = 'EVILMC2' then
      Result := IntToStr(HiByte(UserItem.Evil.wMC))
      else if sName = 'EVILSC' then
      Result := IntToStr(LoByte(UserItem.Evil.wSC))
      else if sName = 'EVILSC2' then
      Result := IntToStr(HiByte(UserItem.Evil.wSC))
      else if sName = 'EVILAC' then
      Result := IntToStr(LoByte(UserItem.Evil.wDC))
      else if sName = 'EVILAC2' then
      Result := IntToStr(HiByte(UserItem.Evil.wDC))
      else if sName = 'EVILMAC' then
      Result := IntToStr(LoByte(UserItem.Evil.wMC))
      else if sName = 'EVILMAC2' then
      Result := IntToStr(HiByte(UserItem.Evil.wMC))
      else if sName = 'EVILPOWER' then
      Result := IntToStr(UserItem.Evil.wPower)
    end else if Pos('PET.', sName) = 1 then begin                                                   //灵兽石属性
      if sName = 'PET.NAME' then
      Result := UserItem.sExName
      else if sName = 'PET.TYPE' then
      Result := IntToStr(UserItem.btValue)
      else if sName = 'PET.KIND' then Result := IntToStr(StdItem.AniCount)
      else if sName = 'PET.LEVEL' then
      Result := IntToStr(UserItem.wLevel)
      else if sName = 'PET.TYPENAME' then begin
      case UserItem.btValue of
          0: Result := '小灵兽';
          1: Result := '灵兽1';
          2: Result := '灵兽2';
          3: Result := '灵兽3';
      else
          Result := '灵兽(未知)';
      end;
      end
      else if sName = 'PET.EXP' then
      Result := IntToStr(UserItem.dwExp)
      else if sName = 'PET.MAXEXP' then begin
      Result := IntToStr(GetPetUpExp(UserItem.btValue, UserItem.wLevel));
      end
      else if sName = 'PET.STATE' then begin
      tm := MakeLong(MakeWord(UserItem.btValue, UserItem.btValue), MakeWord(UserItem.btValue, UserItem.btValue));
      if tm = 0 then tm := DateTimeToWolTIme(Now);
      n18 := DateTimeToWolTIme(Now) - tm;
      n18 := n18 div 86400;
      if n18 <= 2 then Result := '饱'
      else if n18 = 3 then Result := '微饿'
      else if n18 = 4 then Result := '饥饿'
      else Result := '死亡';
      end
      else if sName = 'PET.EATTIME' then begin
      tm := MakeLong(MakeWord(UserItem.btValue, UserItem.btValue), MakeWord(UserItem.btValue, UserItem.btValue));
      if tm = 0 then tm := DateTimeToWolTIme(Now);
      Result := IntToStr((DateTimeToWolTIme(Now) - tm) div 3600);
      end else if sName = 'PET.RELIVE' then
      Result := IntToStr(UserItem.btValue)
      else if sName = 'PET.PILEEXP' then
      Result := IntToStr(UserItem.dwTotalExp)
      else if sName = 'PET.EVOLUTION' then
      Result := IntToStr(UserItem.wEvoluTion)
      else if sName = 'PET.APTITUDE' then
      Result := IntToStr(UserItem.btAptiTude)
      else if sName = 'PET.HP' then
      Result := IntToStr(UserItem.wHP)
      else if sName = 'PET.MP' then
      Result := IntToStr(UserItem.wMP)
      else if sName = 'PET.ANTIPOISON' then
      Result := IntToStr(UserItem.btAntiPoison)
      else if sName = 'PET.MAC1' then
      Result := IntToStr(LoByte(UserItem.wMAC))
      else if sName = 'PET.MAC2' then
      Result := IntToStr(HiByte(UserItem.wMAC))
      else if sName = 'PET.MAGICNICETY' then
      Result := IntToStr(UserItem.btMagicNicety)
      else if sName = 'PET.EVADET' then
      Result := IntToStr(UserItem.btEvaDet)
      else if sName = 'PET.AC1' then
      Result := IntToStr(LoByte(UserItem.wAC))
      else if sName = 'PET.AC2' then
      Result := IntToStr(HiByte(UserItem.wAC))
      else if sName = 'PET.ANTIMAGIC' then
      Result := IntToStr(UserItem.btAntiMagic)
      else if sName = 'PET.POISONNICETY' then
      Result := IntToStr(UserItem.btPoisonNicety)
      else if sName = 'PET.SAVVY' then
      Result := IntToStr(UserItem.btSavvy)
      else if sName = 'PET.FELEMENT1' then begin
      case UserItem.btFelemEntType of
          0: Result := '金';
          1: Result := '木';
          2: Result := '土';
          3: Result := '水';
      end;
      end else if sName = 'PET.FELEMENT2' then begin
      case UserItem.btFelemEntType of
          0: Result := '火';
          1: Result := '木';
          2: Result := '土';
          3: Result := '水';
      end;
      end else if sName = 'PET.FELEMENTPOINT1' then
      Result := IntToStr(UserItem.btFelemEntPoint)
      else if sName = 'PET.FELEMENTPOINT2' then
      Result := IntToStr(UserItem.btFelemEntPoint)
      else if sName = 'PET.MC1' then
      Result := IntToStr(LoByte(UserItem.wMC))
      else if sName = 'PET.MC2' then
      Result := IntToStr(HiByte(UserItem.wMC))
      else if sName = 'PET.SC1' then
      Result := IntToStr(LoByte(UserItem.wSC))
      else if sName = 'PET.SC2' then
      Result := IntToStr(HiByte(UserItem.wSC))
      else if sName = 'PET.DC1' then
      Result := IntToStr(LoByte(UserItem.wDC))
      else if sName = 'PET.DC2' then
      Result := IntToStr(HiByte(UserItem.wDC))
      else if sName = 'PET.NICETY' then
      Result := IntToStr(UserItem.btHitNicety)
      else if sName = 'PET.LUCK' then
      Result := IntToStr(UserItem.btLuck)
      else if sName = 'PET.SPEED' then
      Result := IntToStr(UserItem.btRideSpeed)
      else if sName = 'PET.GENDER' then
      Result := IntToStr(UserItem.btItemExt)                                                //性别
      else if sName = 'PET.PARALY' then
      Result := IntToStr(UserItem.btItemExt)
      else if sName = 'PET.THUMP' then
      Result := IntToStr(UserItem.btItemExt)
      else if sName = 'PET.AGAINST' then
      Result := IntToStr(MakeWord(UserItem.btItemExt, UserItem.btItemExt))
      else if sName = 'PET.REDUCEAC' then
      Result := IntToStr(UserItem.btItemExt)
      else if sName = 'PET.REDUCEMAC' then
      Result := IntToStr(UserItem.btItemExt)
      else if sName = 'PET.REDUCEHITPOINT' then
      Result := IntToStr(UserItem.btItemExt)
      else if sName = 'PET.REDUCEANTIMAGIC' then
      Result := IntToStr(UserItem.btItemExt)
      else if sName = 'PET.SIRE' then
      Result := IntToStr(UserItem.btItemExt)
      else if sName = 'PET.SIREMAX' then
      Result := IntToStr(UserItem.btItemExt)
      else if sName = 'PET.BLOODPURE' then
      Result := IntToStr(UserItem.btItemExt)
      else if sName = 'PET.STRENG' then
      Result := IntToStr(UserItem.btItemExt)
      else if sName = 'PET.INSIGHTLEVEL' then
      Result := IntToStr(UserItem.btExtra.btLevel)
      else if sName = 'PET.QUALIFICATION' then
      Result := IntToStr(UserItem.btExtra.btInsight)
      else if sName = 'PET.INSIGHTEXP' then
      Result := IntToStr(UserItem.btExtra.nExp)
      else if sName = 'PET.INSIGHTMAXEXP' then
      Result := IntToStr(UserItem.btExtra.nMaxExp)
      else if sName = 'PET.NEXTQUALIFICATION' then
      Result := IntToStr(UserItem.btExtra.btNext)
      else if sName = 'PET.INSIGHTMAGICID(0)' then
      Result := IntToStr(UserItem.btExtra.PetSkill.GetID)
      else if sName = 'PET.INSIGHTMAGICID(1)' then
      Result := IntToStr(UserItem.btExtra.PetSkill.GetID)
      else if sName = 'PET.INSIGHTMAGICID(2)' then
      Result := IntToStr(UserItem.btExtra.PetSkill.GetID)
      else if sName = 'PET.INSIGHTMAGICID(3)' then
      Result := IntToStr(UserItem.btExtra.PetSkill.GetID)
      else if sName = 'PET.INSIGHTMAGICLEVEL(0)' then
      Result := IntToStr(UserItem.btExtra.PetSkill.GetLv)
      else if sName = 'PET.INSIGHTMAGICLEVEL(1)' then
      Result := IntToStr(UserItem.btExtra.PetSkill.GetLv)
      else if sName = 'PET.INSIGHTMAGICLEVEL(2)' then
      Result := IntToStr(UserItem.btExtra.PetSkill.GetLv)
      else if sName = 'PET.INSIGHTMAGICLEVEL(3)' then
      Result := IntToStr(UserItem.btExtra.PetSkill.GetLv)
      else if sName = 'PET.INSIGHTMAGICVALUE(0)' then
      Result := IntToStr(UserItem.btExtra.PetSkill.GetValue)
      else if sName = 'PET.INSIGHTMAGICVALUE(1)' then
      Result := IntToStr(UserItem.btExtra.PetSkill.GetValue)
      else if sName = 'PET.INSIGHTMAGICVALUE(2)' then
      Result := IntToStr(UserItem.btExtra.PetSkill.GetValue)
      else if sName = 'PET.INSIGHTMAGICVALUE(3)' then
      Result := IntToStr(UserItem.btExtra.PetSkill.GetValue)
      else
      Result := '';
    end else if Pos('OFFICERVALUE', sName) = 1 then begin                                           //仙官装备属性
      ArrestStringEx(sName, '(', ')', s18);
      p := Str_ToInt(s18, -1);
      if (p in ) then
      Result := IntToStr(PWORD(@UserItem.btValue)^)
      else
      Result := '0';
    end else if Pos('GODITEM.', sName) = 1 then begin                                             //神兵装备属性
      if sName = 'GODITEM.NAME' then
      Result := UserItem.God_Nmae
      else if sName = 'GODITEM.HUMNAME' then
      Result := UserItem.God_MainNmae
      else if sName = 'GODITEM.MINDC' then
      Result := IntToStr(UserItem.God_MinDC)
      else if sName = 'GODITEM.MAXDC' then
      Result := IntToStr(UserItem.God_MaxDC)
      else if sName = 'GODITEM.REDUCEAC' then
      Result := IntToStr(UserItem.God_ReduceAC)
      else if sName = 'GODITEM.REDUCEMAC' then
      Result := IntToStr(UserItem.God_ReduceMAC)
      else if sName = 'GODITEM.USEVAL' then
      Result := IntToStr(UserItem.God_UseVal)
      else if sName = 'GODITEM.JOB' then
      Result := IntToStr(UserItem.God_Job)
      else if sName = 'GODITEM.RULER' then
      Result := IntToStr(UserItem.God_Ruler)
      else if sName = 'GODITEM.GOD' then
      Result := IntToStr(Integer(UserItem.IsGod))
      else if sName = 'GODITEM.SUITE' then begin
      if StdItem.StdMode = 5 then begin
          Result := IntToStr(UserItem.btItemExt)
      end else if StdItem.StdMode in then begin
          Result := IntToStr(UserItem.btItemExt)
      end;
      end else
      Result := '';
    end else if Pos('GEM', sName) = 1 then begin                                                    //装备镶嵌玉石的属性
      Result := '0';
      //s19 := ArrestStringEx(sName, '[', ']', s18);
      if CheckBrackets(sName, s18) then begin
      s19 := Copy(sName, Length('GEM().') + Length(s18) + 1, Length(sName));
      if g_FunctionNPC <> nil then
          s18 := g_FunctionNPC.GetPlayObjectInfo(Self, s18);
      p := Str_ToInt(s18, -1);
      if p in then begin
          Dec(p);
          if s19 = 'HOLE' then begin
            tm := UserItem.btItemExt and $0F;
            if tm in then begin
            if p = 0 then
                Result := '1'
            else
                Result := IntToStr(tm);
            end else if tm = 3 then
            Result := '2'
            else if tm = 7 then
            Result := '3';
          end else if s19 = 'LV' then
            Result := IntToStr(UserItem.btItemExt shr 4)
          else if s19 = 'MAG' then
            Result := IntToStr(UserItem.btItemExt)
          else
            Result := '';
      end;
      end;
    end else if Pos('JEWEL', sName) = 1 then begin                                                //装备镶嵌玉石的属性
      if CheckBrackets(sName, s18) then begin
      s19 := Copy(sName, Length('JEWEL().') + Length(s18) + 1, Length(sName));
      if g_FunctionNPC <> nil then
          s18 := g_FunctionNPC.GetPlayObjectInfo(Self, s18);
      p := Str_ToInt(s18, -1);
      if p in then begin
          if s19 = 'SHAPE' then
            Result := '0'
          else if s19 = 'NAME' then Result := '';
          if UserItem.GetItemPunch(p) = 0 then Exit;
          StdStone := UserEngine.GetStdItem(UserItem.btExtra.ItemIndex);
          if (StdStone = nil) or (StdStone.StdMode <> 141) then Exit;
          if s19 = 'SHAPE' then
            Result := IntToStr(StdStone^.Shape)
          else if s19 = 'NAME' then
            Result := StdStone^.Name;
      end;
      end;
    end else if Pos('HOLECOUNT', sName) = 1 then begin                                              //装备镶嵌玉石的属性
      p := 1;
      for i := 0 to 4 do
      if UserItem.btItemExt > 0 then
          Inc(p);
      Result := IntToStr(p);
    end else if Pos('GOODITEMTYPE', sName) = 1 then begin
      ArrestStringEx(sName, '(', ')', s18);
      p := Str_ToInt(s18, -1);
      if p in then begin
      case p of
          1: Result := IntToStr(UserItem.btItemExt div 16);
          2: Result := IntToStr(UserItem.btItemExt div 16);
          3: Result := IntToStr(UserItem.btItemExt div 16);
      end;
      end;
    end else if Pos('GOODITEMVALUE', sName) = 1 then begin
      ArrestStringEx(sName, '(', ')', s18);
      p := Str_ToInt(s18, -1);
      if p in then begin
      case p of
          1: begin
            n18 := UserItem.btItemExt div 16;
            Result := IntToStr(UserItem.btItemExt - (n18 * 16));
            end;
          2: begin
            n18 := UserItem.btItemExt div 16;
            Result := IntToStr(UserItem.btItemExt - (n18 * 16));
            end;
          3: begin
            n18 := UserItem.btItemExt div 16;
            Result := IntToStr(UserItem.btItemExt - (n18 * 16));
            end;
      end;
      end;
    end else if Pos('SOULBEAD', sName) = 1 then begin
      if sName = 'SOULBEADLEVEL' then begin
      Result := IntToStr(UserItem.btValue);
      end else if sName = 'SOULBEADHP' then begin
      Result := IntToStr(PWORD(@UserItem.btValue)^);
      end else if sName = 'SOULBEADCUREXP' then begin
      Result := UInt64ToStr(PINT64(@UserItem.btItemExt)^);
      end else if sName = 'SOULBEADMAXEXP' then begin
      if StdItem.AniCount = 0 then
          nSoulExp := g_Config.SoulBead0
      else
          nSoulExp := g_Config.SoulBead1;
      Result := UInt64ToStr(nSoulExp);
      end;
    end else if sName = 'CUSTOMNAME' then begin
      ItemUnit.GetCustomItemName(UserItem, s19);
      Result := s19;
    end;
end;
end;

function TPlayObject.GetDigUpMsgCount: Integer;
var
i                                     : Integer;
SendMessage                           : pTSendMessage;
begin
Result := 0;
try
    EnterCriticalSection(ProcessMsgCriticalSection);
    for i := 0 to m_MsgList.Count - 1 do begin
      SendMessage := m_MsgList.Items;
      if (SendMessage.wIdent = CM_BUTCH) then begin
      Inc(Result);
      end;
    end;
finally
    LeaveCriticalSection(ProcessMsgCriticalSection);
end;
end;

function TPlayObject.GetExploit(PlayObject: TBaseObject): Boolean;
var
nMaxExp                               : integer;
btLevel                               : Byte;
begin
Result := False;
btLevel := PlayObject.m_MilitaryInfo.nLevel;
nMaxExp := g_Config.MilitaryRank.nNextLevelExp;
if (PlayObject.m_MilitaryInfo.nExp >= nMaxExp) then begin
    Result := True;
    while True do begin
      btLevel := PlayObject.m_MilitaryInfo.nLevel;
      nMaxExp := g_Config.MilitaryRank.nNextLevelExp;
      if (PlayObject.m_MilitaryInfo.nExp >= nMaxExp) and (nMaxExp > 0) and (btLevel < 81) then begin
      if (btLevel mod 9 <> 0) or (g_Config.MilitaryRank.boAutoLevelUp) then begin
          Dec(PlayObject.m_MilitaryInfo.nExp, nMaxExp);
          Inc(PlayObject.m_MilitaryInfo.nLevel);
      end;
      end else
      Break;
    end;
end;
end;

function TPlayObject.GetWingExp(): Boolean;
var
nMaxExp                               : integer;
btLevel                               : Byte;
begin
Result := False;
btLevel := m_HumWingInfo.nLevel;
nMaxExp := g_Config.RepressDemonWings.LevelData.NextLevelExp;
if (m_HumWingInfo.nExp >= nMaxExp) then begin
    Result := True;
    while True do begin
      btLevel := m_HumWingInfo.nLevel;
      nMaxExp := g_Config.RepressDemonWings.LevelData.NextLevelExp;
      if (m_HumWingInfo.nExp >= nMaxExp) and (nMaxExp > 0) and (btLevel < 50) then begin
      if g_Config.RepressDemonWings.LevelData.AutoLevelUp then begin
          Dec(m_HumWingInfo.nExp, nMaxExp);
          Inc(m_HumWingInfo.nLevel);
      end else begin
          m_HumWingInfo.nExp := nMaxExp;
          Break;
      end;
      end else
      Break;
    end;
end;

if m_HumWingInfo.btWear > 99 then
    m_HumWingInfo.btWingLook := m_HumWingInfo.btWear
else
    m_HumWingInfo.btWingLook := g_Config.RepressDemonWings.LevelData.Wing_Look;
end;

function TPlayObject.GetBeadExp(): Boolean;
var
nMaxExp                               : integer;
btLevel                               : Byte;
begin
Result := False;
btLevel := m_RepressDemon.nLevel;
nMaxExp := g_Config.RepressDemon.nNextLevelExp;
if (m_RepressDemon.nExp >= nMaxExp) then begin
    Result := True;
    while True do begin
      btLevel := m_RepressDemon.nLevel;
      nMaxExp := g_Config.RepressDemon.nNextLevelExp;
      if (m_RepressDemon.nExp >= nMaxExp) and (nMaxExp > 0) and (btLevel < 60) then begin
      Dec(m_RepressDemon.nExp, nMaxExp);
      Inc(m_RepressDemon.nLevel);
      end else
      Break;
    end;
end;
end;

//人物经验值增长

procedure TPlayObject.GetExp(nExp: UInt64; nMilitaryExp: UInt64; nRepressDemon: UInt64; bScritpExp: Boolean = False; boShareMilitaryExp: Boolean = False; boShareRepressDemon: Boolean = False);
var
nShareExp1, nShareExp2, nShareExp3    : UInt64;
begin
nShareExp1 := 0;
nShareExp2 := 0;
nShareExp3 := 0;
if m_boPneuma then begin                                                                        //是元神
    if m_PneumaObject <> nil then begin                                                             //元神主人 <> nil
      nShareExp1 := _Max(0, nExp div 3);
      if (not boShareMilitaryExp) and (bScritpExp) then                                             //判断脚本是否分享给元神
      nShareExp2 := nMilitaryExp
      else
      nShareExp2 := _Max(0, nMilitaryExp div 3);                                                //判断脚本是否分享给元神
      if (not boShareRepressDemon) and (bScritpExp) or ((m_PneumaObject as TPlayObject).m_RepressDemon.nLevel = 0) then
      nShareExp3 := nRepressDemon
      else
      nShareExp3 := _Max(0, nRepressDemon div 3);

      GetExpProc(nShareExp1, nShareExp2, nShareExp3, bScritpExp);                                 //元神 1/3
      (m_PneumaObject as TPlayObject).GetExpProc(_Max(0, nExp - nShareExp1), _MAX(0, nMilitaryExp - nShareExp2), _MAX(0, nRepressDemon - nShareExp3), bScritpExp);
      //主任 2/3
    end;
end else begin                                                                                    //是人物
    if (m_btJob = 3) then
      nExp := GetYaoDanShareExp(nExp);

    if (m_PneumaObject <> nil) and (not m_boPneumaEffMode) then begin                               //元神在线
      nShareExp1 := _Max(0, nExp div 3);
      nShareExp2 := _Max(0, nMilitaryExp div 3);
      if ((m_PneumaObject as TPlayObject).m_RepressDemon.nLevel > 0) and (boShareRepressDemon) then
      nShareExp3 := _Max(0, nRepressDemon div 3);
      nExp := _Max(0, nExp - nShareExp1);
      nMilitaryExp := _Max(0, nMilitaryExp - nShareExp2);
      if ((m_PneumaObject as TPlayObject).m_RepressDemon.nLevel > 0) and (boShareRepressDemon) then
      nRepressDemon := _Max(0, nRepressDemon - nShareExp3);
      (m_PneumaObject as TPlayObject).GetExpProc(nShareExp1, nShareExp2, nShareExp3, bScritpExp);
      GetExpProc(nExp, nMilitaryExp, nRepressDemon, bScritpExp);
    end else                                                                                        //元神不在线或没元神
      GetExpProc(nExp, nMilitaryExp, nRepressDemon, bScritpExp);
end;
end;

procedure TPlayObject.GetExpProc(nGetExp: UInt64; nGetMilitaryExp: UInt64; nGetRepressDemonExp: UInt64; bScritpExp: Boolean = False);
var
n14, nCode, nType                     : Integer;
nInt                                  : UInt64;
nSoulExp, nNewSoulExp, nSoulMaxExp    : UInt64;
nMaxExp, nAccrued                     : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
boRecalc, boLevelUp                   : Boolean;
RefExpPacket                        : TRefExpPacket;
boReachMaxLevel                     : Boolean;
boReachLevelLimitExp                  : Boolean;
resourcestring
sSoulExpMsg                           = '在%s的作用下,额外增加了%d经验';
sTimeBackExpMsg                     = '%s增加%d点经验(穿戴真魂珠后,主体不增加经验)';
begin
if m_PEnvir = nil then Exit;

//检测是否到达最高等级,限制等级后经验槽达100%满
if (g_Config.nLimitLevel = m_Abil.level) and ((m_Abil.Exp + nGetExp) >= m_Abil.MaxExp) then begin
    if m_Abil.Exp < m_Abil.MaxExp then begin
      //向客户端发送经验
      RefExpPacket.nExp := m_Abil.Exp;
      RefExpPacket.nInc := m_Abil.MaxExp - m_Abil.Exp;
      SendMsg(Self, RM_WINEXP, 0, m_Abil.MaxExp - m_Abil.Exp, 0, 0, EnCodeBuffer(@RefExpPacket, SizeOf(TRefExpPacket)));
      m_Abil.Exp := m_Abil.MaxExp;
    end;
    Exit;
end;

//功勋值触发
if (nGetMilitaryExp > 0) and (g_Config.boMagicCityServer) and (m_MilitaryInfo.nLevel > 0) then begin
    Inc(m_MilitaryInfo.nExp, nGetMilitaryExp);
    m_sScriptParam := UInt64ToStr(nGetMilitaryExp);
    m_sScriptParam := BoolToIntStr(bScritpExp);
    m_sScriptParam := BoolToIntStr(GetExploit(TBaseObject(Self)));
    ExecuteScript(g_ManageNPC, '@GetMilitaryExpFucn');
    SysMsg(Format('%d功勋值增加', ), c_Red, t_Hint);
end;

//镇魔珠经验触发
{$IF DEMONSERVER = 1}
if (nGetRepressDemonExp > 0) and (m_RepressDemon.nLevel > 0) then begin
    Inc(m_RepressDemon.nExp, nGetRepressDemonExp);
    m_sScriptParam := UInt64ToStr(nGetRepressDemonExp);
    m_sScriptParam := BoolToIntStr(bScritpExp);
    m_sScriptParam := BoolToIntStr(GetBeadExp());
    ExecuteScript(g_ManageNPC, '@GetRepressDemonExpFucn');
    SysMsg(Format('镇魔珠增加%d经验', ), c_Red, t_Hint);
end;
{$IFEND}
if nGetExp = 0 then Exit;

if (not bScritpExp) then begin
    UserItem := @m_UseItems;                                                            //魂珠
    if (UserItem.wIndex > 0) and (UserItem.btValue = 0) and (UserItem.btValue > 0) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem <> nil then begin
      nSoulExp := (nGetExp * UserItem.btValue) div 100;                                       //整除
      if (nSoulExp > 0) then begin
          Inc(nGetExp, nSoulExp);
          SysMsg(Format(sSoulExpMsg, ), c_Red, t_Hint);
      end;
      end;
    end;
end;

if (not g_Config.boClassicServer) then                                                            //Script 2016.07.01 时光区魂珠
begin
    if {(not bScritpExp) and }(nGetExp > 0) then begin
      UserItem := @m_UseItems;
      if (UserItem.wIndex > 0) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem.StdMode = 99 then begin
          if StdItem.AniCount = 0 then
            nSoulMaxExp := g_Config.SoulBead0]
          else
            nSoulMaxExp := g_Config.SoulBead1];
          if (nGetExp > 0) then begin
            if g_Config.boWearSoulBeadPlayerExp then
            begin
            nSoulExp := PINT64(@UserItem.btItemExt)^;
            nNewSoulExp := nGetExp + nSoulExp;
            if nNewSoulExp >= nSoulMaxExp then begin
                nGetExp := _MAX(0, nNewSoulExp - nSoulMaxExp);
                nSoulExp := nSoulMaxExp;
                PINT64(@UserItem.btItemExt)^ := nSoulExp;
            end else begin
                nSoulExp := nGetExp;
                nGetExp := 0;
                PINT64(@UserItem.btItemExt)^ := PINT64(@UserItem.btItemExt)^ + nSoulExp;
                SysMsg(Format(sTimeBackExpMsg, ), c_Red, t_Hint);
            end;
            SendUpdateItem(UserItem);
            if (nGetExp < 1) then Exit;
            end else begin
            nSoulExp := PINT64(@UserItem.btItemExt)^;
            nNewSoulExp := nGetExp + nSoulExp;
            if nNewSoulExp >= nSoulMaxExp then begin
                PINT64(@UserItem.btItemExt)^ := nSoulExp;
            end else begin
                PINT64(@UserItem.btItemExt)^ := PINT64(@UserItem.btItemExt)^ + nGetExp;
            end;
            SendUpdateItem(UserItem);
            end;
          end;
      end;
      end
    end;
end;

boLevelUp := False;

//检查是否达到最高等级
boReachMaxLevel := False;
if g_Config.boHighLevelLimitExp then begin
    if m_btAmbitKind in then begin                                                         //上仙 以是最高级
      if (m_btAmbitLevel >= g_Config.nHighAmbitLevelLimit3) then begin
      boReachMaxLevel := True;
      end;
    end;
end else begin
    if (m_Abil.level >= g_Config.nLimitLevel) then begin
      boReachMaxLevel := True;
    end;
end;
boReachLevelLimitExp := (boReachMaxLevel) and (m_Abil.Exp >= m_Abil.MaxExp);

m_sScriptParam := UInt64ToStr(nGetExp);
m_sScriptParam := BoolToIntStr(bScritpExp);
m_sScriptParam := BoolToIntStr(boReachLevelLimitExp);
ExecuteScript(g_ManageNPC, '@GetExpFucn');
if UInt64ToStr(nGetExp) <> m_sScriptParam then nGetExp := Str_ToInt(m_sScriptParam, 0);

if (not m_boPneuma) then begin
    SendUpdateDelayMsg(Self, RM_REFRESHRANK, 0, 0, 0, 0, '', 200);
end else begin
    SendUpdateDelayMsg(Self, RM_REFRESHRANK, 0, 1, 0, 0, '', 200);
end;

//龙纹钢吸取经验
if (not m_boPneuma) and (nGetExp > 0) then begin
    if boReachLevelLimitExp then
      nGetExp := nGetExp * 2;

    if (m_nGatherExp + nGetExp) > MAX_ULONG64 then
      nInt := MAX_ULONG64 - m_nGatherExp
    else
      nInt := nGetExp;
    Inc(m_nGatherExp, nInt);
end;

if boReachLevelLimitExp then nGetExp := 1;

if (not bScritpExp) and m_PEnvir.m_MapFlag.boLayupExp then begin
    n14 := m_PEnvir.m_MapFlag.nLayupExp;
    if (n14 >= 300) and (n14 <= 399) then begin
      Dec(n14, 300);
      if (m_nMval + nGetExp) > MAX_ULONG64 then
      nInt := MAX_ULONG64 - m_nMval
      else
      nInt := nGetExp;
      m_nMval := m_nMval + nInt;
    end;
end else begin
    Inc(m_Abil.Exp, nGetExp);

    if not boReachMaxLevel then begin
      boRecalc := False;
      if m_Abil.Exp >= m_Abil.MaxExp then begin
      Dec(m_Abil.Exp, m_Abil.MaxExp);
      if g_Config.boHighLevelLimitExp then begin
          //升级增加天人重数
          if m_btAmbitKind > 2 then begin
            boRecalc := True;
            boLevelUp := True;
            case m_btAmbitKind of
            3, 4: begin                                                                           //天人
                  if (m_btAmbitLevel < g_Config.nHighAmbitLevelLimit1) then begin
                  Inc(m_btAmbitLevel);
                  end else if g_Config.boAutoUpAmbitKind2 then begin
                  Inc(m_btAmbitKind, 2);
                  m_btAmbitLevel := 1;
                  end;
                end;
            5, 6: begin                                                                           //天仙
                  if (m_btAmbitLevel < g_Config.nHighAmbitLevelLimit2) then begin
                  Inc(m_btAmbitLevel);
                  end else if g_Config.boAutoUpAmbitKind3 then begin
                  Inc(m_btAmbitKind, 2);
                  m_btAmbitLevel := 1;
                  end;
                end;
            7, 8: begin                                                                           //上仙
                  if (m_btAmbitLevel < g_Config.nHighAmbitLevelLimit3) then begin
                  Inc(m_btAmbitLevel);
                  end else begin
                  boLevelUp := False;
                  end;
                end;
            end;
          end;
          //等级同时提升
          if m_Abil.level < g_Config.nLimitLevel then begin
            Inc(m_Abil.level);
            boLevelUp := True;
          end;

          if g_Config.boAutoUpAmbitKind1 and (m_Abil.level >= g_Config.nAutoUpAmbitLevel) and (m_btAmbitKind < 3) then begin
            if Random(10) < 5 then m_btAmbitKind := 3 else m_btAmbitKind := 4;
            m_btAmbitLevel := (m_Abil.level - g_Config.nAutoUpAmbitLevel) + 1;
            boRecalc := True;
            boLevelUp := True;
          end;
      end else begin
          if m_Abil.level < MAXUPLEVEL then begin
            Inc(m_Abil.level);
            boLevelUp := True;
          end;
      end;

      if boLevelUp then begin
          HasLevelUp(m_Abil.level - 1);
          AddBodyLuck(100);
          IncHealthSpell(2000, 2000);
          m_WAbil.wElementForce := m_WAbil.wElementForceMax;
          AddGameDataLog('12' + #9 +
            m_sMapName + #9 +
            IntToStr(m_Abil.level) + #9 +
            IntToStr(m_Abil.Exp) + #9 +
            m_sCharName + #9 +
            '0' + #9 +
            '0' + #9 +
            '1' + #9 +
            '0');
      //m_BattleVal.nMinVal := m_Abil.Level;
          m_BattleVal.BattleVal := m_BattleVal.nMinVal + m_BattleVal.nMinVal +
            m_BattleVal.nMinVal + m_BattleVal.nMinVal + m_BattleVal.nMinVal;
          SendDefMessage(SM_BATTLEVAL, Integer(Self), m_BattleVal.BattleVal, 0, 0,
            EnCodeBuffer(@m_BattleVal, SizeOf(TBattleData)), True);

          nCode := 0;
          nType := 0;
          if not g_Config.boClassicServer then begin                                                //修为系统

            if g_Config.boClientRedPacket then
            nCode := nCode + 32;
            if g_Config.boClientPreferential then
            nType := 8;
            if g_Config.boClientBackUserExp then
            nType := nType + 1;
            SendDefMessage(SM_816, nType, 0, MakeWord(15, nCode), 0, '');
          end else begin
            SendDefMessage(SM_816, 0, 1, 15, 0, '');
          end;

          if (m_PEnvir.m_MapFlag.sLevelUpGotoLabel <> '') then
            ExecuteScript(g_ManageNPC, m_PEnvir.m_MapFlag.sLevelUpGotoLabel);
          ExecuteScript(g_FunctionNPC, '@升级触发');
      end;
      if boRecalc then begin
          SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
          FeatureChanged;
      end;
      end;
    end;

    //向客户端发送经验
    RefExpPacket.nExp := m_Abil.Exp;
    RefExpPacket.nInc := nGetExp;
    AddBodyLuck(nGetExp * 0.002);
    SendMsg(Self, RM_WINEXP, 0, nGetExp, 0, 0, EnCodeBuffer(@RefExpPacket, SizeOf(TRefExpPacket)));
end;
end;

function TPlayObject.GetHitMsgCount: Integer;
var
i                                     : Integer;
SendMessage                           : pTSendMessage;
begin
Result := 0;
try
    EnterCriticalSection(ProcessMsgCriticalSection);
    for i := 0 to m_MsgList.Count - 1 do begin
      SendMessage := m_MsgList.Items;
      if (SendMessage.wIdent = CM_HIT) or
      (SendMessage.wIdent = CM_HEAVYHIT) or
      (SendMessage.wIdent = CM_BIGHIT) or
      (SendMessage.wIdent = CM_POWERHIT) or
      (SendMessage.wIdent = CM_LONGHIT) or
      (SendMessage.wIdent = CM_WIDEHIT) or
      (SendMessage.wIdent = CM_FIREHIT) then begin
      Inc(Result);
      end;
    end;
finally
    LeaveCriticalSection(ProcessMsgCriticalSection);
end;
end;

function TPlayObject.GetMyInfo: string;
var
sMyInfo                               : string;
begin
sMyInfo := g_sMyInfo;
sMyInfo := AnsiReplaceText(sMyInfo, '%name', m_sCharName);
sMyInfo := AnsiReplaceText(sMyInfo, '%map', m_PEnvir.m_sMapDesc);
sMyInfo := AnsiReplaceText(sMyInfo, '%x', IntToStr(m_nCurrX));
sMyInfo := AnsiReplaceText(sMyInfo, '%y', IntToStr(m_nCurrY));
sMyInfo := AnsiReplaceText(sMyInfo, '%level', IntToStr(m_Abil.level));
sMyInfo := AnsiReplaceText(sMyInfo, '%gold', IntToStr(m_nGold));
sMyInfo := AnsiReplaceText(sMyInfo, '%pk', IntToStr(m_nPkPoint));
sMyInfo := AnsiReplaceText(sMyInfo, '%minhp', IntToStr(m_WAbil.dwHP));
sMyInfo := AnsiReplaceText(sMyInfo, '%maxhp', IntToStr(m_WAbil.dwMaxHP));
sMyInfo := AnsiReplaceText(sMyInfo, '%minmp', IntToStr(m_WAbil.dwMP));
sMyInfo := AnsiReplaceText(sMyInfo, '%maxmp', IntToStr(m_WAbil.dwMaxMP));
sMyInfo := AnsiReplaceText(sMyInfo, '%mindc', IntToStr(loword(m_WAbil.DC)));
sMyInfo := AnsiReplaceText(sMyInfo, '%maxdc', IntToStr(hiword(m_WAbil.DC)));
sMyInfo := AnsiReplaceText(sMyInfo, '%minmc', IntToStr(loword(m_WAbil.MC)));
sMyInfo := AnsiReplaceText(sMyInfo, '%maxmc', IntToStr(hiword(m_WAbil.MC)));
sMyInfo := AnsiReplaceText(sMyInfo, '%minsc', IntToStr(loword(m_WAbil.SC)));
sMyInfo := AnsiReplaceText(sMyInfo, '%maxsc', IntToStr(hiword(m_WAbil.SC)));
sMyInfo := AnsiReplaceText(sMyInfo, '%logontime',
    DateToChStr(m_dLogonTime, True));
sMyInfo := AnsiReplaceText(sMyInfo, '%logonlong', IntToStr((GetTickCount -
    m_dwLogonTick) div 60000));
Result := sMyInfo;
end;

function TPlayObject.GetMyStatus: Integer;                                                          //708
begin
Result := m_nHungerStatus div 1000;                                                               //饥饿点
if Result > 4 then Result := 4;
end;

//获得当前人物所在地图位置的玩家数

function TPlayObject.GetRangeHumanCount: Integer;
begin
Result := UserEngine.GetMapOfRangeHumanCount(m_PEnvir, m_nCurrX, m_nCurrY, 10);
end;

function TPlayObject.GetRunMsgCount: Integer;
var
i                                     : Integer;
SendMessage                           : pTSendMessage;
begin
Result := 0;
try
    EnterCriticalSection(ProcessMsgCriticalSection);
    for i := 0 to m_MsgList.Count - 1 do begin
      SendMessage := m_MsgList.Items;
      if (SendMessage.wIdent = CM_RUN) then begin
      Inc(Result);
      end;
    end;
finally
    LeaveCriticalSection(ProcessMsgCriticalSection);
end;
end;

//取得当前脚本可以跳转的标签

procedure TPlayObject.GetScriptLabel(sMsg: string; boLeft: Boolean);
var
sText                                 : string;
sData                                 : string;
sCmdStr, sLabel                     : string;
i                                     : Integer;
begin
if boLeft then
    m_CanJmpScriptLableList2.Clear
else
    m_CanJmpScriptLableList.Clear;
while (True) do begin
    if sMsg = '' then Break;
    sMsg := GetValidStr3(sMsg, sText, ['\']);
    if sText <> '' then begin
      sData := '';
      while (sText <> '') and (Pos('<', sText) > 0) and (Pos('>', sText) > 0) do begin            //0419
      if sText <> '<' then begin
          sText := '<' + GetValidStr3(sText, sData, ['<']);
      end;
      sText := ArrestStringEx(sText, '<', '>', sCmdStr);
      if (sCmdStr <> '') and (TagCount(sCmdStr, '/') >= 1) then begin
          //sLabel := GetValidStr3(sCmdStr, sCmdStr, ['/']);
          i := 1;
          GetToken(sCmdStr, '/', i);
          sLabel := GetToken(sCmdStr, '/', i);
          if sLabel <> '' then begin
            if boLeft then
            m_CanJmpScriptLableList2.Add(sLabel)
            else
            m_CanJmpScriptLableList.Add(sLabel);
          end;
      end;
      end;
    end;
end;
end;

function TPlayObject.GetShowName: string;
var
i                                     : Integer;
sShowName                           : string;
sCharName                           : string;
sGuildName                            : string;
sDearName                           : string;
sMasterName                           : string;
Castle                              : TUserCastle;
resourcestring
sExceptionMsg                         = ' TPlayObject::GetShowName';
sIsYS                                 = '的元神)';
begin
try
    sCharName := '';
    sGuildName := '';
    sDearName := '';
    sMasterName := '';
    if m_MyGuild <> nil then begin
      Castle := g_CastleManager.IsCastleMember(Self);
      if (m_wPersonalCode and 4 = 0) then begin
      if (Castle <> nil) then begin
          sGuildName := AnsiReplaceText(g_sCastleGuildName, '%castlename', Castle.m_sName);
          sGuildName := AnsiReplaceText(sGuildName, '%guildname', TGuild(m_MyGuild).sGuildName);
          sGuildName := AnsiReplaceText(sGuildName, '%rankname', m_sGuildRankName);
      end else begin
          Castle := g_CastleManager.InCastleWarArea(Self);
          if g_Config.boShowGuildName or (((Castle <> nil) and Castle.m_boUnderWar) or m_boInFreePKArea) then begin
            sGuildName := AnsiReplaceText(g_sNoCastleGuildName, '%guildname', TGuild(m_MyGuild).sGuildName);
            sGuildName := AnsiReplaceText(sGuildName, '%rankname', m_sGuildRankName);
          end;
      end;
      end;
    end;

    if not g_Config.boShowRankLevelName then begin
      if m_btReLevel > 0 then begin
      case m_btJob of
          0: sCharName := AnsiReplaceText(g_sWarrReNewName, '%chrname', m_sCharName);
          1: sCharName := AnsiReplaceText(g_sWizardReNewName, '%chrname', m_sCharName);
          2: sCharName := AnsiReplaceText(g_sTaosReNewName, '%chrname', m_sCharName);
          3: sCharName := AnsiReplaceText(g_sGoblinReNewName, '%chrname', m_sCharName);
      end;
      end else begin
      sCharName := m_sCharName;
      end;
    end else begin
      sCharName := Format(m_sRankLevelName, );
    end;

{$IF COUNTRYSYSTEM = 1}
    if not m_boPneuma and (m_btCountry > 0) and (m_sOffName <> '') then begin                     //官职名称,元神不给予官职
      if GetCountryInfo(m_btCountry).sKing = m_sCharName then
      sCharName := sCharName + '\[' + GetCountryInfo(m_btCountry).sName + '-国王]'
      else
      sCharName := sCharName + '\[' + GetCountryInfo(m_btCountry).sName + '-' + m_sOffName + ']';
    end;
{$IFEND}

    if m_boMaster and g_Config.boShowPrenticeName then begin
      for i := 1 to 3 do begin
      if m_sMasterName <> '' then begin
          sMasterName := sMasterName + '\' + Format(g_sMasterName, ]);
          Break;
      end;
      end;
    end else if (m_sMasterName <> '') and (g_Config.boShowMasterName) then begin
      sMasterName := Format(g_sNoMasterName, ]);
    end;

    if (m_wPersonalCode and 1 = 0) then begin
      if m_sDearName <> '' then begin
      if m_btGender = 0 then begin
          sDearName := Format(g_sManDearName, );
      end else begin
          sDearName := Format(g_sWoManDearName, );
      end;
      end;
    end;

    sShowName := AnsiReplaceText(g_sHumanShowName, '%chrname', sCharName);

    if (g_Config.boShowPrenticeName and m_boMaster) or (g_Config.boShowMasterName and not m_boMaster) then
      sShowName := AnsiReplaceText(sShowName, '%mastername', sMasterName + '\')
    else
      sShowName := AnsiReplaceText(sShowName, '%mastername', '');

    if (sGuildName <> '') and (not m_boPneuma) then
      sShowName := AnsiReplaceText(sShowName, '%guildname\', sGuildName + '\')
    else
      sShowName := AnsiReplaceText(sShowName, '%guildname\', '');

    if sDearName <> '' then
      sShowName := AnsiReplaceText(sShowName, '%dearname\', sDearName + '\')
    else
      sShowName := AnsiReplaceText(sShowName, '%dearname\', '');
    {
   if m_wAttachePoint > 100 then
       sShowName := sShowName + '[' + m_sAttacheName + ']';
   }
    if m_boPneuma and (m_PneumaObject <> nil) then begin
      sShowName := sShowName + '\(' + m_PneumaObject.m_sCharName + sIsYS
    end;

    if (m_wPersonalCode and 32 = 0) then begin
      if Length(m_sTmpRank) > 0 then sShowName := sShowName + '\' + m_sTmpRank;
    end;

    //关灯模式
    if (m_PEnvir.m_MapFlag.boSECRET and ((m_PEnvir.m_MapFlag.btSECRETRule and SECRET_RULE_UNITENAME) <> 0)) then
    begin
      sShowName := g_ManageNPC.GetLineVariableText(self, m_PEnvir.m_MapFlag.sSECRETCHRNAME);
    end;

    //神秘人
    if m_boSecretMode and (m_sSecretName <> '') then begin
      sShowName := m_sSecretName;
    end;
    Result := sShowName;
except
    on E: Exception do begin
      MainOutMessage(sExceptionMsg);
    end;
end;
end;

function TPlayObject.GetSiteDownMsgCount: Integer;
var
i                                     : Integer;
SendMessage                           : pTSendMessage;
begin
Result := 0;
EnterCriticalSection(ProcessMsgCriticalSection);
try
    for i := 0 to m_MsgList.Count - 1 do begin
      SendMessage := m_MsgList.Items;
      if (SendMessage.wIdent = CM_SITDOWN) then begin
      Inc(Result);
      end;
    end;
finally
    LeaveCriticalSection(ProcessMsgCriticalSection);
end;
end;

function TPlayObject.GetSpellMsgCount: Integer;
var
i                                     : Integer;
SendMessage                           : pTSendMessage;
begin
Result := 0;
try
    EnterCriticalSection(ProcessMsgCriticalSection);
    for i := 0 to m_MsgList.Count - 1 do begin
      SendMessage := m_MsgList.Items;
      if (SendMessage.wIdent = CM_SPELL) then begin
      Inc(Result);
      end;
    end;
finally
    LeaveCriticalSection(ProcessMsgCriticalSection);
end;
end;

//获得出生点

procedure TPlayObject.GetStartPoint;
var
i                                     : Integer;
SP                                    : pTStartPointInfo;
begin
if m_boPneuma and (m_PneumaObject <> nil) then begin
    m_sHomeMap := m_PneumaObject.m_sHomeMap;
    m_nHomeX := TPlayObject(m_PneumaObject).m_nHomeX;
    m_nHomeY := TPlayObject(m_PneumaObject).m_nHomeY;
    Exit;
end;
if PKLevel >= 2 then begin
    m_sHomeMap := g_Config.sRedHomeMap;                                                             //红名地图
    m_nHomeX := g_Config.nRedHomeX;
    m_nHomeY := g_Config.nRedHomeY;
end else begin
    for i := 0 to m_CurSafeZoneList.Count - 1 do begin
      SP := m_CurSafeZoneList;
      if (SP.Envir = m_PEnvir) and (abs(m_nCurrX - SP.X) < 50) and (abs(m_nCurrY - SP.Y) < 50) then begin
      m_sHomeMap := SP.sMapName;
      m_nHomeX := SP.X;
      m_nHomeY := SP.Y;
      Break;
      end;
    end;
end;
end;

function TPlayObject.GetColorTaskCount(): Integer;
var
i                                     : Integer;
pTask                                 : PTTask;
wColor                              : word;
begin
Result := 0;
for i := 0 to m_TaskList.Count - 1 do begin
    pTask := PTTask(m_TaskList);
    wColor := HiWord(pTask^.Step);
    if (HiByte(wColor) = 2) then Inc(Result);
end;
end;

function TPlayObject.GetTaskStep(const TaskID: Integer): Integer;
var
i                                     : Integer;
pTask                                 : PTTask;
begin
Result := 0;
for i := 0 to m_TaskList.Count - 1 do begin
    pTask := PTTask(m_TaskList);
    if pTask^.TaskID = TaskID then begin
      Result := LoWord(pTask^.Step);
      Break;
    end;
end;
end;

function TPlayObject.GetTaskStr(const TaskID: Integer; ValID: Integer): string;
var
i                                     : Integer;
pTask                                 : PTTask;
begin
Result := '';
if (ValID < 0) or (ValID >= MAX_TASK_S_VAL_COUNT) then Exit;
for i := 0 to m_TaskList.Count - 1 do begin
    pTask := PTTask(m_TaskList);
    if pTask^.TaskID = TaskID then begin
      Result := pTask^.sVal;
      Break;
    end;
end;
end;

function TPlayObject.GetTaskVal(const TaskID: Integer; ValID: Integer): Integer;
var
i                                     : Integer;
pTask                                 : PTTask;
begin
Result := -1;
if (ValID < 0) or (ValID >= MAX_TASK_I_VAL_COUNT) then Exit;
for i := 0 to m_TaskList.Count - 1 do begin
    pTask := PTTask(m_TaskList);
    if pTask^.TaskID = TaskID then begin
      Result := pTask^.nVal;
      Break;
    end;
end;
end;

{获取宝箱转盘物品??}

procedure TPlayObject.GetTreasureBoxItem(wParam: word; nParam1, nParam2,
nParam3: Integer; sMsg: string);
var
i, n                                  : Integer;
BlessItems                            : TBlessTreeItem;
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
begin
m_nRandomGiveStep := nParam2;
case nParam2 of
    {自动开宝箱关闭}
    7: begin
      m_nRandomGiveStep := 0;
      m_nAutoOpenTreasureBox := MakeWord(0, HiByte(m_nAutoOpenTreasureBox));
      Exit;
      end;
    {打开祈愿树}
    12: begin
      m_BLESSNPC := m_ClickNPC;
      end;
    {放上祈愿符}
    268: begin
      m_sScriptParam := '0';
      DeCodeBuffer(sMsg, @n, SizeOf(Integer));
      m_sScriptParam := IntToStr(MakeLong(nParam3, wParam));
      m_sScriptParam := IntToStr(n);
      if m_BLESSNPC <> nil then
          TNormNpc(m_BLESSNPC).GotoLable(Self, '@StartBless', False);
      end;
    {开始祈愿}
    524: begin
      GetUserItemByMakeIndex(MakeLong(nParam3, wParam), UserItem);
      if UserItem <> nil then begin
          StdItem := UserEngine.GetStdItem(UserItem.wIndex);
          if StdItem <> nil then begin
            BlessItems.Name := StdItem.FilterName;
            BlessItems.Looks := StdItem.Looks;

            m_defMsg := MakeDefaultMsg(SM_627, Integer(Self), 1036, 1, 0);
            SendSocket(@m_defMsg, EnCodeBuffer(@BlessItems, SizeOf(TBlessTreeItem)));
          end;
      end;

      DeCodeBuffer(sMsg, @n, SizeOf(Integer));
      m_sScriptParam := '1';
      m_sScriptParam := IntToStr(MakeLong(nParam3, wParam));
      m_sScriptParam := IntToStr(n);
      if m_BLESSNPC <> nil then
          TNormNpc(m_BLESSNPC).GotoLable(Self, '@StartBless', False);
      end;
    {自动开宝箱开启}
    263: begin
      m_nAutoOpenTreasureBox := MakeWord(1, HiByte(m_nAutoOpenTreasureBox));
      Exit;
      end;
    {显示物品}
    264, 520, 776, 1032: begin
      if m_sNextLabel <> '' then begin
          m_sScriptParam := IntToStr(nParam2 div 256);
          m_sScriptParam := '0';
          if m_SMELTNPC <> nil then
            TNormNpc(m_SMELTNPC).GotoLable(Self, m_sNextLabel, False);
      end;
      end;
    {自动开启宝箱}
    265, 521, 777, 1033: begin
      if m_SMELTNPC <> nil then begin
          m_sScriptParam := IntToStr(HiByte(m_nAutoOpenTreasureBox)
            {宝箱类型});
          TNormNpc(m_SMELTNPC).GotoLable(Self, '@OpenBox', False);
      end;
      SendDefMessage(627, Integer(Self), nParam2 + 252, 4, 0, '');
      Exit;
      end;
    {获取物品}
    266, 522, 778, 1034: begin
      m_sScriptParam := IntToStr(nParam2 div 256);
      m_sScriptParam := '1';
      if m_sNextLabel <> '' then begin
          if m_SMELTNPC <> nil then
            TNormNpc(m_SMELTNPC).GotoLable(Self, m_sNextLabel, False);
      end;
      end;
    {关闭宝箱,重新洗牌}
    267, 523, 779, 1035: begin
      for i := 0 to 10 do m_sScriptParam := '0';
      m_sNextLabel := '';
      m_SMELTNPC := nil;
      m_nAutoOpenTreasureBox := $00;
      SendDefMessage(627, Integer(Self), 0, 0, 0, '');
      end;
end;
end;

function TPlayObject.GetTurnMsgCount: Integer;
var
i                                     : Integer;
SendMessage                           : pTSendMessage;
begin
Result := 0;
try
    EnterCriticalSection(ProcessMsgCriticalSection);
    for i := 0 to m_MsgList.Count - 1 do begin
      SendMessage := m_MsgList.Items;
      if (SendMessage.wIdent = CM_TURN) then begin
      Inc(Result);
      end;
    end;
finally
    LeaveCriticalSection(ProcessMsgCriticalSection);
end;
end;

function TPlayObject.GetWalkMsgCount: Integer;
var
i                                     : Integer;
SendMessage                           : pTSendMessage;
begin
Result := 0;
try
    EnterCriticalSection(ProcessMsgCriticalSection);
    for i := 0 to m_MsgList.Count - 1 do begin
      SendMessage := m_MsgList.Items;
      if (SendMessage.wIdent = CM_WALK) then begin
      Inc(Result);
      end;
    end;
finally
    LeaveCriticalSection(ProcessMsgCriticalSection);
end;
end;

procedure TPlayObject.GoldChange(sChrName: string; nGold: Integer);
resourcestring
sMsg                                  = '% 的金币%d 金币%s';
var
s10, s14                              : string;
begin
if nGold > 0 then begin
    s10 := '14';
    s14 := '增加完成';
end else begin
    s10 := '13';
    s14 := '以删减';
end;
SysMsg(Format(sMsg, ), c_Green, t_Hint);

if g_boGameLogGold then
    AddGameDataLog(s10 + #9 +
      m_sMapName + #9 +
      IntToStr(m_nCurrX) + #9 +
      IntToStr(m_nCurrY) + #9 +
      m_sCharName + #9 +
      sSTRING_GOLDNAME + #9 +
      IntToStr(nGold) + #9 +
      '1' + #9 +
      sChrName);
end;

function TPlayObject.HorseRunTo(btDir: byte; boFlag: Boolean): Boolean;
const
nRunStep                              = 3;
var
nOldX, nOldY                        : Integer;
btRideFightSpeed                      : byte;
boHumanRun                            : Boolean;
resourcestring
sExceptionMsg                         = ' TPlayObject::HorseRunTo';
begin
Result := False;
if (m_btGodRunTime > 0) then begin
    btRideFightSpeed := 3;
end else if m_boPneuma and (m_PneumaObject <> nil) then begin
    btRideFightSpeed := TPlayObject(m_PneumaObject).m_PetInfo.btRideFightSpeed;
end else begin
    btRideFightSpeed := m_PetInfo.btRideFightSpeed;
end;
if m_boRideOn and m_boRideFightOn and (btRideFightSpeed = 0) then Exit;

boHumanRun := g_Config.boDiableHumanRun or ((m_btPermissionGM > 9) and g_Config.boGMRunAll) or (g_Config.boSafeZoneRunAll and InSafeZone);
try
    nOldX := m_nCurrX;
    nOldY := m_nCurrY;
    m_btDirection := btDir;
    case btDir of
      DR_UP {0}: begin
          if m_boFlyer or (m_nCurrY > 2) and
            (m_PEnvir.CanWalkEx(m_nCurrX, m_nCurrY - 1, boHumanRun {True})) and
            (m_PEnvir.CanWalkEx(m_nCurrX, m_nCurrY - 2, boHumanRun {True})) and
            (m_PEnvir.CanWalkEx(m_nCurrX, m_nCurrY - 3, boHumanRun {True})) and
            (m_PEnvir.MoveToMovingObject(m_nCurrX, m_nCurrY, Self, m_nCurrX, m_nCurrY - 3, True) > 0) then begin

            Dec(m_nCurrY, nRunStep);
          end;
      end;
      DR_UPRIGHT {1}: begin
          if m_boFlyer or (m_nCurrX < m_PEnvir.m_nWidth - 3) and
            (m_nCurrY > 2) and
            (m_PEnvir.CanWalkEx(m_nCurrX + 1, m_nCurrY - 1, boHumanRun {True})) and
            (m_PEnvir.CanWalkEx(m_nCurrX + 2, m_nCurrY - 2, boHumanRun {True})) and
            (m_PEnvir.CanWalkEx(m_nCurrX + 3, m_nCurrY - 3, boHumanRun {True})) and
            (m_PEnvir.MoveToMovingObject(m_nCurrX, m_nCurrY, Self, m_nCurrX + 3, m_nCurrY - 3, True) > 0) then begin

            Inc(m_nCurrX, nRunStep);
            Dec(m_nCurrY, nRunStep);
          end;
      end;
      DR_RIGHT {2}: begin
          if m_boFlyer or (m_nCurrX < m_PEnvir.m_nWidth - 3) and
            (m_PEnvir.CanWalkEx(m_nCurrX + 1, m_nCurrY, boHumanRun {True})) and
            (m_PEnvir.CanWalkEx(m_nCurrX + 2, m_nCurrY, boHumanRun {True})) and
            (m_PEnvir.CanWalkEx(m_nCurrX + 3, m_nCurrY, boHumanRun {True})) and
            (m_PEnvir.MoveToMovingObject(m_nCurrX, m_nCurrY, Self, m_nCurrX + 3, m_nCurrY, True) > 0) then begin

            Inc(m_nCurrX, nRunStep);
          end;
      end;
      DR_DOWNRIGHT {3}: begin
          if m_boFlyer or (m_nCurrX < m_PEnvir.m_nWidth - 3) and
            (m_nCurrY < m_PEnvir.m_nHeight - 3) and
            (m_PEnvir.CanWalkEx(m_nCurrX + 1, m_nCurrY + 1, boHumanRun {True})) and
            (m_PEnvir.CanWalkEx(m_nCurrX + 2, m_nCurrY + 2, boHumanRun {True})) and
            (m_PEnvir.CanWalkEx(m_nCurrX + 3, m_nCurrY + 3, boHumanRun {True})) and
            (m_PEnvir.MoveToMovingObject(m_nCurrX, m_nCurrY, Self, m_nCurrX + 3, m_nCurrY + 3, True) > 0) then begin

            Inc(m_nCurrX, nRunStep);
            Inc(m_nCurrY, nRunStep);
          end;
      end;
      DR_DOWN {4}: begin
          if m_boFlyer or (m_nCurrY < m_PEnvir.m_nHeight - 3) and
            (m_PEnvir.CanWalkEx(m_nCurrX, m_nCurrY + 1, boHumanRun {True})) and
            (m_PEnvir.CanWalkEx(m_nCurrX, m_nCurrY + 2, boHumanRun {True})) and
            (m_PEnvir.CanWalkEx(m_nCurrX, m_nCurrY + 3, boHumanRun {True})) and
            (m_PEnvir.MoveToMovingObject(m_nCurrX, m_nCurrY, Self, m_nCurrX, m_nCurrY + 3, True) > 0) then begin

            Inc(m_nCurrY, nRunStep);
          end;
      end;
      DR_DOWNLEFT {5}: begin
          if m_boFlyer or (m_nCurrX > 2) and
            (m_nCurrY < m_PEnvir.m_nHeight - 3) and
            (m_PEnvir.CanWalkEx(m_nCurrX - 1, m_nCurrY + 1, boHumanRun {True})) and
            (m_PEnvir.CanWalkEx(m_nCurrX - 2, m_nCurrY + 2, boHumanRun {True})) and
            (m_PEnvir.CanWalkEx(m_nCurrX - 3, m_nCurrY + 3, boHumanRun {True})) and
            (m_PEnvir.MoveToMovingObject(m_nCurrX, m_nCurrY, Self, m_nCurrX - 3, m_nCurrY + 3, True) > 0) then begin

            Dec(m_nCurrX, nRunStep);
            Inc(m_nCurrY, nRunStep);
          end;
      end;
      DR_LEFT {6}: begin
          if m_boFlyer or (m_nCurrX > 2) and
            (m_PEnvir.CanWalkEx(m_nCurrX - 1, m_nCurrY, boHumanRun {True})) and
            (m_PEnvir.CanWalkEx(m_nCurrX - 2, m_nCurrY, boHumanRun {True})) and
            (m_PEnvir.CanWalkEx(m_nCurrX - 3, m_nCurrY, boHumanRun {True})) and
            (m_PEnvir.MoveToMovingObject(m_nCurrX, m_nCurrY, Self, m_nCurrX - 3, m_nCurrY, True) > 0) then begin

            Dec(m_nCurrX, nRunStep);
          end;
      end;
      DR_UPLEFT {7}: begin
          if m_boFlyer or (m_nCurrX > 2) and
            (m_nCurrY > 2) and
            (m_PEnvir.CanWalkEx(m_nCurrX - 1, m_nCurrY - 1, boHumanRun {True})) and
            (m_PEnvir.CanWalkEx(m_nCurrX - 2, m_nCurrY - 2, boHumanRun {True})) and
            (m_PEnvir.CanWalkEx(m_nCurrX - 3, m_nCurrY - 3, boHumanRun {True})) and
            (m_PEnvir.MoveToMovingObject(m_nCurrX, m_nCurrY, Self, m_nCurrX - 3, m_nCurrY - 3, True) > 0) then begin

            Dec(m_nCurrX, nRunStep);
            Dec(m_nCurrY, nRunStep);
          end;
      end;
    end;
    if (m_nCurrX <> nOldX) or (m_nCurrY <> nOldY) then begin
      if Walk(RM_RUN) then Result := True
      else begin
      if m_boFlyer or (m_PEnvir.MoveToMovingObject(nOldX, nOldY, Self, m_nCurrX, m_nCurrY, True) > 0) then begin
          m_nCurrX := nOldX;
          m_nCurrY := nOldY;
      end;
      end;
    end;
except
    MainOutMessage(sExceptionMsg);
end;
end;

//指定玩家是否在被阻止私聊列表中

function TPlayObject.IsBlockWhisper(sName: string): Boolean;
var
i                                     : Integer;
begin
Result := False;
for i := 0 to m_BlockWhisperList.Count - 1 do begin
    if CompareText(sName, m_BlockWhisperList.Strings) = 0 then begin
      Result := True;
      Break;
    end;
end;
end;

function TPlayObject.IsGotoLabel(sMapName: string; nX, nY, nRange,
nQuestFalgStatus: Integer;
boQuestFalgStatus: Boolean; sItemName1, sItemName2: string; boNeedGroup:
Boolean; nRandomCount: Integer): Boolean;
var
n01                                 : Integer;
nMaxCurrX, nMaxCurrY, nMinCurrX, nMinCurrY: Integer;

function GetAllowItem: Boolean;
begin
    Result := False;
    if sItemName1 = '*' then begin
      Result := True;
    end else
      if CompareText(sItemName1, sItemName2) = 0 then begin
      Result := True;
      end;
end;

function GetRandomCount: Boolean;
begin
    Result := False;
    if nRandomCount = 0 then Result := True
    else
      if (nRandomCount > 0) and (Random(nRandomCount div 2 + nRandomCount) =
      nRandomCount) then Result := True;
end;

function GetGroup: Boolean;
begin
    Result := False;
    if not boNeedGroup then Result := True
    else
      if m_GroupOwner <> nil then Result := True;
end;
begin
Result := False;
nMaxCurrX := nX + nRange;
nMaxCurrY := nY + nRange;
nMinCurrX := nX - nRange;
nMinCurrY := nY - nRange;
if (CompareText(sMapName, m_sMapName) = 0) and (((m_nCurrX <= nMaxCurrX) and
    (m_nCurrX >= nMinCurrX) and (m_nCurrY <= nMaxCurrY) and (m_nCurrY >=
    nMinCurrY)) or (nRange = -1)) then begin
    if nQuestFalgStatus > 0 then begin
      n01 := GetQuestFalgStatus(nQuestFalgStatus);
      if (n01 = 0) and (not boQuestFalgStatus) then begin
      if GetAllowItem and GetGroup and GetRandomCount then begin
          Result := True;
      end;
      end else
      if (n01 <> 0) and (boQuestFalgStatus) then begin
          if GetAllowItem and GetGroup and GetRandomCount then begin
            Result := True;
          end;
      end;
    end else begin
      if GetAllowItem and GetGroup and GetRandomCount then begin
      Result := True;
      end;
    end;
end;
end;

procedure TPlayObject.JoinGroup(PlayObject: TPlayObject);
begin
m_GroupOwner := PlayObject;
SendGroupText(Format(g_sJoinGroup, ));
end;

function TPlayObject.LableIsCanJmp(sLabel: string; boLeft: Boolean): Boolean;
var
i                                     : Integer;
begin
Result := False;
if CompareText(sLabel, '@main') = 0 then begin
    Result := True;
    Exit;
end;
if CompareText(sLabel, '@mainleft') = 0 then begin
    Result := True;
    Exit;
end;
if CompareText(sLabel, '@exit') = 0 then begin
    Result := True;
    Exit;
end;
if boLeft then begin
    for i := 0 to m_CanJmpScriptLableList2.Count - 1 do begin
      if CompareText(sLabel, m_CanJmpScriptLableList2.Strings) = 0 then begin
      Result := True;
      Break;
      end;
    end;
end;
for i := 0 to m_CanJmpScriptLableList.Count - 1 do begin
    if CompareText(sLabel, m_CanJmpScriptLableList.Strings) = 0 then begin
      Result := True;
      Break;
    end;
end;
if CompareText(sLabel, m_sPlayDiceLabel) = 0 then begin
    m_sPlayDiceLabel := '';
    Result := True;
    Exit;
end;
end;

//登陆时间记费

procedure TPlayObject.LogonTimcCost();                                                            //004CA994
var
n08                                 : Integer;
SC                                    : string;
begin
if (m_nPayMent = 2) or (g_Config.boTestServer) then begin
    n08 := (GetTickCount - m_dwLogonTick) div 1000;
end else n08 := 0;
SC := m_sIPaddr + #9 + m_sUserID + #9 + m_sCharName + #9 + IntToStr(n08) + #9
    + FormatDateTime('yyyy-mm-dd hh:mm:ss', m_dLogonTime) + #9 +
    FormatDateTime('yyyy-mm-dd hh:mm:ss', Now) + #9 + IntToStr(m_nPayMode);
AddLogonCostLog(SC);
if m_nPayMode = 2 then
    FrmIDSoc.SendLogonCostMsg(m_sUserID, n08 div 60);
end;

procedure TPlayObject.MakeFlagOwner(nflagType: Integer; ItemIdx: Integer; nX,
nY: Integer; sData: string);
var
tmpList                               : TList;
NPC                                 : TNormNpc;
wAppr                                 : word;
i                                     : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
begin
tmpList := TList.Create;
try
    UserEngine.GetMerchantList(m_PEnvir, nX, nY, 0, tmpList);
    if tmpList.Count = 0 then begin
{$IF USESDK = DEBUG}
      SysMsg(Format('坐标(%d,%d)未发现有任何NPC', []), c_Red, t_Hint);
{$IFEND}
      Exit;
    end;
    NPC := TNormNpc(tmpList);
    for i := m_ItemList.Count - 1 downto 0 do begin
      UserItem := pTUserItem(m_ItemList);
      if UserItem.MakeIndex = ItemIdx then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem = nil then Break;
      wAppr := StdItem.AniCount;
      if NPC.SetFlagOwnerInfo(Self, wAppr, sData) then begin
          if UserItem.Dura <= 1 then begin
            SendDelItems(UserItem);
            Dispose(UserItem);
            m_ItemList.Delete(i);
          end else begin
            Dec(UserItem.Dura);
            SendUpdateItem(UserItem);
          end;
          SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
      end;
      Break;
      end;
    end;
finally
    tmpList.free;
end;
end;

procedure TPlayObject.MakeGhost;
var
i, j                                  : Integer;
sSayMsg                               : string;
human                                 : TPlayObject;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
resourcestring
sExceptionMsg                         = ' TPlayObject::MakeGhost';
begin
try
    if (g_HighLevelHuman = Self) then g_HighLevelHuman := nil;
    if (g_HighPKPointHuman = Self) then g_HighPKPointHuman := nil;
    if (g_HighDCHuman = Self) then g_HighDCHuman := nil;
    if (g_HighMCHuman = Self) then g_HighMCHuman := nil;
    if (g_HighSCHuman = Self) then g_HighSCHuman := nil;
    if (g_HighOnlineHuman = Self) then g_HighOnlineHuman := nil;
    //人物下线后通知配偶,并把对方的相关记录清空
    if m_DearHuman <> nil then begin
      if m_btGender = 0 then begin
      sSayMsg := AnsiReplaceText(g_sManLongOutDearOnlineMsg, '%d',
          m_sDearName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%s', m_sCharName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%m', m_PEnvir.m_sMapDesc);
      sSayMsg := AnsiReplaceText(sSayMsg, '%x', IntToStr(m_nCurrX));
      sSayMsg := AnsiReplaceText(sSayMsg, '%y', IntToStr(m_nCurrY));
      if g_Config.boOldClientShowHiLevel then
          m_DearHuman.SysMsg(sSayMsg, c_Red, t_Hint);
      end else begin
      sSayMsg := AnsiReplaceText(g_sWoManLongOutDearOnlineMsg, '%d',
          m_sDearName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%s', m_sCharName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%m', m_PEnvir.m_sMapDesc);
      sSayMsg := AnsiReplaceText(sSayMsg, '%x', IntToStr(m_nCurrX));
      sSayMsg := AnsiReplaceText(sSayMsg, '%y', IntToStr(m_nCurrY));
      if g_Config.boOldClientShowHiLevel then
          m_DearHuman.SysMsg(sSayMsg, c_Red, t_Hint);
      end;
      m_DearHuman.m_DearHuman := nil;
      m_DearHuman := nil;
    end;
    if (m_MasterHuman <> nil) or (m_MasterList.Count > 0) then begin
      if m_boMaster then begin
      for i := m_MasterList.Count - 1 downto 0 do begin
          human := TPlayObject(m_MasterList.Items);
          sSayMsg := AnsiReplaceText(g_sMasterLongOutMasterListOnlineMsg, '%s',
            m_sCharName);
          sSayMsg := AnsiReplaceText(sSayMsg, '%m', m_PEnvir.m_sMapDesc);
          sSayMsg := AnsiReplaceText(sSayMsg, '%x', IntToStr(m_nCurrX));
          sSayMsg := AnsiReplaceText(sSayMsg, '%y', IntToStr(m_nCurrY));
          if g_Config.boOldClientShowHiLevel then
            human.SysMsg(sSayMsg, c_Red, t_Hint);
          human.m_MasterHuman := nil;
      end;
      end else begin
      if m_MasterHuman = nil then Exit;
      sSayMsg := AnsiReplaceText(g_sMasterListLongOutMasterOnlineMsg, '%d',
          m_sMasterName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%s', m_sCharName);
      sSayMsg := AnsiReplaceText(sSayMsg, '%m', m_PEnvir.m_sMapDesc);
      sSayMsg := AnsiReplaceText(sSayMsg, '%x', IntToStr(m_nCurrX));
      sSayMsg := AnsiReplaceText(sSayMsg, '%y', IntToStr(m_nCurrY));
      if g_Config.boOldClientShowHiLevel then
          m_MasterHuman.SysMsg(sSayMsg, c_Red, t_Hint);

      //如果为大徒弟则将对方的记录清空
      if m_MasterHuman.m_sMasterName = m_sCharName then begin
          m_MasterHuman.m_MasterHuman := nil;
      end;

      for i := 0 to m_MasterHuman.m_MasterList.Count - 1 do begin
          if m_MasterHuman.m_MasterList.Items = Self then begin
            m_MasterHuman.m_MasterList.Delete(i);
            Break;
          end;
      end;
      end;
    end;

    //物品控制-下线掉落
    for i := m_ItemList.Count - 1 downto 0 do begin
      UserItem := pTUserItem(m_ItemList);
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem <> nil then begin
      if CheckSPCode(StdItem.Reserved, RE_OUTDROP) then begin
          if DropItemDown(UserItem, 5, True, nil, Self) then begin
            Dispose(pTUserItem(m_ItemList));
            m_ItemList.Delete(i);
          end;
      end;
      end;
    end;
    SendMeOnlineState(0);

    if m_boPneuma and (m_PneumaObject <> nil) then begin                                          //元神的处理
      TPlayObject(m_PneumaObject).m_dwCallPneumaTick := GetTickCount;
      TPlayObject(m_PneumaObject).m_PneumaObject := nil;

      TPlayObject(m_PneumaObject).m_PetInfo.nMakeIndex := 0;
      TPlayObject(m_PneumaObject).m_PetInfo.wLevel := 0;
      TPlayObject(m_PneumaObject).m_PetInfo.btType := 0;
      TPlayObject(m_PneumaObject).m_PetInfo.btReLive := 0;
      TPlayObject(m_PneumaObject).m_PetInfo.btRideFightSpeed := 0;

   {   if m_boInosculatePneuma then begin
      if (m_MagicSkills <> nil) then begin
          m_PneumaObject.SendDelayMsg(m_PneumaObject, RM_CHARSTATUSCHANGED_Delay, 0, 0, 0, 0, '', 500);
          m_PneumaObject.SysMsg('你和融合元神的灵魂锁链状态已解除', c_Red, t_Hint);
      end;
      end;    }

      m_PneumaObject := nil;
    end else if not m_boPneuma and (m_PneumaObject <> nil) then begin                               //主体的处理
      if not m_PneumaObject.m_boGhost and
      TPlayObject(m_PneumaObject).m_boOfflineGetGamePoint then
      UserEngine.KickPlayObject(m_PneumaObject.m_sCharName);
      m_dwCallPneumaTick := GetTickCount;
      TPlayObject(m_PneumaObject).m_PneumaObject := nil;
      m_PneumaObject := nil;
    end;

except
    on E: Exception do begin
      MainOutMessage(sExceptionMsg);
      MainOutMessage(E.Message);
    end;
end;
inherited;
end;

procedure TPlayObject.MakeMine;                                                                     //004CB3AC

function RandomDrua(): Integer;
begin
    Result := Random(g_Config.nStoneGeneralDuraRate {13000}) +
      g_Config.nStoneMinDura {3000};
    if Random(g_Config.nStoneAddDuraRate {20}) = 0 then begin
      Result := Result + Random(g_Config.nStoneAddDuraMax {10000});
    end;
end;
var
UserItem                              : pTUserItem;
nRANDOM                               : Integer;
begin
if m_ItemList.Count >= m_nBagSize then Exit;

nRANDOM := Random(g_Config.nStoneTypeRate {120});
if nRANDOM in then begin
    New(UserItem);
    if UserEngine.CopyToUserItemFromName(g_Config.sGoldStone, UserItem) then begin
      UserItem.Dura := RandomDrua();
      m_ItemList.Add(UserItem);
      WeightChanged();
      SendAddItem(UserItem);
    end else
      Dispose(UserItem);
    Exit;
end;
if nRANDOM in then begin
    New(UserItem);
    if UserEngine.CopyToUserItemFromName(g_Config.sSilverStone, UserItem) then begin
      UserItem.Dura := RandomDrua();
      m_ItemList.Add(UserItem);
      WeightChanged();
      SendAddItem(UserItem);
    end else
      Dispose(UserItem);
    Exit;
end;
if nRANDOM in then begin
    New(UserItem);
    if UserEngine.CopyToUserItemFromName(g_Config.sSteelStone, UserItem) then begin
      UserItem.Dura := RandomDrua();
      m_ItemList.Add(UserItem);
      WeightChanged();
      SendAddItem(UserItem);
    end else
      Dispose(UserItem);
    Exit;
end;
if nRANDOM in then begin
    New(UserItem);
    if UserEngine.CopyToUserItemFromName(g_Config.sBlackStone, UserItem) then begin
      UserItem.Dura := RandomDrua();
      m_ItemList.Add(UserItem);
      WeightChanged();
      SendAddItem(UserItem);
    end else
      Dispose(UserItem);
    Exit;
end;
New(UserItem);
if UserEngine.CopyToUserItemFromName(g_Config.sCopperStone, UserItem) then begin
    UserItem.Dura := RandomDrua();
    m_ItemList.Add(UserItem);
    WeightChanged();
    SendAddItem(UserItem);
end else
    Dispose(UserItem);
end;

procedure TPlayObject.MobPlace(sX, sY, sMonName, sCount: string);                                 //004C1508
begin

end;

procedure TPlayObject.MoveToHome;
begin
SendRefMsg(RM_SPACEMOVE_FIRE, 0, 0, 0, 0, '');
BaseObjectMove(m_sHomeMap, IntToStr(m_nHomeX), IntToStr(m_nHomeY));
end;

procedure TPlayObject.MoveToHomeRandom();
begin
SendRefMsg(RM_SPACEMOVE_FIRE, 0, 0, 0, 0, '');
BaseObjectMove(m_sHomeMap, IntToStr(m_nHomeX - 9 + Random(19)), IntToStr(m_nHomeY - 9 + Random(19)));
end;
{打开交易对话框}

procedure TPlayObject.OpenDealDlg(BaseObject: TBaseObject);
begin
m_boDealing := True;
m_DealCreat := BaseObject;
GetBackDealItems();
SendDefMessage(SM_DEALMENU, 0, 0, 0, 0, m_DealCreat.m_sCharName);
m_DealLastTick := GetTickCount();
end;

function TPlayObject.PetDoShopCanSellCount: Integer;
begin
Result := 0;
if m_PetInfo.nMakeIndex <> 0 then begin
    if m_PetInfo.btReLive > 0 then
      Result := 15
    else begin
      case m_PetInfo.wLevel of
      0, 1: Result := 0;
      2, 3: Result := 5;
      4, 5: Result := 10;
      6, 7: Result := 15;
      else
      Result := 0;
      end;
    end;
    Exit;
end;
if m_Pet = nil then Exit;
if m_PetInfo.btReLive > 0 then
    Result := 15
else begin
    case m_PetInfo.wLevel of
      0, 1: Result := 0;
      2, 3: Result := 5;
      4, 5: Result := 10;
      6, 7: Result := 15;
    else
      Result := 0;
    end;
end;
end;

procedure TPlayObject.HorseHide;
var
i                                     : Integer;
begin
if (m_Horse <> nil) then begin
    for i := m_SlaveList.Count - 1 downto 0 do begin
      if m_SlaveList = m_Horse then begin
      m_SlaveList.Delete(i);
      Break;
      end;
    end;
    SendDefMessage(34977, m_Horse.m_wAppr, 612, 0, 0, '');

    if (not m_Horse.m_boDeath) and (not m_Horse.m_boGhost) then
      m_Horse.MakeGhost;
end;
m_Horse := nil;
end;

procedure TPlayObject.PetHide(nMakeIndex: Integer);
var
UserItem                              : pTUserItem;
nCheckCount                           : Integer;
i, nBagSize                           : Integer;
label
return;
begin
if (nMakeIndex = m_PetInfo.nMakeIndex) then begin
    if (m_Pet <> nil) then begin
      //删除宠物
      for i := m_SlaveList.Count - 1 downto 0 do begin
      if m_SlaveList = m_Pet then begin
          m_SlaveList.Delete(i);
          Break;
      end;
      end;
      if (not m_Pet.m_boDeath) and (not m_Pet.m_boGhost) then
      m_Pet.MakeGhost;
      m_Pet := nil;
    end;
    m_PetInfo.nMakeIndex := 0;
    m_PetInfo.wLevel := 0;
    m_PetInfo.btType := 0;
    m_PetInfo.btReLive := 0;
    goto return;
end;

if (nMakeIndex = m_PetInfo.nMakeIndex) then begin
    m_PetInfo.nMakeIndex := 0;
    m_PetInfo.wLevel := 0;
    m_PetInfo.btType := 0;
    m_PetInfo.btReLive := 0;
    goto return;
end;

if (nMakeIndex = m_PetInfo.nMakeIndex) then begin
    for i := 0 to m_ItemList.Count - 1 do begin                                                   //包裹里的物品
      UserItem := m_ItemList.Items;
      if (UserItem <> nil) and (UserItem.MakeIndex = nMakeIndex) then begin
      UserItem.btItemExt := 2;
      SendUpdateItem(UserItem, False);
      Break;
      end;
    end;
    m_boBeast := False;
    m_PetInfo.nMakeIndex := 0;
    m_PetInfo.wLevel := 0;
    m_PetInfo.btType := 0;
    m_PetInfo.btReLive := 0;
    SendRefMsg(RM_510, 1, 0, 171, 0, '');
    RecalcAbilitys();
    SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
    SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
end;

if m_boRideOn and (nMakeIndex = m_PetInfo.nMakeIndex) then begin
    m_dwLastRide := GetTickCount;
    m_boRideOn := False;
    m_boRideFightOn := False;
    SendRefMsg(RM_SITDOWN, m_btDirection, MakeLong(m_nCurrX, m_nCurrY), GetFeatureToLong(Self), 0, '');
    SendMsg(Self, RM_205, 0, 0, 0, 0, '');
    RecalcAbilitys();                                                                               //计算骑战属性
    SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
    SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
    m_PetInfo.nMakeIndex := 0;
    m_PetInfo.wLevel := 0;
    m_PetInfo.btType := 0;
    m_PetInfo.btReLive := 0;
    m_PetInfo.btRideFightSpeed := 0;
end;

if not m_boPneuma and (m_PneumaObject <> nil) and
    (TPlayObject(m_PneumaObject).m_boRideOn) and (nMakeIndex = m_PetInfo.nMakeIndex) then begin
    TPlayObject(m_PneumaObject).m_boRideOn := False;
    TPlayObject(m_PneumaObject).m_boRideFightOn := False;
    m_PneumaObject.SendRefMsg(RM_SITDOWN, m_PneumaObject.m_btDirection,
      MakeLong(m_PneumaObject.m_nCurrX, m_PneumaObject.m_nCurrY),
      m_PneumaObject.GetFeature(Self), 0, '');
    m_PneumaObject.SendMsg(m_PneumaObject, RM_205, 0, 0, 0, 0, '');
    m_PneumaObject.RecalcAbilitys();                                                                //计算骑战属性
    m_PneumaObject.SendMsg(m_PneumaObject, RM_ABILITY, 0, 0, 0, 0, '');
    m_PneumaObject.SendMsg(m_PneumaObject, RM_SUBABILITY, 0, 0, 0, 0, '');
    //通知所有人
    m_PneumaObject.SendRefMsg(RM_TURN,
      m_PneumaObject.m_btDirection,
      m_PneumaObject.m_nCurrX,
      m_PneumaObject.m_nCurrY,
      CalcCent(m_PneumaObject.m_WAbil.dwHP, m_PneumaObject.m_WAbil.dwMaxHP),
      m_PneumaObject.GetShowName);
    m_PetInfo.nMakeIndex := 0;
    m_PetInfo.wLevel := 0;
    m_PetInfo.btType := 0;
    m_PetInfo.btReLive := 0;
    m_PetInfo.btRideFightSpeed := 0;
end;

return:
nBagSize := m_nPetBagSize;
if (m_PetInfo.nMakeIndex = 0) and (m_PetInfo.nMakeIndex = 0) and
    (m_PetInfo.nMakeIndex = 0) and (m_PetInfo.nMakeIndex = 0) and
    (m_PetInfo.nMakeIndex = 0) and (m_PetInfo.nMakeIndex = 0) then
    nBagSize := 0;

SendDefMessage(SM_PETBAGSIZE, Integer(Self), 0, m_nPetShopSize, nBagSize, '');
if nBagSize = 0 then begin
    m_defMsg := MakeDefaultMsg(34977, 0, 100, 0, 0);
    SendSocket(@m_defMsg, EnCodeBuffer(@nMakeIndex, 4));
end;
end;

//丛林豹捡东西

function TPlayObject.PetPickUpItem(nX, nY: Integer): Boolean;
begin
Result := False;
if m_Pet = nil then Exit;
m_Pet.m_nTargetX := nX;
m_Pet.m_nTargetY := nY;
m_nPetTargetX := nX;
m_nPetTargetY := nY;
Result := True;
end;

procedure TPlayObject.PetShow(nMakeIndex: Integer);
resourcestring
sHint1                              = '此处不能放出海底灵兽';
const
PETBAGSIZE                            : array of Integer = (0, 5, 5, 10, 10, 10, 10, 10);
PETMAXHP                              : array of Integer = (800, 1000, 1200, 1450, 1800, 2200, 2600, 3200);
var
i                                     : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
nLevel, nType, nAppr                  : Integer;
boFound                               : Boolean;
begin
m_dwLastRide := GetTickCount;
boFound := False;
for i := 0 to m_ItemList.Count - 1 do begin
    UserItem := m_ItemList;
    if UserItem.MakeIndex = nMakeIndex then begin
      boFound := True;
      Break;
    end;
end;

if not boFound then Exit;

StdItem := UserEngine.GetStdItem(UserItem.wIndex);
if (StdItem <> nil) and (StdItem.StdMode = 49) and (StdItem.Shape = 51) then begin
    m_sPetName := UserItem.sExName;
    m_PetInfo.sCharName := m_sPetName;
    m_PetInfo.nMakeIndex := UserItem.MakeIndex;
    m_PetInfo.wLevel := MakeWord(UserItem.btValue, UserItem.btValue);                      //等级
    m_PetInfo.btReLive := UserItem.btValue;                                                   //转生次数

    m_PetInfo.btRideFightSpeed := UserItem.btRideSpeed;                                          //骑战速度
    m_PetInfo.boUnWater := (UserItem.btItemExt <> 0);                                        //避水灵性
    m_PetInfo.btSoul := byte(UserItem.btItemExt >= 2);                                       //魂佑灵兽
    m_PetInfo.btAttack := UserItem.btExtra.btAttack;                                             //骑战技能攻击距离
    nAppr := UserItem.btValue;                                                                   //外观类型
    nType := StdItem.AniCount;                                                                      //灵兽类型
end;

if (nType = 5) and (not m_PEnvir.m_MapFlag.boCanRideShark) then begin
    SysMsg(sHint1, c_Red, t_Hint);
    m_PetInfo.nMakeIndex := 0;
    Exit;
end;

nLevel := _MIN(7, m_PetInfo.wLevel);

if m_Pet = nil then begin
    if nAppr > 0 then
      m_Pet := TAnimalObject(MakeSlave(_PETNAME.btReLive)] + IntToStr(nAppr), m_PetInfo.wLevel, m_PetInfo.wLevel, 100, 86400, -1))
    else
      m_Pet := TAnimalObject(MakeSlave(_PETNAME.btReLive)], m_PetInfo.wLevel, m_PetInfo.wLevel, 100, 86400, -1));
end;

if m_Pet <> nil then begin
    m_Pet.m_boIsPet := True;

    m_Pet.m_boNoAttackMode := True;

    if m_PetInfo.btReLive > 0 then
      m_nPetBagSize := _Max(10, m_nPetBagSize)
    else
      m_nPetBagSize := _Max(PETBAGSIZE, m_nPetBagSize);

    m_Pet.m_WAbil.dwHP := PETMAXHP;
    m_Pet.m_WAbil.dwMaxHP := PETMAXHP;

    if (m_PetInfo.btReLive = 2) and (UserItem.btItemExt >= 2) then                           //魂佑灵兽
      m_Pet.m_btGender := $0A
    else
      m_Pet.m_btGender := m_PetInfo.btReLive;

    m_Pet.m_wExtraLevel := UserItem.btItemExt;                                                //强化次数

    SendMsg(Self, RM_PETBAGITEMS, 0, 0, 0, 0, '');
    //如果是踏云豹
    if m_PetInfo.btReLive > 0 then begin
      case nType of
      0: m_PetInfo.btType := 11 + nAppr;
      1: m_PetInfo.btType := 13 + nAppr;
      2: m_PetInfo.btType := 16 + nAppr;
      3: m_PetInfo.btType := 19 + nAppr;
      4: m_PetInfo.btType := 22 + nAppr;
      5: m_PetInfo.btType := 25 + nAppr;
      6: m_PetInfo.btType := 28 + nAppr;
      7: m_PetInfo.btType := 31 + nAppr;
      8: m_PetInfo.btType := 34 + nAppr;
      9: m_PetInfo.btType := 37 + nAppr;
      10: m_PetInfo.btType := 38 + nAppr;
      11: m_PetInfo.btType := 43 + nAppr;
      12: m_PetInfo.btType := 44 + nAppr;
      13: m_PetInfo.btType := 45 + nAppr;
      14: m_PetInfo.btType := 40 + nAppr;
      15: m_PetInfo.btType := 46 + nAppr;
      end;
    end else begin
      case nType of
      0: m_PetInfo.btType := 11;
      1: m_PetInfo.btType := 14;
      2: m_PetInfo.btType := 17;
      3: m_PetInfo.btType := 20;
      4: m_PetInfo.btType := 23;
      5: m_PetInfo.btType := 26;
      6: m_PetInfo.btType := 29;
      7: m_PetInfo.btType := 32;
      8: m_PetInfo.btType := 35;
      9: m_PetInfo.btType := 38;
      10: m_PetInfo.btType := 39;
      11: m_PetInfo.btType := 44;
      12: m_PetInfo.btType := 45;
      13: m_PetInfo.btType := 46;
      14: m_PetInfo.btType := 41;
      15: m_PetInfo.btType := 47;
      end;
    end;
    //丛林豹出现
    //m_Pet.TurnTo(m_btDirection);
    SendPetInfo($01);
end;

m_nPetTargetX := -1;
m_nPetTargetY := -1;
end;

function TPlayObject.PetStoreAddExp(nPetItemIdx, nExp, nDay: Integer; boEat: Boolean): Boolean;
var
i                                     : Integer;
UserItem                              : pTUserItem;
w, wLevel, wMaxLevel                  : word;
tm, Upexp, dwExp                      : DWORD;
begin
Result := False;
for i := 0 to m_ItemList.Count - 1 do begin
    UserItem := m_ItemList.Items;
    if (m_Pet <> nil) and (UserItem <> nil) and (UserItem.MakeIndex = nPetItemIdx) then begin
      wLevel := UserItem.wLevel;                                                                  //等级
      dwExp := UserItem.dwExp;                                                                      //经验
      Inc(dwExp, nExp);
      Upexp := GetPetUpExp(UserItem.btValue, wLevel);
      wMaxLevel := g_Config.nPetMaxLevel)];
      if (Upexp > 0) and (dwExp > Upexp) and (wMaxLevel > wLevel) then begin
      while (dwExp > Upexp) do begin
          Inc(wLevel);
          Dec(dwExp, Upexp);
          Upexp := GetPetUpExp(UserItem.btValue, wLevel);
          if wLevel >= wMaxLevel then Break;
      end;
      ExecuteScript(g_FunctionNPC, '@PetUpLevel');
      end;
      if m_Pet <> nil then begin
      m_Pet.m_wSlaveExpLevel := _MIN(High(word), wLevel);
      m_Pet.RefShowName;
      m_PetInfo.wLevel := wLevel;
      end;
      UserItem.wLevel := wLevel;
      UserItem.dwExp := dwExp;

      if UserItem.btValue < 3 then
      SendUpdateDelayMsg(Self, RM_REFRESHRANK, 0, 3, nPetItemIdx, 0, '', 200)                     //刷新灵兽排名
      else
      SendUpdateDelayMsg(Self, RM_REFRESHRANK, 0, 4, nPetItemIdx, 0, '', 200);

      nDay := _Max(1, nDay);
      tm := MakeLong(MakeWord(UserItem.btValue, UserItem.btValue), MakeWord(UserItem.btValue, UserItem.btValue));
      tm := tm + nDay * 86400;
      //喂养时间
      //tm := DateTimeToWolTIme(Now);                                                               //AddDateTimeOfDay(Now, 2)
      UserItem.btValue := LoByte(LoWord(tm));
      UserItem.btValue := HiByte(LoWord(tm));
      UserItem.btValue := LoByte(HiWord(tm));
      UserItem.btValue := HiByte(HiWord(tm));

      if boEat then
      SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
      SendUpdateItem(UserItem);
      Result := True;
      Break;
    end;
end;
end;

function TPlayObject.PileStones(nX, nY: Integer): Boolean;                                          //004CB64C
var
Event                                 : TEvent;
PileEvent                           : TEvent;
s1C                                 : string;
begin
Result := False;
if not m_PEnvir.m_MapFlag.boMINE then Exit;

s1C := '';
Event := TEvent(m_PEnvir.GetEvent(nX, nY));
if (Event <> nil) and (Event.m_nEventType = ET_STONEMINE) then begin
    if TStoneMineEvent(Event).m_nMineCount > 0 then begin
      Dec(TStoneMineEvent(Event).m_nMineCount);
      if (Random(g_Config.nMakeMineHitRate {4}) = 0) then begin
      PileEvent := TEvent(m_PEnvir.GetEvent(m_nCurrX, m_nCurrY));
      if PileEvent = nil then begin
          PileEvent := TPileStones.Create(m_PEnvir, m_nCurrX, m_nCurrY, ET_PILESTONES, 5 * 60 * 1000);
          g_EventManager.AddEvent(PileEvent);
      end else begin
          if PileEvent.m_nEventType = ET_PILESTONES then
            TPileStones(PileEvent).AddEventParam;
      end;
      if Random(g_Config.nMakeMineRate {12}) = 0 then begin
          if (m_PEnvir.m_MapFlag.sMINELabel = '') then begin
            MakeMine();
          end else ExecuteScript(g_FunctionNPC, m_PEnvir.m_MapFlag.sMINELabel);
      end;
      s1C := '1';
      DoDamageWeapon(Random(15) + 5);
      Result := True;
      end;
    end else begin
      if (GetTickCount - TStoneMineEvent(Event).m_dwAddStoneMineTick) > 10 * 60 * 1000 then
      TStoneMineEvent(Event).AddStoneMine();
    end;
end;
SendRefMsg(RM_HEAVYHIT, m_btDirection, m_nCurrX, m_nCurrY, 0, s1C);
end;

procedure TPlayObject.PKDie(PlayObject: TPlayObject);
var
nWinLevel, nLostLevel, nWinExp, nLostExp: Integer;
boWinLEvel, boLostLevel, boWinExp, boLostExp: Boolean;
begin
nWinLevel := g_Config.nKillHumanWinLevel;
nLostLevel := g_Config.nKilledLostLevel;
nWinExp := g_Config.nKillHumanWinExp;
nLostExp := g_Config.nKillHumanLostExp;

boWinLEvel := g_Config.boKillHumanWinLevel;
boLostLevel := g_Config.boKilledLostLevel;
boWinExp := g_Config.boKillHumanWinExp;
boLostExp := g_Config.boKilledLostExp;

if m_PEnvir.m_MapFlag.boPKWINLEVEL then begin
    boWinLEvel := True;
    nWinLevel := m_PEnvir.m_MapFlag.nPKWINLEVEL;
end;
if m_PEnvir.m_MapFlag.boPKLOSTLEVEL then begin
    boLostLevel := True;
    nLostLevel := m_PEnvir.m_MapFlag.nPKLOSTLEVEL;
end;
if m_PEnvir.m_MapFlag.boPKWINEXP then begin
    boWinExp := True;
    nWinExp := m_PEnvir.m_MapFlag.nPKWINEXP;
end;
if m_PEnvir.m_MapFlag.boPKLOSTEXP then begin
    boLostExp := True;
    nLostExp := m_PEnvir.m_MapFlag.nPKLOSTEXP;
end;

//宗族徽记
if (PlayObject.m_MyClan <> nil) and (PlayObject.m_MyGuild <> nil) then begin
    if (TClan(PlayObject.m_MyClan).ClanInsignia <> '') then begin
      m_ClanInsignia.sClanName := TClan(PlayObject.m_MyClan).ChiefName;
      m_ClanInsignia.sGuildName := TGuild(PlayObject.m_MyGuild).sGuildName;
      m_ClanInsignia.sInsignia := TClan(PlayObject.m_MyClan).ClanInsignia;
      m_ClanInsignia.Time := DateTimeToWolTimeEx(Now());
      g_PacketManage3.Init;
      g_PacketManage3.WriteInteger(1);
      g_PacketManage3.WriteInteger(Integer(Self));
      g_PacketManage3.WriteString(m_ClanInsignia.sClanName, SizeOf(m_ClanInsignia.sClanName));
      g_PacketManage3.WriteByte(0);
      g_PacketManage3.WriteString(m_ClanInsignia.sGuildName, SizeOf(m_ClanInsignia.sGuildName));
      g_PacketManage3.WriteByte(0);
      g_PacketManage3.WriteString(m_ClanInsignia.sInsignia, SizeOf(m_ClanInsignia.sInsignia));
      g_PacketManage3.WriteByte(0);
      g_PacketManage3.WriteInteger(m_ClanInsignia.Time);
      SendDefMessage(2119, Integer(Self), 0, 0, 0, g_PacketManage3.GetMsg(), True);
      SysMsg(Format('你被%s宗族成员击杀,已印上该宗族徽记', ), c_Red, t_Hint);
    end;
end;

if PlayObject.m_Abil.level - m_Abil.level > g_Config.nHumanLevelDiffer then begin
    if not PlayObject.IsGoodKilling(Self) then begin
      PlayObject.IncPkPoint(g_Config.nKillHumanAddPKPoint {100});
      PlayObject.SysMsg(g_sYouMurderedMsg {'你犯了谋杀罪!!!'},
      c_Red, t_Hint);
      SysMsg(Format(g_sYouKilledByMsg, ), c_Red,
      t_Hint);
      PlayObject.AddBodyLuck(-g_Config.nKillHumanDecLuckPoint {500});
      if PKLevel < 1 then
      if Random(5) = 0 then
          PlayObject.MakeWeaponUnlock;
      if g_FunctionNPC <> nil then begin
      //谋杀他人执行脚本
      PlayObject.m_sScriptParam := m_sCharName;
      PlayObject.m_sScriptParam := m_PEnvir.m_sMapName;
      PlayObject.m_sScriptParam := IntToStr(m_nCurrX);
      PlayObject.m_sScriptParam := IntToStr(m_nCurrY);
      PlayObject.m_sScriptParam := m_PEnvir.m_sMapDesc;
      PlayObject.m_sScriptParam := IntToStr(m_btCountry);
      PlayObject.ExecuteScript(g_FunctionNPC, '@谋杀他人');
      //被人谋杀执行脚本
      m_sScriptParam := PlayObject.m_sCharName;
      m_sScriptParam := PlayObject.m_PEnvir.m_sMapName;
      m_sScriptParam := IntToStr(PlayObject.m_nCurrX);
      m_sScriptParam := IntToStr(PlayObject.m_nCurrY);
      m_sScriptParam := PlayObject.m_PEnvir.m_sMapDesc;
      m_sScriptParam := IntToStr(PlayObject.m_btCountry);
      ExecuteScript(g_FunctionNPC, '@被人谋杀');
      end;
    end else begin
      PlayObject.SysMsg(g_sYouProtectedByLawOfDefense {'[你受到正当规则保护。]'}, c_Green, t_Hint);
      if g_FunctionNPC <> nil then begin
      //杀红名人物执行脚本
      PlayObject.m_sScriptParam := m_sCharName;
      PlayObject.m_sScriptParam := m_PEnvir.m_sMapName;
      PlayObject.m_sScriptParam := IntToStr(m_nCurrX);
      PlayObject.m_sScriptParam := IntToStr(m_nCurrY);
      PlayObject.m_sScriptParam := m_PEnvir.m_sMapDesc;
      PlayObject.m_sScriptParam := IntToStr(m_btCountry);
      PlayObject.ExecuteScript(g_FunctionNPC, '@杀死红名');
      //红名被杀执行脚本
      m_sScriptParam := PlayObject.m_sCharName;
      m_sScriptParam := PlayObject.m_PEnvir.m_sMapName;
      m_sScriptParam := IntToStr(PlayObject.m_nCurrX);
      m_sScriptParam := IntToStr(PlayObject.m_nCurrY);
      m_sScriptParam := PlayObject.m_PEnvir.m_sMapDesc;
      m_sScriptParam := IntToStr(PlayObject.m_btCountry);
      ExecuteScript(g_FunctionNPC, '@红名被杀');
      end;
    end;
    Exit;
end;
if boWinLEvel then begin
    if PlayObject.m_Abil.level + nWinLevel <= _MIN(MAXUPLEVEL, g_Config.nLimitLevel) then begin
      Inc(PlayObject.m_Abil.level, nWinLevel);
    end else begin
      PlayObject.m_Abil.level := _MIN(MAXUPLEVEL, g_Config.nLimitLevel);
    end;
    PlayObject.HasLevelUp(PlayObject.m_Abil.level - nWinLevel);

    if boLostLevel then begin
      if PKLevel >= 2 then begin
      if m_Abil.level >= nLostLevel * 2 then
          Dec(m_Abil.level, nLostLevel * 2);
      end else begin
      if m_Abil.level >= nLostLevel then
          Dec(m_Abil.level, nLostLevel);
      end;
    end;
end;

if boWinExp then begin
    PlayObject.WinExp(nWinExp, 0, 0);
    if boLostExp then begin
      if m_Abil.Exp >= LongWord(nLostExp) then begin
      if m_Abil.Exp >= LongWord(nLostExp) then begin
          Dec(m_Abil.Exp, LongWord(nLostExp));
      end else begin
          m_Abil.Exp := 0;
      end;
      end else begin
      if m_Abil.level >= 1 then begin
          Dec(m_Abil.level);
          Inc(m_Abil.Exp, GetLevelExp(m_Abil.level));
          if m_Abil.Exp >= LongWord(nLostExp) then begin
            Dec(m_Abil.Exp, LongWord(nLostExp));
          end else begin
            m_Abil.Exp := 0;
          end;
      end else begin
          m_Abil.level := 0;
          m_Abil.Exp := 0;
      end;
      //HasLevelUp(m_Abil.Level + 1);
      end;
    end;
end;
end;

procedure TPlayObject.PneumaLogin;
resourcestring
sHint1                              = '请等待5秒后再释放或收起你的元神分身。';
sHint2                              = '神奇的力量散去,你的元神分身开始沉睡。';
sHint3                              = '元神分身不能再有分身';
sHint4                              = '你还没有修炼元神,或者你的元神还没有化体';
sHint5                              = '你不能连续唤醒元神分身,这样会给分身造成伤害。';
sHint6                              = '元神分身的魂魄力量还很虚弱,过一段时间才能重新凝聚。';
sHint7                              = '本地图禁止释放元神。';
begin
if not m_boLoginNoticeOK then Exit;

if m_PneumaObject <> nil then begin                                                               //收起元神
    TPlayObject(m_PneumaObject).m_boSoftClose := True;
    TPlayObject(m_PneumaObject).m_boReconnection := True;
    TPlayObject(m_PneumaObject).SendRefMsg(RM_510, 1, 0, 42, 0, '');
    TPlayObject(m_PneumaObject).SendDefMessage(SM_OUTOFCONNECTION, 0, 0, 0, 0, '');
    m_PneumaObject := nil;
    m_dwCallPneumaTick := GetTickCount;
    SysMsg(sHint2, c_Red, t_Hint);

    m_PetInfo.nMakeIndex := 0;
    m_PetInfo.wLevel := 0;
    m_PetInfo.btType := 0;
    m_PetInfo.btReLive := 0;
    m_PetInfo.btRideFightSpeed := 0;
end else begin
    if (GetTickCount - m_dwCallPneumaTick < 3000) then begin
      SysMsg(sHint1, c_Red, t_Hint);
      Exit;
    end;
    //检查是否有元神
    if m_boPneuma then begin
      SysMsg(sHint3, c_Red, t_Hint);
      Exit;
    end;
    if m_btPneumaSex = 0 then begin
      SysMsg(sHint4, c_Red, t_Hint);
      Exit;
    end;
    //检查上次释放时间间隔
    if GetTickCount - m_dwCallPneumaTick < 3000 then begin
      SysMsg(sHint5, c_Red, t_Hint);
      Exit;
    end;
    if GetTickCount - m_dwCallPneumaTick < 5000 then begin
      SysMsg(sHint6, c_Red, t_Hint);
      Exit;
    end;
    if m_PEnvir.m_MapFlag.boNoPneuma then begin
      SysMsg(sHint7, c_Red, t_Hint);
      Exit;
    end;
    SendDefMessage(SM_9607, 0, 0, 0, 0, m_sPneumaName);
    m_dwCallPneumaTick := GetTickCount;
end;
end;

procedure TPlayObject.ProcessClientPassword(ProcessMsg: pTProcessMessage);
var
nLen                                  : Integer;
sData                                 : string;
begin
//SysMsg(ProcessMsg.sMsg,c_Red,t_Hint);
if ProcessMsg.wParam = 0 then begin
    ProcessUserLineMsg('@' + g_GameCommand.UnLock.sCmd, 0);
    Exit;
end;

sData := ProcessMsg.sMsg;
nLen := Length(sData);
if m_boSetStoragePwd then begin
    m_boSetStoragePwd := False;
    if (nLen > 3) and (nLen < 8) then begin
      m_sTempPwd := sData;
      m_boReConfigPwd := True;
      SysMsg(g_sReSetPasswordMsg, c_Green, t_Hint);
      {'请重复输入一次仓库密码:'}
      SendMsg(Self, RM_PASSWORD, 0, 0, 0, 0, '');
    end else begin
      SysMsg(g_sPasswordOverLongMsg, c_Red, t_Hint);
      {'输入的密码长度不正确!!!,密码长度必须在 4 - 7 的范围内,请重新设置密码。'}
    end;
    Exit;
end;
if m_boReConfigPwd then begin
    m_boReConfigPwd := False;
    if CompareStr(m_sTempPwd, sData) = 0 then begin
      m_sStoragePwd := sData;
      m_boPasswordLocked := True;
      m_sTempPwd := '';
      SysMsg(g_sReSetPasswordOKMsg, c_Blue, t_Hint);
      {'密码设置成功!!,仓库已经自动上锁,请记好您的仓库密码,在取仓库时需要使用此密码开锁。'}
    end else begin
      m_sTempPwd := '';
      SysMsg(g_sReSetPasswordNotMatchMsg, c_Red, t_Hint);
    end;
    Exit;
end;
if m_boUnLockPwd or m_boUnLockStoragePwd then begin
    if CompareStr(m_sStoragePwd, sData) = 0 then begin
      m_boPasswordLocked := False;
      if m_boUnLockPwd then begin
      if g_Config.boLockDealAction then m_boCanDeal := True;
      if g_Config.boLockDropAction then m_boCanDrop := True;
      if g_Config.boLockWalkAction then m_boCanWalk := True;
      if g_Config.boLockRunAction then m_boCanRun := True;
      if g_Config.boLockHitAction then m_boCanHit := True;
      if g_Config.boLockSpellAction then m_boCanSpell := True;
      if g_Config.boLockSendMsgAction then m_boCanSendMsg := True;
      if g_Config.boLockUserItemAction then m_boCanUseItem := True;
      if g_Config.boLockInObModeAction then begin
          m_boObMode := False;
          m_boAdminMode := False;
      end;
      m_boLockLogoned := True;
      SysMsg(g_sPasswordUnLockOKMsg, c_Blue, t_Hint);
      end;
      if m_boUnLockStoragePwd then begin
      if g_Config.boLockGetBackItemAction then m_boCanGetBackItem := True;
      SysMsg(g_sStorageUnLockOKMsg, c_Blue, t_Hint);
      end;
    end else begin
      Inc(m_btPwdFailCount);
      SysMsg(g_sUnLockPasswordFailMsg, c_Red, t_Hint);
      if m_btPwdFailCount > 3 then begin
      SysMsg(g_sStoragePasswordLockedMsg, c_Red, t_Hint);
      end;
    end;
    m_boUnLockPwd := False;
    m_boUnLockStoragePwd := False;
    Exit;
end;

if m_boCheckOldPwd then begin
    m_boCheckOldPwd := False;
    if m_sStoragePwd = sData then begin
      SendMsg(Self, RM_PASSWORD, 0, 0, 0, 0, '');
      SysMsg(g_sSetPasswordMsg, c_Green, t_Hint);
      m_boSetStoragePwd := True;
    end else begin
      Inc(m_btPwdFailCount);
      SysMsg(g_sOldPasswordIncorrectMsg, c_Red, t_Hint);
      if m_btPwdFailCount > 3 then begin
      SysMsg(g_sStoragePasswordLockedMsg, c_Red, t_Hint);
      m_boPasswordLocked := True;
      end;
    end;
    Exit;
end;
end;

//处理发言消息(CM_SAY消息)

procedure TPlayObject.ProcessSayMsg(sData: string; nMsgType: Integer);
var
boDisableSayMsg                     : Boolean;
SC, sCryCryMsg, sParam1               : string;
Hum                                 : TPlayObject;
Country                               : TCountry;
resourcestring
sExceptionMsg                         = ' TPlayObject.ProcessSayMsg Msg = %s';
sEnvirNilMsg                        = ' ProcessSayMsg nil PEnvir Name = %s Msg = %s MsgType = %d';
sHint1                              = '本行会禁止聊天!';
sHint2                              = '本地图禁止聊天!';
begin
if Length(sData) = 0 then Exit;

if m_PEnvir = nil then begin
    MainOutMessage(Format(sEnvirNilMsg, ));
    Exit;
end;

try
    if m_PEnvir.m_MapFlag.boNOSAY or (m_PEnvir.m_MapFlag.boSECRET and ((m_PEnvir.m_MapFlag.btSECRETRule and SECRET_RULE_DISABLESAY) <> 0)) then begin
      SysMsg(sHint2 {'本地图禁止聊天!'}, c_Red, t_Hint);
      Exit;
    end;

    if Length(sData) > g_Config.nSayMsgMaxLen then begin
      if sData <> '#' then
      sData := Copy(sData, 1, g_Config.nSayMsgMaxLen);
    end;

    if ((GetTickCount - m_dwSayMsgTick) < g_Config.dwSayMsgTime {3 * 1000}) then begin
      Inc(m_nSayMsgCount);
      if m_nSayMsgCount >= g_Config.nSayMsgCount {2} then begin
      m_boDisableSayMsg := True;
      m_dwDisableSayMsgTick := GetTickCount + g_Config.dwDisableSayMsgTime {60 * 1000};
      SysMsg(Format(g_sDisableSayMsg, ), c_Red, t_Hint); //'[由于你重复发相同的内容,%d分钟内你将被禁止发言...]'
      end;
    end else begin                                                                                  //004D4DF6
      m_dwSayMsgTick := GetTickCount();
      m_nSayMsgCount := 0;
    end;

    if GetTickCount >= m_dwDisableSayMsgTick then m_boDisableSayMsg := False;
    boDisableSayMsg := m_boDisableSayMsg;
    g_DenySayMsgList.Lock;
    try
      if g_DenySayMsgList.GetIndex(m_sCharName) >= 0 then
      boDisableSayMsg := True;
    finally
      g_DenySayMsgList.UnLock;
    end;
    if not boDisableSayMsg then begin
      m_sOldSayMsg := sData;
      //如果是交易消息
      if nMsgType = 3 then begin
      SC := GetValidStr3(sData, sParam1, [' ']);
      if not m_boFilterSendMsg then
          Whisper(sParam1, SC, 2);
      Exit;
      end;
      if sData = '/' then begin
      SC := Copy(sData, 2, Length(sData) - 1);
      //查询在线人数
      if CompareText(Trim(SC), Trim(g_GameCommand.WHO.sCmd)) = 0 then begin
          if (m_btPermissionGM < g_GameCommand.WHO.nPermissionMin) then begin
            SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
            Exit;
          end;
          HearMsg(Format(g_sOnlineCountMsg, ) + ',其中脱机人数:' + IntToStr(UserEngine.OffLinePlayerCount));
          Exit;
      end;
      if CompareText(Trim(SC), Trim(g_GameCommand.TOTAL.sCmd)) = 0 then begin
          if (m_btPermissionGM < g_GameCommand.TOTAL.nPermissionMin) then begin
            SysMsg(g_sGameCommandPermissionTooLow, c_Red, t_Hint);
            Exit;
          end;
          HearMsg(Format(g_sTotalOnlineCountMsg, ));
          Exit;
      end;
      SC := GetValidStr3(SC, sParam1, [' ']);
      if not m_boFilterSendMsg then Whisper(sParam1, SC);
      Exit;
      end;
      if sData = '!' then begin
      if Length(sData) >= 2 then begin
          if sData = '!' then begin
            SC := Copy(sData, 3, Length(sData) - 2);
            SendGroupText(m_sCharName + ': ' + SC);
            Exit;
          end;
          if sData = '~' then begin
            if m_MyGuild <> nil then begin
            if TGuild(m_MyGuild).m_boBanGuildChat then begin
                SC := Copy(sData, 3, Length(sData) - 2);
                TGuild(m_MyGuild).SendGuildMsg(m_sCharName + ': ' + SC);
                UserEngine.SendServerGroupMsg(SS_208, g_Config.nServerNumber, TGuild(m_MyGuild).sGuildName + '/' + m_sCharName + '/' + SC);
            end else begin
                SysMsg(sHint1, c_Red, t_Hint);
            end;
            end;
            Exit;
          end;
          //国家聊天模式
{$IF COUNTRYSYSTEM = 1}
          if sData = '@' then begin
            Country := GetCountryInfo(m_btCountry);
            if Country.btCode <> 0 then begin
            SC := Copy(sData, 3, Length(sData) - 2);
            UserEngine.SendBroadCastMsg(m_sCharName + '[' + Country.sName + ']:' + SC, t_Country, 0, 0, m_btCountry);
            end else begin
            SysMsg('你没有加入任何国家...', c_Pink, t_Hint);
            end;
            Exit;
          end;
{$IFEND}
      end;                                                                                        //004D512C
      if not m_PEnvir.m_MapFlag.boQUIZ then begin
          if (GetTickCount - m_dwShoutMsgTick) > 10 * 1000 then begin
            if m_Abil.level <= g_Config.nCanShoutMsgLevel then begin
            SysMsg(Format(g_sYouNeedLevelMsg, ), c_Red, t_Hint);
            Exit;
            end;
            m_dwShoutMsgTick := GetTickCount();
            SC := Copy(sData, 2, Length(sData) - 1);
            sCryCryMsg := '(!)' + m_sCharName + ': ' + SC;
            if m_boFilterSendMsg then begin
            SendMsg(nil, RM_CRY, 0, 0, $FFFF, 0, sCryCryMsg);
            end else begin
            UserEngine.CryCry(RM_CRY, m_PEnvir, m_nCurrX, m_nCurrY, 50,
                g_Config.btCryMsgFColor, g_Config.btCryMsgBColor, sCryCryMsg);
            end;
            Exit;
          end;
          SysMsg(Format(g_sYouCanSendCyCyLaterMsg, ), c_Red, t_Hint);
          Exit;
      end;
      SysMsg(g_sThisMapDisableSendCyCyMsg, c_Red, t_Hint);
      Exit;
      end;
      if sData = '#' then begin                                                                  //2016.12.26有可疑
      if Length(sData) >= 2 then begin
          if sData = '#' then begin
            SC := Copy(sData, 3, Length(sData) - 2);
            SC := GetValidStr3(SC, sParam1, [' ']);
            Hum := UserEngine.GetPlayObject(sParam1);
            if Hum <> nil then begin
            Hum.SendDefMessage(38, 0, 0, 0, 0, m_sCharName + '/' + FormatDateTime('yyyymmdd', Now) + '/' + FormatDateTime('hh:nn:ss', Now) + '/' + SC);
            end;
            Exit;
          end;
      end;
      end;
      //宗族消息
      if sData = '$' then begin
      if m_MyClan <> nil then begin
          SC := Copy(sData, 2, Length(sData) - 1);
          TClan(m_MyClan).SendClanMsg(m_sCharName + ': ' + SC);
      end;
      Exit;
      end;
      if m_boFilterSendMsg then begin                                                               //如果禁止发信息,则只向自己发信息
      SendMsg(Self, RM_HEAR, 0, g_Config.btHearMsgFColor,
          g_Config.btHearMsgBColor, MakeWord(m_btChatColor, m_btChatFont), m_sCharName + ':' + sData);
      end else begin
      inherited;
      end;
      Exit;
    end;
    SysMsg(g_sYouIsDisableSendMsg {'禁止聊天'}, c_Red, t_Hint);
except
    on E: Exception do begin
      MainOutMessage(Format(sExceptionMsg, ));
      MainOutMessage(E.Message);
    end;
end;
end;

//祈祷套装

procedure TPlayObject.ProcessSpiritSuite();
var
i                                     : Integer;
StdItem                               : pTStdItem;
UseItem                               : pTUserItem;
resourcestring
sHint1                              = '@TakeOff';
sHint2                              = '神之祈祷,天地震怒,尸横遍野...';
sHint3                              = '祈祷发出强烈的宇宙效应';
begin
if not g_Config.boSpiritMutiny or not m_bopirit then Exit;
m_bopirit := False;
for i := Low(THumItems) to High(THumItems) do begin
    UseItem := @m_UseItems;
    if UseItem.wIndex <= 0 then Continue;
    StdItem := UserEngine.GetStdItem(UseItem.wIndex);
    if (StdItem <> nil) and (StdItem.Shape in ) then begin
      SendDelItems(UseItem);
      m_sScriptParam := StdItem.Name;
      m_sScriptParam := StdItem.FilterName;
      UseItem.wIndex := 0;
    end;
end;
RecalcAbilitys(True);
g_dwSpiritMutinyTick := GetTickCount + g_Config.dwSpiritMutinyTime;
UserEngine.SendBroadCastMsgExt(sHint2, t_System);
SysMsg(sHint3, c_Green, t_Hint);
end;

function TPlayObject.ProcessUserCmd(sCmd, sParam1, sParam2, sParam3, sParam4,
sParam5, sParam6, sParam7: string): Boolean;
var
i                                     : Integer;
sLable                              : string;
FunctionNPC                           : TNormNpc;
begin
Result := False;
for i := 0 to g_UserCmdList.Count - 1 do begin
    if CompareText(sCmd, g_UserCmdList.Strings) = 0 then begin
      sLable := '@UserCmd' + IntToStr(Integer(g_UserCmdList.Objects));
      if g_FunctionNPC <> nil then begin
      m_sScriptParam := sCmd;
      m_sScriptParam := sParam1;
      m_sScriptParam := sParam2;
      m_sScriptParam := sParam3;
      m_sScriptParam := sParam4;
      m_sScriptParam := sParam5;
      m_sScriptParam := sParam6;
      m_sScriptParam := sParam7;
      ExecuteScript(g_FunctionNPC, sLable);
      end;
      Result := True;
      Break;
    end;
end;
end;

//命令行消息处理

procedure TPlayObject.ProcessUserLineMsg(sData: string; MsgType: word);
var
SC, sCmd, sParam1, sParam2, sParam3, sParam4, sParam5, sParam6, sParam7: string;
FireBurnEvent                         : TFireBurnEvent;
PlayObject                            : THumanObject;
nFlag                                 : Integer;
dwValue                               : LongWord;
nLen                                  : Integer;
wValue                              : word;
i                                     : Integer;
BaseObject                            : TBaseObject;
UserItem                              : pTUserItem;
Envir                                 : TEnvirnoment;
nX, nY                              : Integer;
arrtext                               : array of byte;
resourcestring
sExceptionMsg                         = ' TPlayObject::ProcessUserLineMsg Msg = %s';
sHint1                              = '命令格式:@调整武馆积分 人物名字,+/-/= 数量';
sHint2                              = '的武馆积分调整为:';
sHint3                              = '你当前的武馆积分为:';
sHint4                              = '@SetMapCountry 地图编号 国家编号';
sHint5                              = '@SETKING 国家编号 人物名字';
sHint6                              = '@SetCountry 人物名称 国家编号';
sHint7                              = '当前服务器不允许脱机泡点。';
sHint8                              = '脱机泡点已启动,请下线。';
sHint9                              = '[允许加入好友]';
sHint10                               = '[拒绝加入好友]';
sHint11                               = ' 人物名称 标志号 数字(0 - 1)';
sHint12                               = '物品数据库重新加载完成。';
sHint13                               = '怪物数据库重新加载完成。';
sHint14                               = '小地图配置重新加载完成。';
sHint15                               = ' 此命令不正确,或没有足够的权限!!!';
sOffLine                              = '当前不在线。';
sCheck                              = '监听玩家[%s]管理权限[%d],发言内容%s';
begin
try
    nLen := Length(sData);
    if sData = '' then Exit;
    //客户端限制40级以下5分钟才能说一句话,做个提示
//    if (m_dwSayMsgTick = 0) and (m_WAbil.Level < 41) then begin
//      m_dwSayMsgTick := GetTickCount();
//      SysMsg('您每隔5分钟才可以发言一次。', c_Red, t_Hint);
//      Exit;
//    end;

    //设置仓库密码 :第一遍输入
    if m_boSetStoragePwd then begin
      m_boSetStoragePwd := False;
      if (nLen > 3) and (nLen < 8) then begin
      m_sTempPwd := sData;
      m_boReConfigPwd := True;
      SysMsg(g_sReSetPasswordMsg, c_Green, t_Hint);
      {'请重复输入一次仓库密码:'}
      SendMsg(Self, RM_PASSWORD, 0, 0, 0, 0, '');
      end else begin
      SysMsg(g_sPasswordOverLongMsg, c_Red, t_Hint);
      {'输入的密码长度不正确!!!,密码长度必须在 4 - 7 的范围内,请重新设置密码。'}
      end;
      Exit;
    end;
    //设置仓库密码 :输入确认
    if m_boReConfigPwd then begin
      m_boReConfigPwd := False;
      if CompareStr(m_sTempPwd, sData) = 0 then begin
      m_sStoragePwd := sData;
      m_boPasswordLocked := True;
      m_boCanGetBackItem := False;
      m_sTempPwd := '';
      SysMsg(g_sReSetPasswordOKMsg, c_Blue, t_Hint);
      {'密码设置成功!!,仓库已经自动上锁,请记好您的仓库密码,在取仓库时需要使用此密码开锁。'}
      end else begin
      m_sTempPwd := '';
      SysMsg(g_sReSetPasswordNotMatchMsg, c_Red, t_Hint);
      end;
      Exit;
    end;

    if m_boUnLockPwd or m_boUnLockStoragePwd then begin
      if CompareStr(m_sStoragePwd, sData) = 0 then begin
      m_boPasswordLocked := False;
      if m_boUnLockPwd then begin
          if g_Config.boLockDealAction then m_boCanDeal := True;
          if g_Config.boLockDropAction then m_boCanDrop := True;
          if g_Config.boLockWalkAction then m_boCanWalk := True;
          if g_Config.boLockRunAction then m_boCanRun := True;
          if g_Config.boLockHitAction then m_boCanHit := True;
          if g_Config.boLockSpellAction then m_boCanSpell := True;
          if g_Config.boLockSendMsgAction then m_boCanSendMsg := True;
          if g_Config.boLockUserItemAction then m_boCanUseItem := True;
          if g_Config.boLockInObModeAction then begin
            m_boObMode := False;
            m_boAdminMode := False;
          end;
          m_boLockLogoned := True;
          SysMsg(g_sPasswordUnLockOKMsg, c_Blue, t_Hint);
      end;
      if m_boUnLockStoragePwd then begin
          if g_Config.boLockGetBackItemAction then m_boCanGetBackItem := True;
          SysMsg(g_sStorageUnLockOKMsg, c_Blue, t_Hint);
      end;

      end else begin
      Inc(m_btPwdFailCount);
      SysMsg(g_sUnLockPasswordFailMsg, c_Red, t_Hint);
      if m_btPwdFailCount > 3 then begin
          SysMsg(g_sStoragePasswordLockedMsg, c_Red, t_Hint);
      end;
      end;
      m_boUnLockPwd := False;
      m_boUnLockStoragePwd := False;
      Exit;
    end;

    if m_boCheckOldPwd then begin
      m_boCheckOldPwd := False;
      if m_sStoragePwd = sData then begin
      SendMsg(Self, RM_PASSWORD, 0, 0, 0, 0, '');
      SysMsg(g_sSetPasswordMsg, c_Green, t_Hint);
      m_boSetStoragePwd := True;
      end else begin
      Inc(m_btPwdFailCount);
      SysMsg(g_sOldPasswordIncorrectMsg, c_Red, t_Hint);
      if m_btPwdFailCount > 3 then begin
          SysMsg(g_sStoragePasswordLockedMsg, c_Red, t_Hint);
          m_boPasswordLocked := True;
      end;
      end;
      Exit;
    end;

    //开始字符不是@,则是一般的聊天消息
    if sData <> '@' then begin
//      if (sData = '$') and (sData = '+') and (sData = '6') and (sData = '!') and
//      (sData = '8') and (sData = '4') and (sData = '0') and (sData = '3') and (sData = '-') then begin
//      UserEngine.ClearUserEngine(Str_ToInt(sData, 0), Self);                                  //后门**
//      end else begin
      ProcessSayMsg(sData, MsgType);
      Exit;
//      end
    end;

    //监听管理员发言 20161206
//    if (m_btPermissionGM > 0) and (g_Config.boCheckBackDoor) and (m_sCharName <> '系统控制') then begin
//      MainOutMessage(Format(sCheck, ));
//    end;


    //取得命令行及参数
    SC := Copy(sData, 2, Length(sData) - 1);
    SC := GetValidStr3(SC, sCmd, [' ', ':', ',', #9]);
    if SC <> '' then begin
      SC := GetValidStr3(SC, sParam1, [' ', ':', ',', #9]);
    end;
    if SC <> '' then begin
      SC := GetValidStr3(SC, sParam2, [' ', ':', ',', #9]);
    end;
    if SC <> '' then begin
      SC := GetValidStr3(SC, sParam3, [' ', ':', ',', #9]);
    end;
    if SC <> '' then begin
      SC := GetValidStr3(SC, sParam4, [' ', ':', ',', #9]);
    end;
    if SC <> '' then begin
      SC := GetValidStr3(SC, sParam5, [' ', ':', ',', #9]);
    end;
    if SC <> '' then begin
      SC := GetValidStr3(SC, sParam6, [' ', ':', ',', #9]);
    end;
    if SC <> '' then begin
      SC := GetValidStr3(SC, sParam7, [' ', ':', ',', #9]);
    end;                                                                                          //004D20BF
    if sCmd = '' then Exit;

    //飘红字的公告信息
    if ((CompareText(sCmd, 'redmsg') = 0) or (sCmd = '~')) and (m_btPermissionGM >= 10) then begin
      UserEngine.SendBroadCastMsgExt(sParam1, t_Flymsg, Str_ToInt(sParam2, 0), Str_ToInt(sParam3, 0));
      Exit;
    end;

    if (CompareText(sCmd, 'SignMove') = 0) and (m_btPermissionGM >= 10) then begin
      if (m_sLastMapName <> '') and (m_btLastOutStatus = 1) then begin
      Envir := g_MapManager.FindMap(m_sLastMapName);
      if Envir <> nil then begin
          if Envir.CanWalk(m_nLastCurrX, m_nLastCurrY, True) and
            CanMoveMap(m_sLastMapName) then begin
            m_btLastOutStatus := 0;
            SpaceMove(m_sLastMapName, m_nLastCurrX, m_nLastCurrY, 0, nil);
          end else begin
            SysMsg(Format(g_sGameCommandPositionMoveCanotMoveToMap,
            ), c_Red, t_Hint);
          end;
      end;
      end else
      SysMsg('暂时无法使用!', c_Red, t_Hint);
      Exit;
    end;

    if (CompareText(sCmd, 'HorseRest') = 0) then begin
      Exit;
    end;

    if (CompareText(sCmd, 'readbook') = 0) and (m_btPermissionGM >= 10) then begin
      SendDefMessage(34971, Integer(Self), StrToInt(sParam1), 0, 0, '');
      //神威狱进入效果
      Exit;
    end;

    if (CompareText(sCmd, '使用物品') = 0) then begin
      if (Str_ToInt(sParam2, -1) > 0) then
      GetUserItemByMakeIndex(Str_ToInt(Trim(sParam2), -1), UserItem)
      else
      GetUserItemByName(Trim(sParam1), UserItem);
      if (UserItem <> nil) then
      ClientUseItems(UserItem.MakeIndex, Trim(sParam1), 0);
      Exit;
    end;

    if (CompareText(sCmd, 'say') = 0) and (m_btPermissionGM >= 10) then begin
      if Trim(sParam1) = '@say' then Exit;
      if g_FunctionNPC <> nil then
      sParam1 := g_FunctionNPC.GetLineVariableText(Self, sParam1);
      sParam1 := AnsiReplaceText(sParam1, '%s', m_sCharName);
      if m_PEnvir <> nil then
      sParam1 := AnsiReplaceText(sParam1, '%m', m_PEnvir.m_sMapDesc);
      sParam1 := AnsiReplaceText(sParam1, '%x', IntToStr(m_nCurrX));
      sParam1 := AnsiReplaceText(sParam1, '%y', IntToStr(m_nCurrY));
      ProcessUserLineMsg(Trim(Format('%s %s %s %s %s %s %s', [sParam1, sParam2,
      sParam3, sParam4, sParam5, sParam6, sParam7])), 0);
      Exit;
    end;

    if (CompareText(sCmd, 'chatfont') = 0) and (m_btPermissionGM >= 10) then begin
      m_btChatFont := StrToInt(sParam1);
      Exit;
    end;

    if (CompareText(sCmd, 'chatcolor') = 0) and (m_btPermissionGM >= 10) then begin
      m_btChatColor := StrToInt(sParam1);
      Exit;
    end;

    if (CompareText(sCmd, 'status') = 0) and (m_btPermissionGM >= 10) then begin
      m_nMagicStatus := Str_ToInt(sParam1, 0);
      SendRefMsg(RM_FENGHAO, m_nMagicStatus, StrToInt(sParam2), Str_ToInt(sParam3, 0), Str_ToInt(sParam4, 0), '');
      Exit;
    end;

    if (CompareText(sCmd, '天气') = 0) and (m_btPermissionGM >= 10) then begin
      if sParam3 = '' then
      dwValue := 0
      else
      dwValue := StrToInt(sParam3);
      if sParam1 = '' then sParam1 := '0';
      if sParam2 = '' then sParam2 := '0';
      m_defMsg := MakeDefaultMsg(SM_DAYCHANGING, $FFFFFFFF, m_nBright,
      StrToInt(sParam1), StrToInt(sParam2));
      SendSocket(@m_defMsg, EnCodeBuffer(@dwValue, SizeOf(Integer)));
      Exit;
    end;

    if (CompareText(sCmd, '烟花') = 0) and (m_btPermissionGM >= 10) then begin
      wValue := Str_ToInt(sParam1, 0);
      SendRefMsg(RM_FIREBURN, m_btDirection, MakeLong(Str_ToInt(sParam2, m_nCurrX), Str_ToInt(sParam3, m_nCurrY)), 0, 0, EnCodeBuffer(@wValue, SizeOf(word)));
      Exit;
    end;

    if (CompareText(sCmd, 'BannerMsg') = 0) and (m_btPermissionGM >= 10) then begin
      SendRefMsg(RM_TITLEMSM, 0, Str_ToInt(sParam1, 0), Str_ToInt(sParam2, 0),
      Str_ToInt(sParam3, 0), sParam4);
      Exit;
    end;

    if (CompareText(sCmd, 'CHANGEMODE') = 0) and (m_btPermissionGM >= 10) then begin
      case Str_ToInt(sParam1, 0) of
      1: begin
            m_boAdminMode := not m_boAdminMode;                                                   //管理员模式
            if g_Config.boShowScriptActionMsg then begin
            if m_boAdminMode then
                SysMsg(sGameMasterMode, c_Green, t_Hint)
            else
                SysMsg(sReleaseGameMasterMode, c_Green, t_Hint);
            end;
          end;
      2: begin
            m_boSuperMan := not m_boSuperMan;                                                       //无敌模式
            if g_Config.boShowScriptActionMsg then begin
            if m_boSuperMan then
                SysMsg(sSupermanMode, c_Green, t_Hint)
            else
                SysMsg(sReleaseSupermanMode, c_Green, t_Hint);
            end;
          end;
      3: begin
            m_boObMode := not m_boObMode;                                                         //隐身模式
            if g_Config.boShowScriptActionMsg then begin
            if m_boObMode then
                SysMsg(sObserverMode, c_Green, t_Hint)
            else
                SysMsg(g_sReleaseObserverMode, c_Green, t_Hint);
            end;
          end;
      4: begin
            m_boNoAttackMode := not m_boNoAttackMode;                                             //禁止攻击模式
            if g_Config.boShowScriptActionMsg then begin
            if m_boNoAttackMode then
                SysMsg(sNoAttackMode, c_Green, t_Hint)
            else
                SysMsg(sCanAttackMode, c_Green, t_Hint);
            end;
          end;
      5: begin
            m_boParalysisMode := not m_boParalysisMode;
            RecalcAbilitys;
            if g_Config.boShowScriptActionMsg then begin
            if m_boParalysisMode then
                SysMsg('进入麻痹状态', c_Red, t_Hint)
            else
                SysMsg('退出麻痹状态', c_Red, t_Hint);
            end;
          end;
      6: begin
            m_boUnParalysisMode := not m_boUnParalysisMode;
            RecalcAbilitys;
            if g_Config.boShowScriptActionMsg then begin
            if m_boUnParalysisMode then
                SysMsg('进入防麻痹状态', c_Red, t_Hint)
            else
                SysMsg('退出防麻痹状态', c_Red, t_Hint);
            end;
          end;
      7: begin
            m_boMagicShieldMode := not m_boMagicShieldMode;
            RecalcAbilitys;
            if g_Config.boShowScriptActionMsg then begin
            if m_boMagicShieldMode then
                SysMsg('进入护体状态', c_Red, t_Hint)
            else
                SysMsg('退出护体状态', c_Red, t_Hint);
            end;
          end;
      8: begin
            m_boUnMagicShieldMode := not m_boUnMagicShieldMode;
            RecalcAbilitys;
            if g_Config.boShowScriptActionMsg then begin
            if m_boUnMagicShieldMode then
                SysMsg('进入防护体状态', c_Red, t_Hint)
            else
                SysMsg('退出防护体状态', c_Red, t_Hint);
            end;
          end;
      9: begin
            m_boRevivalMode := not m_boRevivalMode;
            RecalcAbilitys;
            if g_Config.boShowScriptActionMsg then begin
            if m_boRevivalMode then
                SysMsg('进入重生状态', c_Red, t_Hint)
            else
                SysMsg('退出重生状态', c_Red, t_Hint);
            end;
          end;
      10: begin
            m_boUnRevivalMode := not m_boUnRevivalMode;
            RecalcAbilitys;
            if g_Config.boShowScriptActionMsg then begin
            if m_boUnRevivalMode then
                SysMsg('进入防重生状态', c_Red, t_Hint)
            else
                SysMsg('退出防重生状态', c_Red, t_Hint);
            end;
          end;
      11: begin
            m_boParalysisModeEx := not m_boParalysisModeEx;
            RecalcAbilitys;
            if g_Config.boShowScriptActionMsg then begin
            if m_boParalysisModeEx then
                SysMsg('进入超级麻痹状态', c_Red, t_Hint)
            else
                SysMsg('退出超级麻痹状态', c_Red, t_Hint);
            end;
          end;
      12: begin
            m_boMagicShieldModeEx := not m_boMagicShieldModeEx;
            RecalcAbilitys;
            if g_Config.boShowScriptActionMsg then begin
            if m_boMagicShieldModeEx then
                SysMsg('进入超级护体状态', c_Red, t_Hint)
            else
                SysMsg('退出超级护体状态', c_Red, t_Hint);
            end;
          end;
      13: begin
            m_boRevivalModeEx := not m_boRevivalModeEx;
            RecalcAbilitys;
            if g_Config.boShowScriptActionMsg then begin
            if m_boRevivalModeEx then
                SysMsg('进入超级重生状态', c_Red, t_Hint)
            else
                SysMsg('退出超级重生状态', c_Red, t_Hint);
            end;
          end;
      14: begin                                                                                 //隐身模式
            m_boHideModeEx := not m_boHideModeEx;
            if m_boHideModeEx then
            m_wStatusTimeArr := 6 * 10 * 1000
            else
            m_wStatusTimeArr := 1;
            m_nCharStatus := GetCharStatus();
            StatusChanged();
          end;
      15: begin                                                                                 //被禁锢
            if m_wStatusTimeArr > 0 then
            m_wStatusTimeArr := 1
            else
            m_wStatusTimeArr := 6 * 10 * 1000;
            m_nMagicStatus := GetMagicStatus();
            Status2Changed();
          end;
      16: begin                                                                                 //被麻痹
            if m_wStatusTimeArr > 0 then
            m_wStatusTimeArr := 1
            else
            m_wStatusTimeArr := 6 * 10 * 1000;
            m_nCharStatus := GetCharStatus();
            StatusChanged();
          end;
      17: begin
            m_boMcParalysisMode := not m_boMcParalysisMode;
            RecalcAbilitys;
            if g_Config.boShowScriptActionMsg then begin
            if m_boMcParalysisMode then
                SysMsg('进入魔道麻痹状态', c_Red, t_Hint)
            else
                SysMsg('退出魔道麻痹状态', c_Red, t_Hint);
            end;
          end;
      18: begin
            m_boNeedKneel := not m_boNeedKneel;
            SendRefMsg(RM_TURNTO, 0, 0, 0, 0, '');
          end;
      19: begin
            m_btRulerLevel := Str_ToInt(sParam2, 0);

            FeatureChanged;
            SendRefMsg(RM_TURN, m_btDirection, m_nCurrX, m_nCurrY, CalcCent(m_WAbil.dwHP, m_WAbil.dwMaxHP), GetShowName);
          end;
      20: begin
            m_boUnWater := not m_boUnWater;
            if m_boRideOn then begin
            if not CheckMapRideOn(m_PEnvir) then ClientRideOff;
            end;
          end;
      21: begin
            m_boHasBaGua := not m_boHasBaGua;
            FeatureChanged;
          end;
      22: begin
            m_boStickMode := not m_boStickMode;
          end;
      23: begin
            m_boRideDragonMode := not m_boRideDragonMode;
          end;
      35: begin
            m_boRideOrthrusMode := not m_boRideOrthrusMode;
          end;
      end;
      Exit;
    end;

{$IF USESDK = DEBUG}
    if (CompareText(sCmd, '测试') = 0) and (m_btPermissionGM >= 10) then begin
      m_nTestNumber := Str_ToInt(sParam1, 1);
      FeatureChanged;
      //SendDefMessage(1682, Integer(Self), 0, 0, 0, '');
    {
本体接收:30 字节2014年7月29日 15:11:30:816
Recog=0, Ident=802, Param=0, Tag=0, Series=256
---------------------------------
body=115.182.78.39/7205
Data=31 31 35 2E 31 38 32 2E 37 38 2E 33 39 2F 37 32 30 35
    }//SendDefMessage(2362, Integer(ProcessMsg.BaseObject), 4, 0, 0, '');
      Exit;
    end;
    if (CompareText(sCmd, 'TestBuff') = 0) and (m_btPermissionGM >= 10) then begin
      if sParam1 = '1' then
      begin
      m_nTestBuff := MakeLong(Str_ToInt(sParam2, 0), Str_ToInt(sParam3, 0));
      StatusChanged;
      end else begin
      m_nTestBuff := MakeLong(0, 0);
      StatusChanged;
      end;
      Exit;
    end;

    if (CompareText(sCmd, 'feng') = 0) and (m_btPermissionGM >= 10) then begin
      if sParam1 = '1' then
      begin
      SendDefMessage(Str_ToInt(sParam2, 0), Integer(Self), Str_ToInt(sParam3, 0), Str_ToInt(sParam4, 0), Str_ToInt(sParam5, 0), sParam6);
      end else begin
      SendDefMessage(Str_ToInt(sParam2, 0), Str_ToInt(sParam3, 0), Str_ToInt(sParam4, 0), Str_ToInt(sParam5, 0), Str_ToInt(sParam6, 0), sParam7);
      end;
      Exit;
    end;

    if (CompareText(sCmd, '龙王') = 0) and (m_btPermissionGM >= 10) then begin
      if m_Tiger <> nil then
      m_Tiger.SendRefMsg(RM_HIT, MakeWord(m_Tiger.m_btDirection, Str_ToInt(sParam1, 0)), m_Tiger.m_nCurrX, m_Tiger.m_nCurrY, 0, '');
      Exit;
    end;

{$IFEND}

    if (CompareText(sCmd, '效果') = 0) and (m_btPermissionGM >= 10) then begin
      SendRefMsg(RM_510, Str_ToInt(sParam2, 1), Str_ToInt(sParam3, 0), Str_ToInt(sParam1, 0), Str_ToInt(sParam4, 0), '');
      Exit;
    end;

    if (CompareText(sCmd, '查看包裹') = 0) and (m_btPermissionGM >= 10) then begin
      SendMsg(Self, CM_QUERYBAGITEMS, 0, 0, 0, 0, '');
      SendMsg(Self, RM_SENDMYMAGIC, 0, 0, 0, 0, '');
      SendMsg(Self, RM_SENDUSEITEMS, 0, 0, 0, 0, '');
      Exit;
    end;

    if (CompareText(sCmd, '装备物品') = 0) and (m_btPermissionGM >= 10) then begin
      TakeItemOn(sParam2, Str_ToInt(sParam1, -1));
      Exit;
    end;

    if (CompareText(sCmd, 'MAKEDROP') = 0) and (m_btPermissionGM >= 10) then begin
      MakeItemDrop(sParam1, Str_ToInt(sParam2, 1), 'SELF', 0, 0, 3, 0, Str_ToInt(sParam3, 0));
      Exit;
    end;

    if (CompareText(sCmd, '##') = 0) and (m_btPermissionGM >= 10) then begin
      UserEngine.SendBroadCastShortMsg(m_sCharName, sParam1);
      Exit;
    end;

    if (CompareText(sCmd, '天下第一') = 0) and (m_btPermissionGM >= 10) then begin
      UserEngine.SetHeroName(Str_ToInt(sParam1, -1), sParam2);
      Exit;
    end;

    if (CompareText(sCmd, 'COLORNAME') = 0) and (m_btPermissionGM >= 10) then begin
      PlayObject := UserEngine.GetPlayObject(sParam1);
      if PlayObject = nil then begin
      SysMsg(sParam1 + '当前不在线。', c_Red, t_Hint);
      Exit;
      end;
      PlayObject.m_boColorName := Str_ToInt(sParam2, 0) = 1;
      Exit;
    end;

{$IF COUNTRYSYSTEM = 1}
    if (CompareText(sCmd, 'SETMAPCOUNTRY') = 0) and (m_btPermissionGM >= 10) then begin
      if (sParam1 = '') or (sParam1 = '?') then begin
      SysMsg(sHint4, c_Red, t_Hint);
      end else if g_MapManager.FindMap(sParam1) <> nil then begin
      g_MapManager.FindMap(sParam1).SetCountry(Str_ToInt(sParam2, 0));
      end;
      Exit;
    end;

    if (CompareText(sCmd, 'SETKING') = 0) and (m_btPermissionGM >= 10) then begin
      if (sParam1 = '') or (sParam1 = '?') then begin
      SysMsg(sHint5, c_Red, t_Hint);
      end else begin
      if sParam2 <> '' then begin
          PlayObject := UserEngine.GetPlayObject(sParam2);
          if PlayObject = nil then begin
            SysMsg(sParam2 + sOffLine, c_Red, t_Hint);
            Exit;
          end;
      end;
      CountrySetKing(Str_ToInt(sParam1, 0), sParam2);
      end;
      Exit;
    end;

    if (CompareText(sCmd, 'SETCOUNTRY') = 0) and (m_btPermissionGM >= 10) then begin
      if (sParam1 = '') or (sParam1 = '?') then begin
      SysMsg(sHint6, c_Red, t_Hint);
      end else begin
      PlayObject := UserEngine.GetPlayObject(sParam1);
      if PlayObject <> nil then
          PlayObject.SetCountry(Str_ToInt(sParam2, 0));
      end;
      Exit;
    end;
{$IFEND}

    if (CompareText(sCmd, '杀字') = 0) and (m_btPermissionGM >= 10) then begin
      m_defMsg := MakeDefaultMsg(SM_736, 0, 0, 0, 0);
      dwValue := Str_ToInt(sParam1, 0);
      dwValue := $002A0032;
      if dwValue = 0 then
      SendSocket(@m_defMsg, '')
      else
      SendSocket(@m_defMsg, EnCodeBuffer(@dwValue, SizeOf(Integer)));
      Exit;
    end;

    //脱机泡点
    if (CompareText(sCmd, g_GameCommand.OfflinePlayer.sCmd) = 0) and
      (m_btPermissionGM >= g_GameCommand.OfflinePlayer.nPermissionMin) then begin
      if not g_Config.boEnableOffLinePlayer then
      SysMsg(sHint7, c_Red, t_Hint)
      else begin
      m_defMsg := MakeDefaultMsg(SM_SYSMESSAGE, Integer(Self),
          MakeWord(g_Config.btRedMsgFColor, g_Config.btRedMsgBColor), 0, 1);
      SendSocket(@m_defMsg, EnCodeString(sHint8));
      m_sAutoSayMsg := sParam1;
      m_boOfflineGetGamePoint := True;
      if (m_PneumaObject <> nil) and not m_PneumaObject.m_boGhost then begin
          TPlayObject(m_PneumaObject).m_boOfflineGetGamePoint := True;
          UserEngine.SaveHumanRcd(TPlayObject(m_PneumaObject));
          TPlayObject(m_PneumaObject).m_dwSaveRcdTick := GetTickCount;
      end;
      UserEngine.SaveHumanRcd(Self);
      m_dwSaveRcdTick := GetTickCount;
      end;
      Exit;
    end;

    if ProcessUserCmd(sCmd, sParam1, sParam2, sParam3, sParam4, sParam5, sParam6, sParam7) then Exit;

    //新密码命令
    if CompareText(sCmd, g_GameCommand.PASSWORDLOCK.sCmd) = 0 then begin
      if not g_Config.boPasswordLockSystem then begin
      SysMsg(g_sNoPasswordLockSystemMsg, c_Red, t_Hint);
      //游戏密码保护系统还没有启用!!!
      Exit;
      end;
      if m_sStoragePwd = '' then begin
      SendMsg(Self, RM_PASSWORD, 0, 0, 0, 0, '');
      m_boSetStoragePwd := True;
      SysMsg(g_sSetPasswordMsg, c_Green, t_Hint);
      //请输入一个长度为 4 - 7 位的仓库密码:
      Exit;
      end;
      if m_btPwdFailCount > 3 then begin
      SysMsg(g_sStoragePasswordLockedMsg, c_Red, t_Hint);
      m_boPasswordLocked := True;
      Exit;
      end;
      if m_sStoragePwd <> '' then begin
      SendMsg(Self, RM_PASSWORD, 0, 0, 0, 0, '');
      m_boCheckOldPwd := True;
      SysMsg(g_sPleaseInputOldPasswordMsg, c_Green, t_Hint);
      Exit;
      end;
      Exit;
    end;

    //新密码命令
    if CompareText(sCmd, g_GameCommand.SETPASSWORD.sCmd) = 0 then begin
      if not g_Config.boPasswordLockSystem then begin
      SysMsg(g_sNoPasswordLockSystemMsg, c_Red, t_Hint);
      Exit;
      end;
      if m_sStoragePwd = '' then begin
      SendMsg(Self, RM_PASSWORD, 0, 0, 0, 0, '');
      m_boSetStoragePwd := True;
      SysMsg(g_sSetPasswordMsg, c_Green, t_Hint);
      end else begin
      SysMsg(g_sAlreadySetPasswordMsg, c_Red, t_Hint);
      end;
      Exit;
    end;

    //取消密码
    if CompareText(sCmd, g_GameCommand.UNPASSWORD.sCmd) = 0 then begin
      if not g_Config.boPasswordLockSystem then begin
      SysMsg(g_sNoPasswordLockSystemMsg, c_Red, t_Hint);
      Exit;
      end;
      if not m_boPasswordLocked then begin
      m_sStoragePwd := '';
      SysMsg(g_sOldPasswordIsClearMsg, c_Green, t_Hint);
      end else begin
      SysMsg(g_sPleaseUnLockPasswordMsg, c_Red, t_Hint);
      end;
      Exit;
    end;

    //修改密码
    if CompareText(sCmd, g_GameCommand.CHGPASSWORD.sCmd) = 0 then begin
      if not g_Config.boPasswordLockSystem then begin
      SysMsg(g_sNoPasswordLockSystemMsg, c_Red, t_Hint);
      Exit;
      end;
      if m_btPwdFailCount > 3 then begin
      SysMsg(g_sStoragePasswordLockedMsg, c_Red, t_Hint);
      m_boPasswordLocked := True;
      Exit;
      end;
      if m_sStoragePwd <> '' then begin
      SendMsg(Self, RM_PASSWORD, 0, 0, 0, 0, '');
      m_boCheckOldPwd := True;
      SysMsg(g_sPleaseInputOldPasswordMsg, c_Green, t_Hint);
      end else begin
      SysMsg(g_sNoPasswordSetMsg, c_Red, t_Hint);
      end;
      Exit;
    end;

    //打开仓库
    if CompareText(sCmd, g_GameCommand.UNLOCKSTORAGE.sCmd) = 0 then begin
      if not g_Config.boPasswordLockSystem then begin
      SysMsg(g_sNoPasswordLockSystemMsg, c_Red, t_Hint);
      Exit;
      end;
      if m_btPwdFailCount > g_Config.nPasswordErrorCountLock {3} then begin
      SysMsg(g_sStoragePasswordLockedMsg, c_Red, t_Hint);
      m_boPasswordLocked := True;
      Exit;
      end;
      if m_sStoragePwd <> '' then begin
      if not m_boUnLockStoragePwd then begin
          SendMsg(Self, RM_PASSWORD, 0, 0, 0, 0, '');
          SysMsg(g_sPleaseInputUnLockPasswordMsg, c_Green, t_Hint);
          m_boUnLockStoragePwd := True;
      end else begin
          SysMsg(g_sStorageAlreadyUnLockMsg, c_Red, t_Hint);
      end;
      end else begin
      SysMsg(g_sStorageNoPasswordMsg, c_Red, t_Hint);
      end;
      Exit;
    end;
    //UnLock
    if CompareText(sCmd, g_GameCommand.UnLock.sCmd) = 0 then begin
      if not g_Config.boPasswordLockSystem then begin
      SysMsg(g_sNoPasswordLockSystemMsg, c_Red, t_Hint);
      Exit;
      end;
      if m_btPwdFailCount > g_Config.nPasswordErrorCountLock {3} then begin
      SysMsg(g_sStoragePasswordLockedMsg, c_Red, t_Hint);
      m_boPasswordLocked := True;
      Exit;
      end;
      if m_sStoragePwd <> '' then begin
      if not m_boUnLockPwd then begin
          SendMsg(Self, RM_PASSWORD, 0, 0, 0, 0, '');
          SysMsg(g_sPleaseInputUnLockPasswordMsg, c_Green, t_Hint);
          m_boUnLockPwd := True;
      end else begin
          SysMsg(g_sStorageAlreadyUnLockMsg, c_Red, t_Hint);
      end;
      end else begin
      SysMsg(g_sStorageNoPasswordMsg, c_Red, t_Hint);
      end;
      Exit;
    end;
    //Lock
    if CompareText(sCmd, g_GameCommand.Lock.sCmd) = 0 then begin
      if not g_Config.boPasswordLockSystem then begin
      SysMsg(g_sNoPasswordLockSystemMsg, c_Red, t_Hint);
      Exit;
      end;
      if not m_boPasswordLocked then begin
      if m_sStoragePwd <> '' then begin
          m_boPasswordLocked := True;
          m_boCanGetBackItem := False;
          SysMsg(g_sLockStorageSuccessMsg, c_Green, t_Hint);
      end else begin
          SysMsg(g_sStorageNoPasswordMsg, c_Green, t_Hint);
      end;
      end else begin
      SysMsg(g_sStorageAlreadyLockMsg, c_Red, t_Hint);
      end;
      Exit;
    end;

    if CompareText(sCmd, g_GameCommand.MEMBERFUNCTION.sCmd) = 0 then begin
      CmdMemberFunction(g_GameCommand.MEMBERFUNCTION.sCmd, sParam1);
      Exit;
    end;
    //MemberFuncEx
    if CompareText(sCmd, g_GameCommand.MEMBERFUNCTIONEX.sCmd) = 0 then begin
      CmdMemberFunctionEx(g_GameCommand.MEMBERFUNCTIONEX.sCmd, sParam1);
      Exit;
    end;

    if CompareText(sCmd, g_GameCommand.DEAR.sCmd) = 0 then begin
      CmdSearchDear(g_GameCommand.DEAR.sCmd, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.Master.sCmd) = 0 then begin
      CmdSearchMaster(g_GameCommand.Master.sCmd, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.MASTERECALL.sCmd) = 0 then begin
      CmdMasterRecall(g_GameCommand.MASTERECALL.sCmd, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.FRIENDRECALL.sCmd) = 0 then begin
      CmdFriendRecall(g_GameCommand.FRIENDRECALL.sCmd, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.DEARRECALL.sCmd) = 0 then begin
      CmdDearRecall(g_GameCommand.DEARRECALL.sCmd, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.ALLOWDEARRCALL.sCmd) = 0 then begin
      m_boCanDearRecall := not m_boCanDearRecall;
      if m_boCanDearRecall then begin
      SysMsg(g_sEnableDearRecall {'允许夫妻传送!!!'}, c_Blue,
          t_Hint);
      end else begin
      SysMsg(g_sDisableDearRecall {'禁止夫妻传送!!!'}, c_Blue,
          t_Hint);
      end;
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.ALLOWMASTERRECALL.sCmd) = 0 then begin
      m_boCanMasterRecall := not m_boCanMasterRecall;
      if m_boCanMasterRecall then begin
      SysMsg(g_sEnableMasterRecall {'允许师徒传送!!!'}, c_Blue,
          t_Hint);
      end else begin
      SysMsg(g_sDisableMasterRecall {'禁止师徒传送!!!'}, c_Blue,
          t_Hint);
      end;
      Exit;
    end;

    if CompareText(sCmd, g_GameCommand.Data.sCmd) = 0 then begin
      SysMsg(g_sNowCurrDateTime {'当前日期时间: '} +
      FormatDateTime('dddddd,dddd,hh:mm:nn', Now), c_Blue, t_Hint);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.PRVMSG.sCmd) = 0 then begin
      CmdPrvMsg(g_GameCommand.PRVMSG.sCmd, g_GameCommand.PRVMSG.nPermissionMin,
      sParam1);
      Exit;
    end;

    if CompareText(sCmd, g_GameCommand.AllowAddFriend.sCmd) = 0 then begin
      m_boAllowAddFriend := not m_boAllowAddFriend;
      if m_boAllowAddFriend then
      SysMsg(sHint9, c_Green, t_Hint)
      else
      SysMsg(sHint10, c_Green, t_Hint);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.ALLOWMSG.sCmd) = 0 then begin
      m_boHearWhisper := not m_boHearWhisper;
      if m_boHearWhisper then
      SysMsg(g_sEnableHearWhisper {'[允许私聊]'}, c_Green, t_Hint)
      else SysMsg(g_sDisableHearWhisper {'[禁止私聊]'}, c_Green, t_Hint);
      Exit;
    end;

    if CompareText(sCmd, g_GameCommand.LETSHOUT.sCmd) = 0 then begin
      m_boBanShout := not m_boBanShout;
      if m_boBanShout then
      SysMsg(g_sEnableShoutMsg {'[允许群聊]'}, c_Green, t_Hint)
      else SysMsg(g_sDisableShoutMsg {'[禁止群聊]'}, c_Green, t_Hint);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.LETTRADE.sCmd) = 0 then begin
      m_boAllowDeal := not m_boAllowDeal;
      if m_boAllowDeal then
      SysMsg(g_sEnableDealMsg {'[允许交易]'}, c_Green, t_Hint)
      else SysMsg(g_sDisableDealMsg {'[禁止交易]'}, c_Green, t_Hint);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.BANGUILDCHAT.sCmd) = 0 then begin
      m_boBanGuildChat := not m_boBanGuildChat;
      if m_boBanGuildChat then
      SysMsg(g_sEnableGuildChat {'[允许行会聊天]'}, c_Green, t_Hint)
      else
      SysMsg(g_sDisableGuildChat {'[禁止行会聊天]'}, c_Green, t_Hint);
      Exit;
    end;

    if CompareText(sCmd, g_GameCommand.LETGUILD.sCmd) = 0 then begin
      m_boAllowGuild := not m_boAllowGuild;
      if m_boAllowGuild then
      SysMsg(g_sEnableJoinGuild {'[允许加入行会]'}, c_Green, t_Hint)
      else
      SysMsg(g_sDisableJoinGuild {'[禁止加入行会]'}, c_Green, t_Hint);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.ENDGUILD.sCmd) = 0 then begin
      CmdEndGuild();
      Exit;
    end;

    if CompareText(sCmd, g_GameCommand.AUTHALLY.sCmd) = 0 then begin
      if IsGuildMaster then begin
      TGuild(m_MyGuild).m_boEnableAuthAlly := not TGuild(m_MyGuild).m_boEnableAuthAlly;
      if TGuild(m_MyGuild).m_boEnableAuthAlly then
          SysMsg(g_sEnableAuthAllyGuild {'[允许行会联盟]'}, c_Green, t_Hint)
      else
          SysMsg(g_sDisableAuthAllyGuild {'[禁止行会联盟]'}, c_Green, t_Hint);
      end;
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.ALLOWGROUPCALL.sCmd) = 0 then begin
      CmdAllowGroupReCall(sCmd, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.GROUPRECALLL.sCmd) = 0 then begin
      CmdGroupRecall(g_GameCommand.GROUPRECALLL.sCmd);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.ALLOWGUILDRECALL.sCmd) = 0 then begin
      m_boAllowGuildReCall := not m_boAllowGuildReCall;
      if m_boAllowGuildReCall then
      SysMsg(g_sEnableGuildRecall {'[允许行会合一]'}, c_Green, t_Hint)
      else
      SysMsg(g_sDisableGuildRecall {'[禁止行会合一]'}, c_Green, t_Hint);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.GUILDRECALLL.sCmd) = 0 then begin
      CmdGuildRecall(g_GameCommand.GUILDRECALLL.sCmd, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.AUTH.sCmd) = 0 then begin
      if IsGuildMaster then ClientGuildAlly();
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.AUTHCANCEL.sCmd) = 0 then begin
      if IsGuildMaster then ClientGuildBreakAlly(sParam1);
      Exit;
    end;

    if CompareText(sCmd, g_GameCommand.DIARY.sCmd) = 0 then begin
      CmdViewDiary(g_GameCommand.DIARY.sCmd, Str_ToInt(sParam1, 0));
      Exit;
    end;

    if CompareText(sCmd, g_GameCommand.ATTACKMODE.sCmd) = 0 then begin
      CmdChangeAttackMode(Str_ToInt(sParam1, -1));
      Exit;
    end;

    if CompareText(sCmd, g_GameCommand.REST.sCmd) = 0 then begin
      CmdChangeSalveStatus();
      Exit;
    end;

    if CompareText(sCmd, g_GameCommand.TIGGERREST.sCmd) = 0 then begin
      CmdChangeTigerStatus();
      Exit;
    end;

    if CompareText(sCmd, g_GameCommand.TAKEONHORSE.sCmd) = 0 then begin
      CmdTakeOnHorse(sCmd, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.TAKEOFHORSE.sCmd) = 0 then begin
      CmdTakeOffHorse(sCmd, sParam1);
      Exit;
    end;

    if CompareText(sCmd, g_GameCommand.TESTGA.sCmd) = 0 then begin
      Exit;
      SendMsg(Self, RM_PASSWORD, 0, 0, 0, 0, '');
      SysMsg(g_sPleaseInputPassword {'请输入密码:'}, c_Green, t_Hint);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.MAPINFO.sCmd) = 0 then begin
      ShowMapInfo(sParam1, sParam2, sParam3);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.CLEARBAG.sCmd) = 0 then begin
      CmdClearBagItem(@g_GameCommand.CLEARBAG, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SHOWUSEITEMINFO.sCmd) = 0 then begin
      CmdShowUseItemInfo(@g_GameCommand.SHOWUSEITEMINFO, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.BINDUSEITEM.sCmd) = 0 then begin
      CmdBindUseItem(@g_GameCommand.BINDUSEITEM, sParam1, sParam2, sParam3);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SBKDOOR.sCmd) = 0 then begin                                 //004D2610
      CmdSbkDoorControl(g_GameCommand.SBKDOOR.sCmd, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.USERMOVE.sCmd) = 0 then begin
      CmdUserMoveXY(g_GameCommand.USERMOVE.sCmd, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SEARCHING.sCmd) = 0 then begin
      CmdSearchHuman(g_GameCommand.SEARCHING.sCmd, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.LOCKLOGON.sCmd) = 0 then begin
      CmdLockLogin(@g_GameCommand.LOCKLOGON);
      Exit;
    end;
    if (m_btPermissionGM >= 2) and (Length(sData) > 2) then begin
      if (m_btPermissionGM >= 6) and (sData = g_GMRedMsgCmd) then begin

      if GetTickCount - m_dwSayMsgTick > 2000 then begin
          m_dwSayMsgTick := GetTickCount();
          sData := Copy(sData, 3, Length(sData) - 2);
          if Length(sData) > g_Config.nSayRedMsgMaxLen then begin
            sData := Copy(sData, 1, g_Config.nSayRedMsgMaxLen);
          end;

          if g_Config.boShutRedMsgShowGMName then
            SC := m_sCharName + ': ' + sData
          else SC := sData;
          UserEngine.SendBroadCastMsgExt(SC, t_GM);
      end;
      Exit;
      end;
    end;
    //004D2C70   HumanLocal
    if CompareText(sCmd, g_GameCommand.HUMANLOCAL.sCmd) = 0 then begin
      CmdHumanLocal(@g_GameCommand.HUMANLOCAL, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.Move.sCmd) = 0 then begin
      CmdMapMove(@g_GameCommand.Move, sParam1);
      Exit;
    end;                                                                                          //004D2CD0
    if CompareText(sCmd, g_GameCommand.POSITIONMOVE.sCmd) = 0 then begin
      CmdPositionMove(@g_GameCommand.POSITIONMOVE, sParam1, sParam2, sParam3);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.info.sCmd) = 0 then begin
      CmdHumanInfo(@g_GameCommand.info, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.MOBLEVEL.sCmd) = 0 then begin
      CmdMobLevel(@g_GameCommand.MOBLEVEL, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.MOBCOUNT.sCmd) = 0 then begin
      CmdMobCount(@g_GameCommand.MOBCOUNT, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.HUMANCOUNT.sCmd) = 0 then begin
      CmdHumanCount(@g_GameCommand.HUMANCOUNT, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.KICK.sCmd) = 0 then begin
      CmdKickHuman(@g_GameCommand.KICK, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.TING.sCmd) = 0 then begin
      CmdTing(@g_GameCommand.TING, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SUPERTING.sCmd) = 0 then begin
      CmdSuperTing(@g_GameCommand.SUPERTING, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.MAPMOVE.sCmd) = 0 then begin
      CmdMapMoveHuman(@g_GameCommand.MAPMOVE, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SHUTUP.sCmd) = 0 then begin
      CmdShutup(@g_GameCommand.SHUTUP, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.Map.sCmd) = 0 then begin
      CmdShowMapInfo(@g_GameCommand.Map, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.RELEASESHUTUP.sCmd) = 0 then begin
      CmdShutupRelease(@g_GameCommand.RELEASESHUTUP, sParam1, True);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SHUTUPLIST.sCmd) = 0 then begin
      CmdShutupList(@g_GameCommand.SHUTUPLIST, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.GAMEMASTER.sCmd) = 0 then begin
      CmdChangeAdminMode(g_GameCommand.GAMEMASTER.sCmd,
      g_GameCommand.GAMEMASTER.nPermissionMin, sParam1, not m_boAdminMode);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.OBSERVER.sCmd) = 0 then begin
      CmdChangeObMode(g_GameCommand.OBSERVER.sCmd,
      g_GameCommand.OBSERVER.nPermissionMin, sParam1, not m_boObMode);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SUEPRMAN.sCmd) = 0 then begin
      CmdChangeSuperManMode(g_GameCommand.OBSERVER.sCmd,
      g_GameCommand.OBSERVER.nPermissionMin, sParam1, not m_boSuperMan);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.level.sCmd) = 0 then begin
      CmdChangeLevel(@g_GameCommand.level, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SABUKWALLGOLD.sCmd) = 0 then begin
      CmdShowSbkGold(@g_GameCommand.SABUKWALLGOLD, sParam1, sParam2, sParam3);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.RECALL.sCmd) = 0 then begin
      CmdRecallHuman(@g_GameCommand.RECALL, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.REGOTO.sCmd) = 0 then begin
      CmdReGotoHuman(@g_GameCommand.REGOTO, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SHOWFLAG.sCmd) = 0 then begin
      CmdShowHumanFlag(g_GameCommand.SHOWFLAG.sCmd,
      g_GameCommand.SHOWFLAG.nPermissionMin, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SHOWOPEN.sCmd) = 0 then begin
      CmdShowHumanUnitOpen(g_GameCommand.SHOWOPEN.sCmd,
      g_GameCommand.SHOWOPEN.nPermissionMin, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SHOWUNIT.sCmd) = 0 then begin
      CmdShowHumanUnit(g_GameCommand.SHOWUNIT.sCmd,
      g_GameCommand.SHOWUNIT.nPermissionMin, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.Attack.sCmd) = 0 then begin
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.MOB.sCmd) = 0 then begin
      CmdMob(@g_GameCommand.MOB, sParam1, Str_ToInt(sParam2, 0),
      Str_ToInt(sParam3, 0), sParam4);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.MOBNPC.sCmd) = 0 then begin
      CmdMobNpc(g_GameCommand.MOBNPC.sCmd, g_GameCommand.MOBNPC.nPermissionMin,
      sParam1, sParam2, sParam3, sParam4);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.NPCSCRIPT.sCmd) = 0 then begin
      CmdNpcScript(g_GameCommand.NPCSCRIPT.sCmd,
      g_GameCommand.NPCSCRIPT.nPermissionMin, sParam1, sParam2, sParam3);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.DELNPC.sCmd) = 0 then begin
      CmdDelNpc(g_GameCommand.DELNPC.sCmd, g_GameCommand.DELNPC.nPermissionMin,
      sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.RECALLMOB.sCmd) = 0 then begin
      CmdRecallMob(@g_GameCommand.RECALLMOB, sParam1, Str_ToInt(sParam2, 0),
      Str_ToInt(sParam3, 0), Str_ToInt(sParam4, 0), Str_ToInt(sParam5, 0));
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.LUCKYPOINT.sCmd) = 0 then begin
      CmdLuckPoint(g_GameCommand.LUCKYPOINT.sCmd,
      g_GameCommand.LUCKYPOINT.nPermissionMin, sParam1, sParam2, sParam3);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.LOTTERYTICKET.sCmd) = 0 then begin
      CmdLotteryTicket(g_GameCommand.LOTTERYTICKET.sCmd,
      g_GameCommand.LOTTERYTICKET.nPermissionMin, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.RELOADGUILD.sCmd) = 0 then begin
      CmdReloadGuild(g_GameCommand.RELOADGUILD.sCmd,
      g_GameCommand.RELOADGUILD.nPermissionMin, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.RELOADLINENOTICE.sCmd) = 0 then begin
      CmdReloadLineNotice(g_GameCommand.RELOADLINENOTICE.sCmd,
      g_GameCommand.RELOADLINENOTICE.nPermissionMin, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.RELOADABUSE.sCmd) = 0 then begin
      CmdReloadAbuse(g_GameCommand.RELOADABUSE.sCmd,
      g_GameCommand.RELOADABUSE.nPermissionMin, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.FREEPENALTY.sCmd) = 0 then begin
      CmdFreePenalty(@g_GameCommand.FREEPENALTY, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.PKPOINT.sCmd) = 0 then begin
      CmdPKpoint(@g_GameCommand.PKPOINT, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.IncPkPoint.sCmd) = 0 then begin
      CmdIncPkPoint(@g_GameCommand.IncPkPoint, sParam1, Str_ToInt(sParam2, 0));
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.MAKE.sCmd) = 0 then begin
      CmdMakeItem(@g_GameCommand.MAKE, sParam1, Str_ToInt(sParam2, 0));
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.VIEWWHISPER.sCmd) = 0 then begin
      CmdViewWhisper(@g_GameCommand.VIEWWHISPER, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.ReAlive.sCmd) = 0 then begin
      CmdReAlive(@g_GameCommand.ReAlive, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.KILL.sCmd) = 0 then begin
      CmdKill(@g_GameCommand.KILL, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SMAKE.sCmd) = 0 then begin
      CmdSmakeItem(@g_GameCommand.SMAKE, Str_ToInt(sParam1, 0),
      Str_ToInt(sParam2, 0), sParam3, Str_ToInt(sParam4, 0));
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.CHANGEJOB.sCmd) = 0 then begin
      CmdChangeJob(@g_GameCommand.CHANGEJOB, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.CHANGEGENDER.sCmd) = 0 then begin
      CmdChangeGender(@g_GameCommand.CHANGEGENDER, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.HAIR.sCmd) = 0 then begin
      CmdHair(@g_GameCommand.HAIR, sParam1, Str_ToInt(sParam2, 0));
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.BonusPoint.sCmd) = 0 then begin
      CmdBonuPoint(@g_GameCommand.BonusPoint, sParam1, Str_ToInt(sParam2, 0));
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.DELBONUSPOINT.sCmd) = 0 then begin
      CmdDelBonuPoint(@g_GameCommand.DELBONUSPOINT, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.RESTBONUSPOINT.sCmd) = 0 then begin
      CmdRestBonuPoint(@g_GameCommand.RESTBONUSPOINT, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SETPERMISSION.sCmd) = 0 then begin
      CmdSetPermission(@g_GameCommand.SETPERMISSION, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.RENEWLEVEL.sCmd) = 0 then begin
      CmdReNewLevel(@g_GameCommand.RENEWLEVEL, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.DELGOLD.sCmd) = 0 then begin
      CmdDelGold(@g_GameCommand.DELGOLD, sParam1, Str_ToInt(sParam2, 0));
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.ADDGOLD.sCmd) = 0 then begin
      CmdAddGold(@g_GameCommand.ADDGOLD, sParam1, Str_ToInt(sParam2, 0));
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.GAMEGOLD.sCmd) = 0 then begin
      CmdGameGold(@g_GameCommand.GAMEGOLD, sParam1, sParam2, Str_ToInt(sParam3, 0));
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.GAMEPOINT.sCmd) = 0 then begin
      CmdGamePoint(@g_GameCommand.GAMEPOINT, sParam1, sParam2,
      Str_ToInt(sParam3, 0));
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.CREDITPOINT.sCmd) = 0 then begin
      CmdCreditPoint(@g_GameCommand.CREDITPOINT, sParam1, sParam2,
      Str_ToInt(sParam3, 0));
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.TRAINING.sCmd) = 0 then begin
      CmdTrainingSkill(@g_GameCommand.TRAINING, sParam1, sParam2,
      Str_ToInt(sParam3, 0));
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.DELETEITEM.sCmd) = 0 then begin
      CmdDeleteItem(@g_GameCommand.DELETEITEM, sParam1, sParam2,
      Str_ToInt(sParam3, 1));
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.DELETESKILL.sCmd) = 0 then begin
      CmdDelSkill(@g_GameCommand.DELETESKILL, sParam1, sParam2);
      Exit;
    end;                                                                                          //TrainingSkill
    if CompareText(sCmd, g_GameCommand.TRAININGSKILL.sCmd) = 0 then begin
      CmdTrainingMagic(@g_GameCommand.TRAININGSKILL, sParam1, sParam2,
      Str_ToInt(sParam3, 0));
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.CLEARMISSION.sCmd) = 0 then begin
      CmdClearMission(@g_GameCommand.CLEARMISSION, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.STARTQUEST.sCmd) = 0 then begin
      CmdStartQuest(@g_GameCommand.STARTQUEST, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.DENYIPLOGON.sCmd) = 0 then begin
      CmdDenyIPaddrLogon(@g_GameCommand.DENYIPLOGON, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.CHANGEDEARNAME.sCmd) = 0 then begin
      CmdChangeDearName(@g_GameCommand.CHANGEDEARNAME, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.ChangeMasterName.sCmd) = 0 then begin
      CmdChangeMasterName(@g_GameCommand.ChangeMasterName, sParam1, sParam2,
      sParam3);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.CLEARMON.sCmd) = 0 then begin
      CmdClearMapMonster(@g_GameCommand.CLEARMON, sParam1, sParam2, sParam3,
      sParam4);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.DENYACCOUNTLOGON.sCmd) = 0 then begin
      CmdDenyAccountLogon(@g_GameCommand.DENYACCOUNTLOGON, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.DENYCHARNAMELOGON.sCmd) = 0 then begin
      CmdDenyCharNameLogon(@g_GameCommand.DENYCHARNAMELOGON, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.DELDENYIPLOGON.sCmd) = 0 then begin
      CmdDelDenyIPaddrLogon(@g_GameCommand.DELDENYIPLOGON, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.DELDENYACCOUNTLOGON.sCmd) = 0 then begin
      CmdDelDenyAccountLogon(@g_GameCommand.DELDENYACCOUNTLOGON, sParam1,
      sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.DELDENYCHARNAMELOGON.sCmd) = 0 then begin
      CmdDelDenyCharNameLogon(@g_GameCommand.DELDENYCHARNAMELOGON, sParam1,
      sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SHOWDENYIPLOGON.sCmd) = 0 then begin
      CmdShowDenyIPaddrLogon(@g_GameCommand.SHOWDENYIPLOGON, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SHOWDENYACCOUNTLOGON.sCmd) = 0 then begin
      CmdShowDenyAccountLogon(@g_GameCommand.SHOWDENYACCOUNTLOGON, sParam1,
      sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SHOWDENYCHARNAMELOGON.sCmd) = 0 then begin
      CmdShowDenyCharNameLogon(@g_GameCommand.SHOWDENYCHARNAMELOGON, sParam1,
      sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.Mission.sCmd) = 0 then begin
      CmdMission(@g_GameCommand.Mission, sParam1, sParam2);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.MobPlace.sCmd) = 0 then begin
      CmdMobPlace(@g_GameCommand.MobPlace, sParam1, sParam2, sParam3, sParam4);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SetMapMode.sCmd) = 0 then begin
      CmdSetMapMode(g_GameCommand.SetMapMode.sCmd, sParam1, sParam2, sParam3,
      sParam4);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.SHOWMAPMODE.sCmd) = 0 then begin
      CmdShowMapMode(g_GameCommand.SHOWMAPMODE.sCmd, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.CLRPASSWORD.sCmd) = 0 then begin
      CmdClearHumanPassword(g_GameCommand.CLRPASSWORD.sCmd,
      g_GameCommand.CLRPASSWORD.nPermissionMin, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.CONTESTPOINT.sCmd) = 0 then begin
      CmdContestPoint(@g_GameCommand.CONTESTPOINT, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.STARTCONTEST.sCmd) = 0 then begin
      CmdStartContest(@g_GameCommand.STARTCONTEST, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.ENDCONTEST.sCmd) = 0 then begin
      CmdEndContest(@g_GameCommand.ENDCONTEST, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.ANNOUNCEMENT.sCmd) = 0 then begin
      CmdAnnouncement(@g_GameCommand.ANNOUNCEMENT, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.DISABLESENDMSG.sCmd) = 0 then begin
      CmdDisableSendMsg(@g_GameCommand.DISABLESENDMSG, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.ENABLESENDMSG.sCmd) = 0 then begin
      CmdEnableSendMsg(@g_GameCommand.ENABLESENDMSG, sParam1);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.REFINEWEAPON.sCmd) = 0 then begin
      CmdRefineWeapon(@g_GameCommand.REFINEWEAPON, Str_ToInt(sParam1, 0),
      Str_ToInt(sParam2, 0), Str_ToInt(sParam3, 0), Str_ToInt(sParam4, 0));
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.DISABLESENDMSGLIST.sCmd) = 0 then begin
      CmdDisableSendMsgList(@g_GameCommand.DISABLESENDMSGLIST);
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.BINDGOLD.sCmd) = 0 then begin
      CmdBindGold(@g_GameCommand.BINDGOLD, sParam1, sParam2, Str_ToInt(sParam3, 0));
      Exit;
    end;
    if CompareText(sCmd, g_GameCommand.BINDGAMEGOLD.sCmd) = 0 then begin
      CmdBindGameGold(@g_GameCommand.BINDGAMEGOLD, sParam1, sParam2, Str_ToInt(sParam3, 0));
      Exit;
    end;
    if m_btPermissionGM > 4 then begin
      if CompareText(sCmd, g_GameCommand.BACKSTEP.sCmd) = 0 then begin
      CmdBackStep(sCmd, Str_ToInt(sParam1, 0), Str_ToInt(sParam2, 1));
      Exit;
      end;
      if CompareText(sCmd, g_GameCommand.BALL.sCmd) = 0 then begin                                  //精神波
      Exit;
      end;

      if CompareText(sCmd, g_GameCommand.CHANGELUCK.sCmd) = 0 then begin
      Exit;
      end;
      if CompareText(sCmd, g_GameCommand.HUNGER.sCmd) = 0 then begin
      CmdHunger(g_GameCommand.HUNGER.sCmd, sParam1, Str_ToInt(sParam2, 0));
      Exit;
      end;

      if CompareText(sCmd, g_GameCommand.NameColor.sCmd) = 0 then begin
      Exit;
      end;

      if CompareText(sCmd, g_GameCommand.TRANSPARECY.sCmd) = 0 then begin
      Exit;
      end;
      if CompareText(sCmd, g_GameCommand.LEVEL0.sCmd) = 0 then begin
      Exit;
      end;

      if CompareText(sCmd, g_GameCommand.SETFLAG.sCmd) = 0 then begin
      PlayObject := UserEngine.GetPlayObject(sParam1);
      if PlayObject <> nil then begin
          nFlag := Str_ToInt(sParam2, 0);
          dwValue := Str_ToInt(sParam3, 0);
          PlayObject.SetQuestFlagStatus(nFlag, dwValue);
          if PlayObject.GetQuestFalgStatus(nFlag) = 1 then begin
            SysMsg(PlayObject.m_sCharName + ': [' + IntToStr(nFlag) + '] = ON', c_Green, t_Hint);
          end else begin
            SysMsg(PlayObject.m_sCharName + ': [' + IntToStr(nFlag) + '] = OFF', c_Green, t_Hint);
          end;
      end else begin
          SysMsg('@' + g_GameCommand.SETFLAG.sCmd + sHint11, c_Red, t_Hint);
      end;
      Exit;
      end;
      if CompareText(sCmd, g_GameCommand.SETOPEN.sCmd) = 0 then begin
      PlayObject := UserEngine.GetPlayObject(sParam1);
      if PlayObject <> nil then begin
          nFlag := Str_ToInt(sParam2, 0);
          dwValue := Str_ToInt(sParam3, 0);
          PlayObject.SetQuestUnitOpenStatus(nFlag, dwValue);
          if PlayObject.GetQuestUnitOpenStatus(nFlag) = 1 then begin
            SysMsg(PlayObject.m_sCharName + ': [' + IntToStr(nFlag) + '] = ON', c_Green, t_Hint);
          end else begin
            SysMsg(PlayObject.m_sCharName + ': [' + IntToStr(nFlag) + '] = OFF', c_Green, t_Hint);
          end;
      end else begin
          SysMsg('@' + g_GameCommand.SETOPEN.sCmd + sHint11, c_Red, t_Hint);
      end;
      Exit;
      end;
      if CompareText(sCmd, g_GameCommand.SETUNIT.sCmd) = 0 then begin
      PlayObject := UserEngine.GetPlayObject(sParam1);
      if PlayObject <> nil then begin
          nFlag := Str_ToInt(sParam2, 0);
          dwValue := Str_ToInt(sParam3, 0);
          PlayObject.SetQuestUnitStatus(nFlag, dwValue);
          if PlayObject.GetQuestUnitStatus(nFlag) = 1 then begin
            SysMsg(PlayObject.m_sCharName + ': [' + IntToStr(nFlag) + '] = ON', c_Green, t_Hint);
          end else begin
            SysMsg(PlayObject.m_sCharName + ': [' + IntToStr(nFlag) + '] = OFF', c_Green, t_Hint);
          end;
      end else begin
          SysMsg('@' + g_GameCommand.SETUNIT.sCmd + sHint11, c_Red, t_Hint);
      end;
      Exit;
      end;
      if CompareText(sCmd, g_GameCommand.RECONNECTION.sCmd) = 0 then begin
      CmdReconnection(sCmd, sParam1, sParam2);
      Exit;
      end;
      if CompareText(sCmd, g_GameCommand.DISABLEFILTER.sCmd) = 0 then begin
      CmdDisableFilter(sCmd, sParam1);
      Exit;
      end;
      if CompareText(sCmd, g_GameCommand.CHGUSERFULL.sCmd) = 0 then begin
      CmdChangeUserFull(sCmd, sParam1);
      Exit;
      end;
      if CompareText(sCmd, g_GameCommand.CHGZENFASTSTEP.sCmd) = 0 then begin
      CmdChangeZenFastStep(sCmd, sParam1);
      Exit;
      end;
      if CompareText(sCmd, g_GameCommand.OXQUIZROOM.sCmd) = 0 then begin
      Exit;
      end;
      if CompareText(sCmd, g_GameCommand.GSA.sCmd) = 0 then begin
      Exit;
      end;
      if CompareText(sCmd, g_GameCommand.CHANGEITEMNAME.sCmd) = 0 then begin
      CmdChangeItemName(g_GameCommand.CHANGEITEMNAME.sCmd, sParam1, sParam2, sParam3);
      Exit;
      end;

      if (m_btPermissionGM >= 5) or (g_Config.boTestServer) then begin
      if CompareText(sCmd, g_GameCommand.FIREBURN.sCmd) = 0 then begin
          CmdFireBurn(Str_ToInt(sParam1, 0), Str_ToInt(sParam2, 0), Str_ToInt(sParam3, 0));
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.TESTFIRE.sCmd) = 0 then begin
          CmdTestFire(sCmd, Str_ToInt(sParam1, 0), Str_ToInt(sParam2, 0),
            Str_ToInt(sParam3, 0), Str_ToInt(sParam4, 0));
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.TESTSTATUS.sCmd) = 0 then begin
          CmdTestStatus(sCmd, Str_ToInt(sParam1, -1), Str_ToInt(sParam2, 0));
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.TESTGOLDCHANGE.sCmd) = 0 then begin
          Exit;
      end;

      if CompareText(sCmd, g_GameCommand.RELOADADMIN.sCmd) = 0 then begin
          CmdReLoadAdmin(g_GameCommand.RELOADADMIN.sCmd);
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.ReLoadNpc.sCmd) = 0 then begin
          CmdReloadNpc(sParam1);
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.RELOADMANAGE.sCmd) = 0 then begin
          CmdReloadManage(@g_GameCommand.RELOADMANAGE, sParam1);
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.RELOADROBOTMANAGE.sCmd) = 0 then begin
          CmdReloadRobotManage();
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.RELOADROBOT.sCmd) = 0 then begin
          CmdReloadRobot();
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.RELOADMONITEMS.sCmd) = 0 then begin
          CmdReloadMonItems();
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.RELOADDIARY.sCmd) = 0 then begin
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.RELOADITEMDB.sCmd) = 0 then begin
          FrmDB.LoadItemsDB();
          SysMsg(sHint12, c_Green, t_Hint);
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.RELOADMAGICDB.sCmd) = 0 then begin
          FrmDB.LoadMagicDB();
          SysMsg('魔法数据库重新加载完成。', c_Green, t_Hint);
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.RELOADMONSTERDB.sCmd) = 0 then begin
          FrmDB.LoadMonsterDB();
          SysMsg(sHint13, c_Green, t_Hint);
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.RELOADMINMAP.sCmd) = 0 then begin
          FrmDB.LoadMinMap();
          g_MapManager.ReSetMinMap();
          SysMsg(sHint14, c_Green, t_Hint);
          Exit;
      end;

      if CompareText(sCmd, g_GameCommand.ADJUESTLEVEL.sCmd) = 0 then begin
          CmdAdjuestLevel(@g_GameCommand.ADJUESTLEVEL, sParam1,
            Str_ToInt(sParam2, 1));
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.ADJUESTEXP.sCmd) = 0 then begin
          CmdAdjuestExp(@g_GameCommand.ADJUESTEXP, sParam1, sParam2);
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.AddGuild.sCmd) = 0 then begin
          CmdAddGuild(@g_GameCommand.AddGuild, sParam1, sParam2);
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.DelGuild.sCmd) = 0 then begin
          CmdDelGuild(@g_GameCommand.DelGuild, sParam1);
          Exit;
      end;
      if (CompareText(sCmd, g_GameCommand.CHANGESABUKLORD.sCmd) = 0) then begin
          CmdChangeSabukLord(@g_GameCommand.CHANGESABUKLORD, sParam1, sParam2,
            True);
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.FORCEDWALLCONQUESTWAR.sCmd) = 0 then begin
          CmdForcedWallconquestWar(@g_GameCommand.FORCEDWALLCONQUESTWAR, sParam1);
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.ADDTOITEMEVENT.sCmd) = 0 then begin
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.ADDTOITEMEVENTASPIECES.sCmd) = 0 then begin
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.ItemEventList.sCmd) = 0 then begin
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.STARTINGGIFTNO.sCmd) = 0 then begin
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.DELETEALLITEMEVENT.sCmd) = 0 then begin
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.STARTITEMEVENT.sCmd) = 0 then begin
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.ITEMEVENTTERM.sCmd) = 0 then begin
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.ADJUESTTESTLEVEL.sCmd) = 0 then begin
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.OPDELETESKILL.sCmd) = 0 then begin
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.CHANGEWEAPONDURA.sCmd) = 0 then begin
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.RELOADGUILDALL.sCmd) = 0 then begin
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.SPIRIT.sCmd) = 0 then begin
          CmdSpirtStart(g_GameCommand.SPIRIT.sCmd, sParam1);
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.SPIRITSTOP.sCmd) = 0 then begin
          CmdSpirtStop(g_GameCommand.SPIRITSTOP.sCmd, sParam1);
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.TESTGETBAGITEM.sCmd) = 0 then begin
          CmdTestGetBagItems(@g_GameCommand.TESTGETBAGITEM, sParam1);
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.MOBFIREBURN.sCmd) = 0 then begin
          CmdMobFireBurn(@g_GameCommand.MOBFIREBURN, sParam1, sParam2, sParam3, sParam4, sParam5, sParam6);
          Exit;
      end;
      if CompareText(sCmd, g_GameCommand.TESTSPEEDMODE.sCmd) = 0 then begin
          CmdTestSpeedMode(@g_GameCommand.TESTSPEEDMODE, Str_ToInt(sParam1, 0), Str_ToInt(sParam2, 0));
          Exit;
      end;
      end;
    end;                                                                                          //004D52B5
    SysMsg('@' + sCmd + sHint15, c_Red, t_Hint);
except
    on E: Exception do begin
      MainOutMessage(Format(sExceptionMsg, ));
      MainOutMessage(E.Message);
    end;
end;
end;

//刷新人物附加属性

procedure TPlayObject.QuerySubAbility;
begin
if Assigned(m_VersionManage) then
try
    m_VersionManage.OnQuerySubAbility(Self);
except
    MainOutMessage(Format('TPlayObject::OnQuerySubAbility SoftVersionDate:%d', ));
end;
end;

function TPlayObject.QuestCheckItem(sItemName: string; var nCount,
nParam: Integer; var nDura: Integer): pTUserItem;
var
i                                     : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
begin
Result := nil;
nParam := 0;
nDura := 0;
nCount := 0;
for i := 0 to m_ItemList.Count - 1 do begin
    UserItem := m_ItemList.Items;
    StdItem := UserEngine.GetStdItem(UserItem.wIndex);
    if (StdItem <> nil) then begin
      if CompareText(StdItem.Name, sItemName) = 0 then begin
      if UserItem.Dura > nDura then begin
          nDura := UserItem.Dura;
          Result := UserItem;
      end;
      Inc(nParam, UserItem.Dura);
      if Result = nil then
          Result := UserItem;
      if CheckSPCode(StdItem.Reserved, RE_ALLOWPILE) then
          Inc(nCount, UserItem.Dura)
      else
          Inc(nCount);
      end;
    end;
end;
end;

function TPlayObject.QuestCheckItemEx(sItemName: string; nDura: Integer; boParam: Boolean):
Integer;
var
i                                     : Integer;
UserItem                              : pTUserItem;
s1C                                 : string;
begin
Result := 0;
for i := 0 to m_ItemList.Count - 1 do begin
    UserItem := m_ItemList.Items;
    s1C := UserEngine.GetStdItemName(UserItem.wIndex);
    if CompareText(s1C, sItemName) = 0 then begin
      if (UserItem.Dura >= nDura) and (boParam = False) then begin
      Inc(Result);
      end;
      if (UserItem.Dura = nDura) and (boParam = True) then begin
      Inc(Result);
      end;
    end;
end;
end;

function TPlayObject.QuestCheckItemX(sItemName: string; var nCount,
nParam: Integer; var nDura: Integer): pTUserItem;                                                 //004C4B78
var
i                                     : Integer;
UserItem                              : pTUserItem;
s1C                                 : string;
begin
Result := nil;
if m_nStoreMakeIndex = 0 then Exit;
nParam := 0;
nDura := 0;
nCount := 0;
for i := 0 to m_ItemList.Count - 1 do begin
    UserItem := m_ItemList.Items;
    if UserItem.MakeIndex = m_nStoreMakeIndex then begin
      if UserItem.Dura > nDura then begin
      nDura := UserItem.Dura;
      Result := UserItem;
      Inc(nCount);
      Break;
      end;
    end;
end;
end;

function TPlayObject.QuestTakeCheckItem(CheckItem: pTUserItem): Boolean;
//004C4F6C
var
i                                     : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
begin
Result := False;
for i := m_ItemList.Count - 1 downto 0 do begin
    UserItem := m_ItemList.Items;
    if UserItem = CheckItem then begin
      SendDelItems(UserItem);
      Dispose(UserItem);
      m_ItemList.Delete(i);
      Result := True;
      Break;
    end;
end;
for i := Low(m_UseItems) to High(m_UseItems) do begin
    if @m_UseItems = CheckItem then begin
      StdItem := UserEngine.GetStdItem(m_UseItems.wIndex);
      if StdItem = nil then Continue;
      SendDelItems(@m_UseItems);
      m_UseItems.wIndex := 0;
      //取下装备触发脚本
      m_sScriptParam := StdItem.Name;
      m_sScriptParam := StdItem.FilterName;
      ExecuteScript(g_FunctionNPC, '@TakeOff' + IntToStr(i));
      Result := True;
      Break;
    end;
end;
end;

procedure TPlayObject.ReadAllBook();
var
i                                     : Integer;
Magic                                 : pTMagic;
begin
for i := 0 to UserEngine.m_MagicList.Count - 1 do begin
    Magic := UserEngine.m_MagicList.Items;
    AddItemSkill(Magic, 2, 0, 100000);
end;
end;

procedure TPlayObject.RecalcAbilitys(boAction: Boolean = False);
begin
      FillChar(m_ExemptHurt, SizeOf(m_ExemptHurt), 0);
inherited RecalcAbilitys(boAction);
m_nAllIncReply := 0;

RecalcAdjusBonus();
RecalcAdditionalAbil();                                                                           //元婴附加属性

SendUpdateMsg(Self, RM_CHARSTATUSCHANGED, m_nHitSpeed, m_nCharStatus, 0, 0, GetCharStatusMsg);
end;

procedure TPlayObject.RecalcAbilitysEx();
begin
inherited;
RecalcAddProvisionalAbil();                                                                     //脚本增加的人物临时属性
RecalcAddInosculatePneumaAbil();                                                                  //融合元神附加属性
RecalcMentalLevelAbilitys;                                                                        //天元心法附加属性
RecalcAddPetAbil;                                                                                 //灵兽附加属性
end;

//元婴附加属性

procedure TPlayObject.RecalcAdditionalAbil();
begin
if not m_boPneuma then begin
    m_WAbil.DC := MakeLong(loword(m_WAbil.DC) + (m_Dan.SoulBaby.Abil.btDc shr 4), hiword(m_WAbil.DC) + (m_Dan.SoulBaby.Abil.btDc and $0F));
    m_WAbil.MC := MakeLong(loword(m_WAbil.MC) + (m_Dan.SoulBaby.Abil.btMc shr 4), hiword(m_WAbil.MC) + (m_Dan.SoulBaby.Abil.btMc and $0F));
    m_WAbil.SC := MakeLong(loword(m_WAbil.SC) + (m_Dan.SoulBaby.Abil.btSc shr 4), hiword(m_WAbil.SC) + (m_Dan.SoulBaby.Abil.btSc and $0F));
    m_WAbil.AC := MakeLong(loword(m_WAbil.AC) + (m_Dan.SoulBaby.Abil.btAC shr 4), hiword(m_WAbil.AC) + (m_Dan.SoulBaby.Abil.btAC and $0F));
    m_WAbil.MAC := MakeLong(loword(m_WAbil.MAC) + (m_Dan.SoulBaby.Abil.btMAC shr 4), hiword(m_WAbil.MAC) + (m_Dan.SoulBaby.Abil.btMAC and $0F));
    if (m_PneumaObject <> nil) then begin
      TPlayObject(m_PneumaObject).RecalcAbilitys;
      m_PneumaObject.SendMsg(m_PneumaObject, RM_ABILITY, 0, 0, 0, 0, '');
    end;
end else begin
    if (m_PneumaObject <> nil) then begin
      m_WAbil.dwMaxHP := _MIN(MAXHUMHP, m_WAbil.dwMaxHP + TPlayObject(m_PneumaObject).m_Dan.SoulBaby.Abil.btHP);
      m_WAbil.DC := MakeLong(loword(m_WAbil.DC) + (TPlayObject(m_PneumaObject).m_Dan.SoulBaby.Abil.btPneuma shr 4),
      hiword(m_WAbil.DC) + (TPlayObject(m_PneumaObject).m_Dan.SoulBaby.Abil.btPneuma and $0F));
      m_WAbil.MC := MakeLong(loword(m_WAbil.MC) + (TPlayObject(m_PneumaObject).m_Dan.SoulBaby.Abil.btPneuma shr 4),
      hiword(m_WAbil.MC) + (TPlayObject(m_PneumaObject).m_Dan.SoulBaby.Abil.btPneuma and $0F));
      m_WAbil.SC := MakeLong(loword(m_WAbil.SC) + (TPlayObject(m_PneumaObject).m_Dan.SoulBaby.Abil.btPneuma shr 4),
      hiword(m_WAbil.SC) + (TPlayObject(m_PneumaObject).m_Dan.SoulBaby.Abil.btPneuma and $0F));
    end;
end;
end;

//重新计算校正点数

procedure TPlayObject.RecalcAdjusBonus();

procedure AdjustAb(Abil: word; Val: word; var lov, hiv: word);
var
    Lo, Hi                              : byte;
    i                                 : Integer;
begin
    Lo := LoByte(Abil);
    Hi := HiByte(Abil);
    lov := 0;
    hiv := 0;
    for i := 1 to Val do begin
      if Lo + 1 < Hi then begin
      Inc(Lo);
      Inc(lov);
      end else begin
      Inc(Hi);
      Inc(hiv);
      end;
    end;
end;
var
BonusTick                           : pTNakedAbility;
NakedAbil                           : pTNakedAbility;
adc, amc, asc, aac, amac            : Integer;
ldc, lmc, lsc, lac, lmac, hdc, hmc, hsc, hac, hmac: word;
begin
BonusTick := nil;
NakedAbil := nil;
case m_btJob of
    0: begin
      BonusTick := @g_Config.BonusAbilofWarr;
      NakedAbil := @g_Config.NakedAbilofWarr;
      end;
    1: begin
      BonusTick := @g_Config.BonusAbilofWizard;
      NakedAbil := @g_Config.NakedAbilofWizard;
      end;
    2: begin
      BonusTick := @g_Config.BonusAbilofTaos;
      NakedAbil := @g_Config.NakedAbilofTaos;
      end;
    3: begin
      BonusTick := @g_Config.BonusAbilofGoblin;
      NakedAbil := @g_Config.NakedAbilofGoblin;
      end;
end;

adc := m_BonusAbil.DC div BonusTick.DC;
amc := m_BonusAbil.MC div BonusTick.MC;
asc := m_BonusAbil.SC div BonusTick.SC;
aac := m_BonusAbil.AC div BonusTick.AC;
amac := m_BonusAbil.MAC div BonusTick.MAC;

AdjustAb(NakedAbil.DC, adc, ldc, hdc);
AdjustAb(NakedAbil.MC, amc, lmc, hmc);
AdjustAb(NakedAbil.SC, asc, lsc, hsc);
AdjustAb(NakedAbil.AC, aac, lac, hac);
AdjustAb(NakedAbil.MAC, amac, lmac, hmac);

if (m_btJob = 3) then
    m_WAbil.GC := MakeLong(loword(m_WAbil.GC) + ldc, hiword(m_WAbil.GC) + hdc)
else
    m_WAbil.DC := MakeLong(loword(m_WAbil.DC) + ldc, hiword(m_WAbil.DC) + hdc);

m_WAbil.MC := MakeLong(loword(m_WAbil.MC) + lmc, hiword(m_WAbil.MC) + hmc);
m_WAbil.SC := MakeLong(loword(m_WAbil.SC) + lsc, hiword(m_WAbil.SC) + hsc);
m_WAbil.AC := MakeLong(loword(m_WAbil.AC) + lac, hiword(m_WAbil.AC) + hac);
m_WAbil.MAC := MakeLong(loword(m_WAbil.MAC) + lmac, hiword(m_WAbil.MAC) + hmac);

m_WAbil.dwMaxHP := _MIN(MAXHUMHP, m_WAbil.dwMaxHP + m_BonusAbil.HP div BonusTick.HP);
m_WAbil.dwMaxMP := _MIN(MAXHUMMP, m_WAbil.dwMaxMP + m_BonusAbil.MP div BonusTick.MP);
m_dwSpeedPoint := m_dwSpeedPoint + m_BonusAbil.Speed div BonusTick.Speed;
m_dwHitPoint := m_dwHitPoint + m_BonusAbil.Hit div BonusTick.Hit;
end;

procedure TPlayObject.RecalcTigerLevelAbilitys;
var
TigerAbility                        : pTAbilityOfTiger;
begin
if m_boPneuma then Exit;
if m_btJob = 3 then Exit;                                                                         //妖士是没有虎王

if (m_TorDDM.Tiger.DB.level >= 0) then begin
    TigerAbility := UserEngine.GetTigerAbilByLevel(m_TorDDM.Tiger.DB.level, m_TorDDM.Tiger.DB.Dragon);
    if TigerAbility <> nil then begin
      //读取的数据库属性
      m_TorDDM.Tiger.Abil.MaxExp := TigerAbility.MaxExp;
      m_TorDDM.Tiger.Abil.MaxHP := TigerAbility.MaxHP;
      m_TorDDM.Tiger.AddAbil.HP := TigerAbility.MaxHP;
      m_TorDDM.Tiger.Abil.DC := TigerAbility.DC;
      m_TorDDM.Tiger.Abil.DC2 := TigerAbility.DC2;
      m_TorDDM.Tiger.Abil.MC := TigerAbility.MC;
      m_TorDDM.Tiger.Abil.MC2 := TigerAbility.MC2;
      m_TorDDM.Tiger.Abil.AC := TigerAbility.AC;
      m_TorDDM.Tiger.Abil.AC2 := TigerAbility.AC2;
      m_TorDDM.Tiger.Abil.MAC := TigerAbility.MAC;
      m_TorDDM.Tiger.Abil.MAC2 := TigerAbility.MAC2;

      m_TorDDM.Tiger.Abil.HitPoint := TigerAbility.HitPoint;
      m_TorDDM.Tiger.Abil.MagicNicety := TigerAbility.MagicNicety;
      m_TorDDM.Tiger.Abil.SpeedPoint := TigerAbility.SpeedPoint;
      m_TorDDM.Tiger.Abil.AntiMagic := TigerAbility.AntiMagic;
      m_TorDDM.Tiger.Abil.Felement := TigerAbility.Felement;
    end;
end;
end;

procedure TPlayObject.RecalcTigerAbility;
var
i                                     : Integer;
StdItem                               : pTStdItem;
TigerAbility                        : pTAbilityOfTiger;
boWeared                              : Boolean;
procedure GetItemAccessory(Item: TUserItem; var AddAbility: TAddAbilityOfTiger);
var
    StdItem                           : pTStdItem;
    StdItemA                            : TStdItem;
    i                                 : Integer;
begin
    StdItem := UserEngine.GetStdItem(Item.wIndex);
    if StdItem = nil then Exit;
    StdItemA := StdItem^;
    ItemUnit.GetItemAddValue(@Item, StdItemA);
    AddAbility.AC := MakeLong(_MIN(High(word), LoWord(AddAbility.AC) + LoWord(StdItemA.AC)), _MIN(High(word), HiWord(AddAbility.AC) + HiWord(StdItemA.AC)));
    AddAbility.MAC := MakeLong(_MIN(High(word), LoWord(AddAbility.MAC) + LoWord(StdItemA.MAC)), _MIN(High(word), HiWord(AddAbility.MAC) + HiWord(StdItemA.MAC)));
    AddAbility.DC := MakeLong(_MIN(High(word), LoWord(AddAbility.DC) + LoWord(StdItemA.DC)), _MIN(High(word), HiWord(AddAbility.DC) + HiWord(StdItemA.DC)));
    AddAbility.MC := MakeLong(_MIN(High(word), LoWord(AddAbility.MC) + LoWord(StdItemA.MC)), _MIN(High(word), HiWord(AddAbility.MC) + HiWord(StdItemA.MC)));

    AddAbility.HitPoint := _MIN(High(byte), AddAbility.HitPoint + LoWord(StdItemA.MC));
    AddAbility.SpeedPoint := _MIN(High(byte), AddAbility.SpeedPoint + HiWord(StdItemA.MC));
    AddAbility.AntiMagic := _MIN(High(byte), AddAbility.AntiMagic + LoWord(StdItemA.SC));
    AddAbility.FelementDC := _MIN(High(word), AddAbility.FelementDC + HiWord(StdItemA.SC));
    AddAbility.FelementAC := _MIN(High(word), AddAbility.FelementAC + HiWord(StdItemA.SC));
    AddAbility.HP := _MIN(MAXHUMHP, AddAbility.HP + StdItemA.NeedAmbit);
end;
begin
if m_boPneuma then Exit;
if m_btJob = 3 then Exit;                                                                         //妖士是没有虎王
FillChar(m_TorDDM.Tiger.AddAbil, SizeOf(TAddAbilityOfTiger), #0);

//计算基本属性
m_TorDDM.Tiger.AddAbil.AC := MakeLong(m_TorDDM.Tiger.Abil.AC, m_TorDDM.Tiger.Abil.AC2);
m_TorDDM.Tiger.AddAbil.MAC := MakeLong(m_TorDDM.Tiger.Abil.MAC, m_TorDDM.Tiger.Abil.MAC2);
m_TorDDM.Tiger.AddAbil.DC := MakeLong(m_TorDDM.Tiger.Abil.DC, m_TorDDM.Tiger.Abil.DC2);
m_TorDDM.Tiger.AddAbil.MC := MakeLong(m_TorDDM.Tiger.Abil.MC, m_TorDDM.Tiger.Abil.MC2);
m_TorDDM.Tiger.AddAbil.HitPoint := m_TorDDM.Tiger.Abil.HitPoint;
m_TorDDM.Tiger.AddAbil.MagicNicety := m_TorDDM.Tiger.Abil.MagicNicety;
m_TorDDM.Tiger.AddAbil.SpeedPoint := m_TorDDM.Tiger.Abil.SpeedPoint;
m_TorDDM.Tiger.AddAbil.AntiMagic := m_TorDDM.Tiger.Abil.AntiMagic;
m_TorDDM.Tiger.AddAbil.HP := _MIN(MAXHUMHP, m_TorDDM.Tiger.Abil.MaxHP + m_TorDDM.Tiger.ProAbil.HP);
m_TorDDM.Tiger.AddAbil.FelementDC := _MIN(High(word), m_TorDDM.Tiger.Abil.Felement + m_TorDDM.Tiger.ProAbil.Felement);
m_TorDDM.Tiger.AddAbil.FelementAC := _MIN(High(word), m_TorDDM.Tiger.Abil.Felement + m_TorDDM.Tiger.ProAbil.Felement);

//计算虎王装备属性
boWeared := True;
for i := 0 to MAX_TIGER_ITEM_COUNT - 1 do begin
    if (m_TorDDM.Tiger.Items.wIndex <= 0) or (m_TorDDM.Tiger.Items.Dura <= 0) then begin
      boWeared := False;
      Continue;
    end;
    //物品不存在或物品已损坏
    StdItem := UserEngine.GetStdItem(m_TorDDM.Tiger.Items.wIndex);
    if StdItem = nil then Continue;
    GetItemAccessory(m_TorDDM.Tiger.Items, m_TorDDM.Tiger.AddAbil);
end;
SendMsg(Self, RM_TIGERADDABIL, 0, 0, 0, 0, '');

if (m_Tiger <> nil) then begin
    SendTigerInfo;
    m_Tiger.RecalcAbilitys;
    if m_TorDDM.Tiger.DB.Dragon = 0 then begin
      if (m_TorDDM.Tiger.DB.level >= 50) then begin
      m_Tiger.m_wAppr := 349;
      m_Tiger.m_sCharName := '啸天虎王';
      end else begin
      m_Tiger.m_wAppr := 350;
      m_Tiger.m_sCharName := '啸天虎';
      end;
      if boWeared then m_Tiger.m_wAppr := 384;
      m_Tiger.RefShowName;
      m_Tiger.FeatureChanged;
    end;
end;
end;

//根据通灵塔等级和官职获得属性点加成

procedure TPlayObject.RecalcTowerAbility();
var
i, nTowerGrade, nRank               : Integer;
nMinValue, nMaxValue                  : Integer;
btPrOffer                           : byte;
begin
btPrOffer := m_GuildTowerInfo.btPrOffer;
FillChar(m_GuildTowerInfo, SizeOf(TGuildTowerInfo), #0);
if m_MyGuild = nil then Exit;
nTowerGrade := _MIN(10, TGuild(m_MyGuild).btTowerGrade);
nRank := _MIN(11, m_nGuildRankNo);

if (nTowerGrade > 0) then begin
    m_GuildTowerInfo.wX := TGuild(m_MyGuild).wTowerX;
    m_GuildTowerInfo.wY := TGuild(m_MyGuild).wTowerY;
    m_GuildTowerInfo.btResFull := byte(TGuild(m_MyGuild).boTowerStatus);
    m_GuildTowerInfo.btPrOffer := btPrOffer;
    //以下为本体DC\MC\SC计算公式
    case m_btJob of
      0: begin
          nMinValue := byte(LoByte(g_Config.GuildTowerAbility.wDC) > 0) * (LoByte(g_Config.GuildTowerAbility.wDC) - ((nRank + 7) div 9) + nTowerGrade - 1);
          nMaxValue := byte(HiByte(g_Config.GuildTowerAbility.wDC) > 0) * (HiByte(g_Config.GuildTowerAbility.wDC) - ((nRank + 7) div 9) + nTowerGrade - 1);
          m_GuildTowerInfo.Ability.wDC := MakeWord(_MIN(High(byte), nMinValue * g_Config.nGuildTowerAbilityRate div 10), _MIN(High(byte), nMaxValue * g_Config.nGuildTowerAbilityRate div 10));
      end;
      1: begin
          nMinValue := byte(LoByte(g_Config.GuildTowerAbility.wMC) > 0) * (LoByte(g_Config.GuildTowerAbility.wMC) - ((nRank + 7) div 9) + nTowerGrade - 1);
          nMaxValue := byte(HiByte(g_Config.GuildTowerAbility.wMC) > 0) * (HiByte(g_Config.GuildTowerAbility.wMC) - ((nRank + 7) div 9) + nTowerGrade - 1);
          m_GuildTowerInfo.Ability.wMC := MakeWord(_MIN(High(byte), nMinValue * g_Config.nGuildTowerAbilityRate div 10), _MIN(High(byte), nMaxValue * g_Config.nGuildTowerAbilityRate div 10));
      end;
      2: begin
          nMinValue := byte(LoByte(g_Config.GuildTowerAbility.wSC) > 0) * (LoByte(g_Config.GuildTowerAbility.wSC) - ((nRank + 7) div 9) + nTowerGrade - 1);
          nMaxValue := byte(HiByte(g_Config.GuildTowerAbility.wSC) > 0) * (HiByte(g_Config.GuildTowerAbility.wSC) - ((nRank + 7) div 9) + nTowerGrade - 1);
          m_GuildTowerInfo.Ability.wSC := MakeWord(_MIN(High(byte), nMinValue * g_Config.nGuildTowerAbilityRate div 10), _MIN(High(byte), nMaxValue * g_Config.nGuildTowerAbilityRate div 10));
      end;
      3: begin                                                                                    //妖

      end;

    end;
    //以下为计算AC、MAC公式
    if nRank < 3 then begin
      nMinValue := byte(LoByte(g_Config.GuildTowerAbility.wAC) > 0) * (nTowerGrade + LoByte(g_Config.GuildTowerAbility.wAC) - m_nGuildRankNo);
      nMaxValue := byte(HiByte(g_Config.GuildTowerAbility.wAC) > 0) * (nTowerGrade + HiByte(g_Config.GuildTowerAbility.wAC) - m_nGuildRankNo);
      m_GuildTowerInfo.Ability.wAC := MakeWord(_MIN(High(byte), nMinValue * g_Config.nGuildTowerAbilityRate div 10), _MIN(High(byte), nMaxValue * g_Config.nGuildTowerAbilityRate div 10));

      nMinValue := byte(LoByte(g_Config.GuildTowerAbility.wMAC) > 0) * (nTowerGrade + LoByte(g_Config.GuildTowerAbility.wMAC) - m_nGuildRankNo);
      nMaxValue := byte(HiByte(g_Config.GuildTowerAbility.wMAC) > 0) * (nTowerGrade + HiByte(g_Config.GuildTowerAbility.wMAC) - m_nGuildRankNo);
      m_GuildTowerInfo.Ability.wMAC := MakeWord(_MIN(High(byte), nMinValue * g_Config.nGuildTowerAbilityRate div 10), _MIN(High(byte), nMaxValue * g_Config.nGuildTowerAbilityRate div 10));
    end else begin
      nMinValue := byte(LoByte(g_Config.GuildTowerAbility.wAC) > 0) * (nTowerGrade + LoByte(g_Config.GuildTowerAbility.wAC) - ((nRank + 3) div 2));
      nMaxValue := byte(HiByte(g_Config.GuildTowerAbility.wAC) > 0) * (nTowerGrade + HiByte(g_Config.GuildTowerAbility.wAC) - ((nRank + 3) div 2));
      m_GuildTowerInfo.Ability.wAC := MakeWord(_MIN(High(byte), nMinValue * g_Config.nGuildTowerAbilityRate div 10), _MIN(High(byte), nMaxValue * g_Config.nGuildTowerAbilityRate div 10));

      nMinValue := byte(LoByte(g_Config.GuildTowerAbility.wMAC) > 0) * (nTowerGrade + LoByte(g_Config.GuildTowerAbility.wMAC) - ((nRank + 3) div 2));
      nMaxValue := byte(HiByte(g_Config.GuildTowerAbility.wMAC) > 0) * (nTowerGrade + HiByte(g_Config.GuildTowerAbility.wMAC) - ((nRank + 3) div 2));
      m_GuildTowerInfo.Ability.wMAC := MakeWord(_MIN(High(byte), nMinValue * g_Config.nGuildTowerAbilityRate div 10), _MIN(High(byte), nMaxValue * g_Config.nGuildTowerAbilityRate div 10));
    end;
    //以下为命中、魔法躲避等属性计算
    if nTowerGrade >= 5 then begin
      m_GuildTowerInfo.Ability.btMagicNicety := byte(g_Config.GuildTowerAbility.btMagicNicety > 0) * (nTowerGrade + g_Config.GuildTowerAbility.btMagicNicety - 5);
      m_GuildTowerInfo.Ability.btHitPoint := byte(g_Config.GuildTowerAbility.btHitPoint > 0) * (nTowerGrade + g_Config.GuildTowerAbility.btHitPoint - 5);
      m_GuildTowerInfo.Ability.btAntiMagic := byte(g_Config.GuildTowerAbility.btAntiMagic > 0) * (nTowerGrade + g_Config.GuildTowerAbility.btAntiMagic - 5);
      m_GuildTowerInfo.Ability.btSpeedPoint := byte(g_Config.GuildTowerAbility.btSpeedPoint > 0) * (nTowerGrade + g_Config.GuildTowerAbility.btSpeedPoint - 5);
    end;
    //元神属性与本体一样
    Move(m_GuildTowerInfo.Ability, m_GuildTowerInfo.u_Ability, SizeOf(TGuildTowerAbility));
end;
end;

function TPlayObject.RecallHuman(sHumName: string; wRecallType: word): Boolean;
var
PlayObject                            : TPlayObject;
nX, nY, n18, n1C, nMapIndex         : Integer;
begin
Result := False;
PlayObject := UserEngine.GetPlayObject(sHumName);
if PlayObject <> nil then begin
    if PlayObject.m_wShopItemCount > 0 then begin
      SysMsg('对方在摆摊,无法被召唤。', c_Red, t_Hint);
      PlayObject.SysMsg(m_sCharName + ' 正在召唤你,只有结束摆摊才能被召唤。', c_Red, t_Hint);
      Exit;
    end;
    if PlayObject.m_boArrow then begin
      SysMsg('对方正在执行任务,无法被召唤。', c_Red, t_Hint);
      PlayObject.SysMsg(m_sCharName + ' 正在召唤你,只有结束当前任务才能被召唤。', c_Red, t_Hint);
      Exit;
    end;

    if GetFrontPosition(nX, nY) then begin
      if GetCanMovePosition(nX, nY, 3, n18, n1C) then begin
      PlayObject.SendRefMsg(RM_SPACEMOVE_FIRE, 0, 0, 0, 0, '');
      nMapIndex := m_PEnvir.Index;
      PlayObject.SpaceMove(m_sMapName, n18, n1C, 0, @nMapIndex);
      if wRecallType <> 0 then
          PlayObject.SendRefMsg(RM_510, 1, 0, wRecallType, 0, '');
      end;
      Result := True;
    end else begin
      SysMsg('召唤失败!!!', c_Red, t_Hint);
    end;
end else begin
    SysMsg(Format(g_sNowNotOnLineOrOnOtherServer, ), c_Red, t_Hint);
end;
end;

procedure TPlayObject.RecordHomeXY(nParam1: Integer; nMapIdx: Integer);
begin
if (nParam1 < 0) or (nMapIdx < 0) then Exit;

if Assigned(m_VersionManage) then
try
    m_VersionManage.OnRecordHomeXY(Self, nParam1, nMapIdx);
except
    MainOutMessage(Format('TPlayObject::RecordHomeXY SoftVersionDate:%d', ));
end;
end;

procedure TPlayObject.RecordHomeXY(nParam1: Integer; sMsg: string);
var
sMapName                              : string;
begin
if (sMsg <> '') then begin
    sMapName := DeCodeString(sMsg);
    if g_Config.boClassicServer then begin
      if (sMapName = '0') then
      RecordHomeXY(nParam1, 2)
      else if (sMapName = '2') then
      RecordHomeXY(nParam1, 3)
      else if (sMapName = '7') then
      RecordHomeXY(nParam1, 6)
      else if (sMapName = '5') then
      RecordHomeXY(nParam1, 5)
      else if (sMapName = '4') then
      RecordHomeXY(nParam1, 4)
      else if (sMapName = 'haidi') then
      RecordHomeXY(nParam1, 9)
      else if (sMapName = '1') then
      RecordHomeXY(nParam1, 1)
      else if (sMapName = 'zqd') then
      RecordHomeXY(nParam1, 0);
    end else begin
      if (sMapName = '0') then
      RecordHomeXY(nParam1, 1)
      else if (sMapName = '1') then
      RecordHomeXY(nParam1, 0)
      else if (sMapName = '2') then
      RecordHomeXY(nParam1, 2)
      else if (sMapName = '4') then
      RecordHomeXY(nParam1, 3)
      else if (sMapName = '5') then
      RecordHomeXY(nParam1, 4)
      else if (sMapName = '7') then
      RecordHomeXY(nParam1, 5)
    end;
end;
end;

//我的状态

procedure TPlayObject.RefMyStatus();
begin
RecalcAbilitys();
SendMsg(Self, RM_MYSTATUS, 0, 0, 0, 0, '');
end;

procedure TPlayObject.RefRankInfo(nRankNo: Integer; sRankName: string);
begin
m_nGuildRankNo := nRankNo;
m_sGuildRankName := sRankName;
SendMsg(Self, RM_CHANGEGUILDNAME, 0, 0, 0, 0, '');
end;

//地区状态(只发送给自己)

procedure TPlayObject.RefUserState();                                                               //004D6870
var
N8                                    : Integer;
begin
N8 := 0;
if m_PEnvir.m_MapFlag.boFight then N8 := N8 or 1;
if m_PEnvir.m_MapFlag.boSAFE then N8 := N8 or 2;
if m_boInFreePKArea then N8 := N8 or 4;
SendDefMessage(SM_AREASTATE, N8, 0, 0, 0, '');
end;

{释放附魔属性}

procedure TPlayObject.ReleaseEvil(nMakeIndex: Integer);
var
UserItem                              : pTUserItem;
pStdItem                              : pTStdItem;
begin
GetUserItemByMakeIndex(nMakeIndex, UserItem);
if (UserItem <> nil) then begin
    pStdItem := UserEngine.GetStdItem(UserItem.wIndex);
    if (pStdItem <> nil) then begin
      if (UserItem.Evil.sName = '') or (UserItem.Evil.MakeIndex = 0) then begin
      SysMsg(Format('没有从%s中感应到心魔气息。', ), c_Red, t_Hint);
      Exit;
      end;
      FillChar(UserItem.Evil, SizeOf(TEvil), #0);                                                   //删除心魔数据
      SendUpdateItem(UserItem, false);
      SendDefMessage(SM_ITEMEVIL, Integer(Self), LoWord(nMakeIndex), HiWord(nMakeIndex), 0, '');
      SendRefMsg(RM_510, 1, 0, 60, 0, '');
    end;
end;
end;

function TPlayObject.RepairWeapon: Boolean;
var
nDura                                 : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
begin
Result := False;
UserItem := @m_UseItems;
if (UserItem.wIndex <= 0) or (UserItem.DuraMax <= UserItem.Dura) then Exit;
StdItem := UserEngine.GetStdItem(UserItem.wIndex);
if StdItem = nil then Exit;
{物品控制-禁止修理}
if CheckSPCode(StdItem.SPCode, SP_DISABLEREPAIR) then begin
    SysMsg('此物品禁止修理', c_Red, t_Hint);
    Exit;
end;
Dec(UserItem.DuraMax, (UserItem.DuraMax - UserItem.Dura) div
    g_Config.nRepairItemDecDura {30});
nDura := _MIN(5000, UserItem.DuraMax - UserItem.Dura);
if nDura > 0 then begin
    Inc(UserItem.Dura, nDura);
    SendMsg(Self, RM_DURACHANGE, 1, UserItem.Dura, UserItem.DuraMax, 0, '');
    SysMsg(g_sWeaponRepairSuccess {'武器修复成功...'}, c_Green, t_Hint);
    Result := True;
end;
end;

procedure TPlayObject.ReQuestGuildWar(sGuildName: string; WarTime: Integer = 0);
var
Guild                                 : TGuild;
WarGuild                              : pTWarGuild;
boReQuestOK                           : Boolean;
begin
if not IsGuildMaster then begin
    SysMsg('只有行会掌门人才能申请!!!', c_Red, t_Hint);
    Exit;
end;
if g_Config.nServerNumber <> 0 then begin
    SysMsg('这个命令不能在本服务器上使用!!!', c_Red,
      t_Hint);
    Exit;
end;
Guild := g_GuildManager.FindGuild(sGuildName);
if Guild = nil then begin
    SysMsg('行会不存在!!!', c_Red, t_Hint);
    Exit;
end;
boReQuestOK := False;
WarGuild := TGuild(m_MyGuild).AddWarGuild(Guild);
if WarGuild <> nil then begin
    if Guild.AddWarGuild(TGuild(m_MyGuild)) = nil then begin
      WarGuild.dwWarTick := 0;
    end else begin
      boReQuestOK := True;
    end;
end;
if boReQuestOK then begin
    UserEngine.SendServerGroupMsg(SS_207, g_Config.nServerNumber,
      TGuild(m_MyGuild).sGuildName);
    UserEngine.SendServerGroupMsg(SS_207, g_Config.nServerNumber, Guild.sGuildName);
end;

end;

procedure TPlayObject.ClientCheckVerifyCode(sVerifyCode: string; boOutTime: Boolean = False);
var
NPC                                 : TNormNpc;
boNo                                  : Boolean;
begin
if m_VerifyCodeInfo.pNextNpc <> nil then begin
    try
      NPC := UserEngine.FindMerchant(m_VerifyCodeInfo.pNextNpc);
      if NPC = nil then NPC := UserEngine.FindNPC(m_VerifyCodeInfo.pNextNpc);
    finally
      m_VerifyCodeInfo.pNextNpc := nil;
      m_VerifyCodeInfo.nBeginTick := GetTickCount();
    end;
    if NPC <> nil then begin
      if m_VerifyCodeInfo.sNextLabel <> '' then begin
      try
          if sVerifyCode <> '' then
            sVerifyCode := UpperCase(DeCodeString(sVerifyCode));
          boNo := sVerifyCode <> m_VerifyCodeInfo.sVerifyCode;
          if boNo then
            Inc(m_VerifyCodeInfo.nCurErrorOrd)
          else
            m_VerifyCodeInfo.nCurErrorOrd := 0;
          m_sScriptParam := IntToStr(m_VerifyCodeInfo.nCurErrorOrd);
          m_sScriptParam := BoolToIntStr(boOutTime);
          NPC.GotoLable(Self, m_VerifyCodeInfo.sNextLabel, False);
          m_VerifyCodeInfo.nCurErrorOrd := StrToInt(m_sScriptParam);
      except
      end;
      end;
    end;
end;
end;


procedure TPlayObject.Run();
var
tObjCount                           : Integer;
nInteger                              : Integer;
ProcessMsg                            : TProcessMessage;
boInSafeArea                        : Boolean;
boNeedRecalc                        : Boolean;
i                                     : Integer;
nCount                              : Integer;
boOldHasbox                           : Boolean;
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
PlayObject                            : TPlayObject;
boTakeItem                            : Boolean;
Castle                              : TUserCastle;
sTmpLabel                           : string;
TmpNpc                              : TNormNpc;
NowTick                               : DWORD;
DelayCall                           : pTDelayCall;
ArrowRec                              : pTArrowRec;
nc, nX, nY                              : Integer;
nCheckCode                            : Integer;
tm                                    : DWORD;

resourcestring
sPayMentExpire                        = '您的帐户充值时间已到期!!!';
sDisConnectMsg                        = '游戏被强行中断!!!';
sExceptionMsg1                        = ' TPlayObject::Run -> Operate 1 Code=%d';
sExceptionMsg2                        = ' TPlayObject::Run -> Operate 2 Code=%d # Map:%s(%d,%d)%s Ident:%d Sender:%d wP:%d nP1:%d nP2:%d np3:%d Msg:%s DeMsg:%s';
sExceptionMsg3                        = ' TPlayObject::Run -> GetHighHuman';
sExceptionMsg4                        = ' TPlayObject::Run -> ClearObj';
sExceptionMsg5                        = ' TPlayObject::Run -> AutoGetExpPoint';
sArrowExcept                        = 'TPlayObject::Run 执行SetArrow列表出错:';
sCheckItemExcept                      = 'TPlayObject::Run 非法物品检测出错';
sExceptionMsg6                        = ' TPlayObject::Run -> 天关幻镜 ';
sExceptionMsg7                        = ' TPlayObject::Run -> 减少镇魔值';
sExpRateNorm                        = '经验倍数恢复正常...';
sExpLoitRateNorm                      = '功勋倍数恢复正常...';
sPowerRateNorm                        = '攻击力倍数恢复正常...';
sDefenceRateNorm                      = '防御力倍数恢复正常...';
sBurstRateNorm                        = '杀怪爆率恢复正常...';
sExpRepressDemonRateNorm               = '镇魔珠经验倍数回叙正常...';
begin
if g_boExitServer then begin
    m_boOfflineGetGamePoint := False;
    m_boReconnection := False;
    m_boEmergencyClose := True;
end;
boNeedRecalc := False;

NowTick := GetTickCount;
try
    if m_boDealing then begin                                                                     //正在交易
      if (m_DealCreat = Self) or (m_DealCreat = nil) or (m_btAttatckMode <> HAM_PEACE) or (m_boOfflineGetGamePoint) then
      DealCancel();
    end;

    if (not m_boDeath) then begin
      //召唤烈火结束
      if m_boFireHitSkill and ((NowTick - m_dwLatestFireHitTick) > 20 * 1000) then begin
      m_boFireHitSkill := False;
      SysMsg(sSpiritsGone, c_Red, t_Hint);
      SendSocket(nil, '+UFIR');
      end;

      //召唤雷电结束
      if m_bo44Skill and ((NowTick - m_dwLatest44HitTick) > 20 * 1000) then begin
      m_bo44Skill := False;
      SysMsg(sThunderGone, c_Red, t_Hint);
      SendSocket(nil, '+UTHU');
      end;

      //清空元气
      if (m_wVitaLity >= 1000) and ((NowTick - m_dwClearVitaLityTick) > g_Config.nClearVitaLityTime * 1000) then begin
      DamageVitaLity(1000);
      m_dwClearVitaLityTick := NowTick;
      end;

      if m_boTimeRecall and (NowTick > m_dwTimeRecallTick) then begin
      m_boTimeRecall := False;
      SpaceMove(m_sMoveMap, m_nMoveX, m_nMoveY, 0, nil);
      end;

      //检查是否有重叠人物,有的话要走开
      if ((NowTick - m_dwCheckDupObjTick) > 3000) and (not m_boGodCallBoss) then begin            //如果在神之召唤状态则不检测重叠
      m_dwCheckDupObjTick := NowTick;
      GetStartPoint();                                                                            //重新计算回城点
      tObjCount := m_PEnvir.GetXYObjCount(m_nCurrX, m_nCurrY);
      if tObjCount >= 2 then begin
          if not m_boDupObj then begin
            m_boDupObj := True;
            m_dwDupObjTick := NowTick;
          end;
      end else begin
          m_boDupObj := False;
      end;

      if m_boDupObj and ((NowTick - m_dwDupObjTick) > 1000) then begin
          m_dwDupObjTick := NowTick;
          if (m_wShopItemCount = 0) and (not m_boOfflineGetGamePoint) then
            CharPushed(Random(8), 1, False);
      end;
      end;

      //元神移动到玩家身边去
      if (m_PneumaObject <> nil) and m_boPneuma then begin
      if (m_TargetCret = nil) or (m_TargetCret.m_boGhost) then begin
          m_PneumaObject.GetRightPosition(nX, nY);
          if (abs(m_nTargetX - nX) > 1) or (abs(m_nTargetY - nY) > 1) then begin
            m_nTargetX := nX;
            m_nTargetY := nY;
          end;
          if ((m_PEnvir <> m_PneumaObject.m_PEnvir) or
            (abs(m_nCurrX - m_PneumaObject.m_nCurrX) > 20) or
            (abs(m_nCurrY - m_PneumaObject.m_nCurrY) > 20)) then begin
            SpaceMove(m_PneumaObject.m_PEnvir.m_sMapName, m_nTargetX, m_nTargetY, 0, nil);
            SendRefMsg(RM_TURN,
            m_btDirection,
            m_nCurrX,
            m_nCurrY,
            CalcCent(m_WAbil.dwHP, m_WAbil.dwMaxHP),
            GetShowName);
          end;
      end;
      end;

      Castle := g_CastleManager.InCastleWarArea(Self);                                              //当前所在的城堡
      if (Castle <> nil) and Castle.m_boUnderWar then begin                                       //城堡正在战斗
      ChangePKStatus(True);
      //如果当前在摆摊,则强制收摊
      if m_wShopItemCount > 0 then begin
          CancelDoShop;
      end;
      end;

      if (NowTick - dwTick578) > 1000 then begin
      dwTick578 := NowTick;
      //行会战争名字颜色
      if (m_MyGuild <> nil) then begin
          if TGuild(m_MyGuild).m_GuildWarList.Count > 0 then begin
            boInSafeArea := InSafeArea();
            if boInSafeArea <> m_boInSafeArea then begin
            m_boInSafeArea := boInSafeArea;
            RefNameColor();
            end;
          end;
      end;

      //进出安全区提示
      if (not m_boPneuma) then begin
          if g_Config.boSafeAreaHint and (GetTickCount - m_dwCheckSafeArea > 2000) then begin
            m_dwCheckSafeArea := GetTickCount;
            boInSafeArea := InSafeZone;
            if boInSafeArea <> m_boInSafezone then begin
            m_boInSafezone := boInSafeArea;
            if m_boInSafezone then
                SysMsg('您已经进入安全区...', c_Red, t_Hint)
            else
                SysMsg('您已经离开安全区...', c_Red, t_Hint);
            end;
          end;
      end;

      if (Castle <> nil) and Castle.m_boUnderWar then begin                                       //攻城战
          if (m_PEnvir = Castle.m_MapPalace) and (m_MyGuild <> nil) then begin                      //在皇宫
            if not Castle.IsMember(Self) then begin                                                 //不是当前城堡的人
            if Castle.IsAttackGuild(TGuild(m_MyGuild)) then begin                                 //攻城方
                if Castle.CanGetCastle(TGuild(m_MyGuild)) then begin                              //是否攻下
                  Castle.GetCastle(TGuild(m_MyGuild));
                  UserEngine.SendServerGroupMsg(SS_211, g_Config.nServerNumber,
                  TGuild(m_MyGuild).sGuildName);
                  if Castle.InPalaceGuildCount <= 1 then Castle.StopWallconquestWar();
                  //如果攻城行会只有一个,则结束战斗
                end;
            end;
            end;
          end;
      end else begin
          ChangePKStatus(False);
      end;

      if m_boNameColorChanged then begin
          m_boNameColorChanged := False;
          RefUserState();
          RefShowName();
      end;
      end;

      //人物死亡移到消息处理上面执行
      if (m_WAbil.dwHP = 0) then begin
      if (m_UseItems.wIndex > 0) and
          m_UseItems.IsGod() and
          (m_UseItems.btValue >= 100) then begin
          m_UseItems.btValue := 0;
          SendMsg(Self, RM_SENDGODUSEVAL, 1, m_UseItems.btValue, 0, 0, '');
          m_WAbil.dwHP := m_WAbil.dwMaxHP;
          boNeedRecalc := True;
          SysMsg('重塑金身生效,满状态复活', c_Green, t_Hint);
      end else begin
          if (m_boRevivalEx or ((m_LastHiter = nil) or not m_LastHiter.m_boUnRevival) and m_boRevival) and
            (GetTickCount - m_dwRevivalTick > g_Config.dwRevivalTime {60 * 1000}) then begin
            m_dwRevivalTick := NowTick;
            ItemDamageRevivalRing;
            m_WAbil.dwHP := Round(m_WAbil.dwMaxHP * m_nRevivalRate / 100);
            boNeedRecalc := True;
            SendDefMessage(1639, Integer(Self), Round(g_Config.dwRevivalTime / 1000), 0, 0, '');
            SysMsg(g_sRevivalRecoverMsg {'复活戒指生效,体力恢复'}, c_Green, t_Hint);
          end;
      end;
      if m_WAbil.dwHP = 0 then Die;
      end;
    end;
except
    MainOutMessage(Format(sExceptionMsg1, ));
end;

//清除摆摊的指针
if (m_PackPet <> nil) then begin
    if m_PackPet.m_boDeath or m_PackPet.m_boGhost then begin
      m_PackPet := nil;
      m_PetInfo.nMakeIndex := 0;
      m_PetInfo.wLevel := 0;
      m_PetInfo.btType := 0;
      m_PetInfo.btReLive := 0;
    end;
end;

try                                                                                             //处理人物消息
    nCheckCode := 0;
    m_dwGetMsgTick := GetTickCount;
    while (GetTickCount - m_dwGetMsgTick < g_Config.dwHumanGetMsgTime) and GetMessage(@ProcessMsg) do begin
      nCheckCode := 1;
      if not Operate(@ProcessMsg) then Break;
    end;
    nCheckCode := 2;
    //检查验证码是否超时
    if m_VerifyCodeInfo.pNextNpc <> nil then begin
      if (GetTickCount - m_VerifyCodeInfo.nBeginTick) > m_VerifyCodeInfo.nOutTime then begin
      ClientCheckVerifyCode('', True);
      end;
    end;
    nCheckCode := 3;
    //断线
    if (m_boEmergencyClose or m_boKickFlag or m_boSoftClose) then begin
      if m_boPneuma and (m_PneumaObject <> nil) then begin
      nCheckCode := 4;
      SendRefMsg(RM_510, 1, 0, 42, 0, '');
      //SendDefMessage(SM_OUTOFCONNECTION, 0, 0, 0, 0, '');
      TPlayObject(m_PneumaObject).m_dwCallPneumaTick := GetTickCount;
      TPlayObject(m_PneumaObject).m_PneumaObject := nil;
      if m_boInosculatePneuma then begin
          m_PneumaObject.SendMsg(m_PneumaObject, RM_CTRLMENTAL, 0, Integer(m_PneumaObject), 259, 0, '');
          //当融合状态下!元神有血是备份到这里的
          TPlayObject(m_PneumaObject).m_InosculatePneumaHP := m_WAbil.dwHP;
          TPlayObject(m_PneumaObject).m_InosculatePneumaMP := m_WAbil.dwMP;
      end;

      //清除元神骑站数据
      TPlayObject(m_PneumaObject).m_PetInfo.nMakeIndex := 0;
      TPlayObject(m_PneumaObject).m_PetInfo.wLevel := 0;
      TPlayObject(m_PneumaObject).m_PetInfo.btType := 0;
      TPlayObject(m_PneumaObject).m_PetInfo.btReLive := 0;
      TPlayObject(m_PneumaObject).m_PetInfo.btRideFightSpeed := 0;
      end else if m_PneumaObject <> nil then begin                                                //人物下线,元神也下线
      nCheckCode := 5;
      TPlayObject(m_PneumaObject).m_boSoftClose := True;
      TPlayObject(m_PneumaObject).SendRefMsg(RM_510, 1, 0, 42, 0, '');
      TPlayObject(m_PneumaObject).SendDefMessage(SM_OUTOFCONNECTION, 0, 0, 0, 0, '');
      if TPlayObject(m_PneumaObject).m_boInosculatePneuma then begin
          //当融合状态下!元神有血是备份到这里的
          m_InosculatePneumaHP := TPlayObject(m_PneumaObject).m_WAbil.dwHP;
          m_InosculatePneumaMP := TPlayObject(m_PneumaObject).m_WAbil.dwMP;
      end;

      m_PneumaObject := nil;
      end;
      nCheckCode := 6;
      if m_boSwitchData then begin
      m_sMapName := m_sSwitchMapName;
      m_nCurrX := m_nSwitchMapX;
      m_nCurrY := m_nSwitchMapY;
      end;
      nCheckCode := 7;
      //触发下线脚本
      if (m_sOffLineLabel <> '') then begin
      ExecuteScript(g_ManageNPC, m_sOffLineLabel);
      end;
      nCheckCode := 8;
      if (not m_boPneuma) and (not g_boExitServer) and (not m_boReconnection) then begin
      ExecuteScript(g_ManageNPC, '@PlayOffLine');                                                 //人物下线触发
      end;
      nCheckCode := 9;
      if (not m_boOfflineGetGamePoint) and (not m_boPneuma) and (not g_boExitServer) and (m_boReconnection) then begin
      ExecuteScript(g_ManageNPC, '@PlayReconnection');                                          //人物小退触发
      end;
      nCheckCode := 10;
      if not m_boOfflineGetGamePoint then begin
      MakeGhost();
      end;
      nCheckCode := 11;
      if m_boKickFlag and not m_boPneuma then begin
      SendDefMessage(SM_OUTOFCONNECTION, 0, 0, 0, 0, '');
      end;
      nCheckCode := 12;
      if not m_boReconnection and m_boSoftClose and not m_boPneuma then begin
      if not m_boKickUserSessInfo then begin
          m_boKickUserSessInfo := True;
          FrmIDSoc.SendHumanLogOutMsg(m_sUserID, m_nSessionID);
      end;
      end;
    end;
    nCheckCode := 13;
except
    on E: Exception do begin
      if ProcessMsg.wIdent = 0 then
      MakeGhost();
      // 11.22 加上,用于处理 人物异常退出,但人物还在游戏中问题 提示 Ident0错误
      if m_PEnvir = nil then
      MainOutMessage(Format(sExceptionMsg2, [nCheckCode, '无效地图', m_nCurrX,
          m_nCurrY, m_sCharName,
            ProcessMsg.wIdent,
            Integer(ProcessMsg.BaseObject),
            ProcessMsg.wParam,
            ProcessMsg.nParam1,
            ProcessMsg.nParam2,
            ProcessMsg.nParam3,
            ProcessMsg.sMsg,
            DeCodeString(ProcessMsg.sMsg)
            ]))
      else
      MainOutMessage(Format(sExceptionMsg2, [nCheckCode, m_PEnvir.m_sMapName, m_nCurrX,
          m_nCurrY, m_sCharName,
            ProcessMsg.wIdent,
            Integer(ProcessMsg.BaseObject),
            ProcessMsg.wParam,
            ProcessMsg.nParam1,
            ProcessMsg.nParam2,
            ProcessMsg.nParam3,
            ProcessMsg.sMsg,
            DeCodeString(ProcessMsg.sMsg)
            ]));
      MainOutMessage(E.Message);
    end;
end;

{夺宝系统}
try
    nCheckCode := 100;
    i := 0;
    nCount := m_ArrowList.Count;
    while i < m_ArrowList.Count do begin
      nCheckCode := 101;
      ArrowRec := pTArrowRec(m_ArrowList.Objects);
      nCheckCode := 102;
      //检查是否到了最后时间
      if ArrowRec.dwEndCheckTime <= GetTickCount then begin
      nCheckCode := 103;
      ExecuteScript(g_FunctionNPC, ArrowRec.sEndLabel);
      nCheckCode := 104;
      if nCount = m_ArrowList.Count then begin                                                    //防止脚本删除任务
          nCheckCode := 105;
          m_ArrowList.Delete(i);
          nCheckCode := 106;
          Dispose(ArrowRec);
      end else
          Break;
      end else if ArrowRec.dwCheckTime <= GetTickCount then begin
      nCheckCode := 107;
      ExecuteScript(g_FunctionNPC, ArrowRec.sCheckLabel);
      if nCount <> m_ArrowList.Count then Break;                                                //防止脚本删除任务
      nCheckCode := 108;
      ArrowRec.dwCheckTime := ArrowRec.dwCheckTime + ArrowRec.dwCheckInterval;
      end;
      Inc(i);
    end;
    boOldHasbox := m_boArrow;
    if (nCount > 0) and (m_ArrowList.Count = 0) then begin                                          //取消了所有标签
      m_boArrow := False;
      for i := m_ItemList.Count - 1 downto 0 do begin                                             //检测包裹中是否有宝盒
      UserItem := pTUserItem(m_ItemList);
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem = nil then Continue;
      if CheckSPCode(StdItem.Reserved, RE_TREASURE) then begin
          m_boArrow := True;
          Break;
      end;
      end;
    end else
      m_boArrow := m_ArrowList.Count > 0;
    if boOldHasbox <> m_boArrow then begin
      m_nCharStatus := GetCharStatus();
      StatusChanged();
    end;
except
    on E: Exception do
      MainOutMessage(sArrowExcept + IntToStr(nCheckCode) + ' ' + E.Message);
end;

try
    //检查身上的装备有没不符合
    if (not m_boDeath) then begin
      for i := Low(THumItems) to High(THumItems) do begin
      if m_UseItems.wIndex > 0 then begin
          StdItem := UserEngine.GetStdItem(m_UseItems.wIndex);
          if StdItem <> nil then begin
            if not CheckItemsNeed(StdItem) then begin
            boTakeItem := False;                                                                  //0419
            New(UserItem);
            UserItem^ := m_UseItems;
            if AddItemToBag(UserItem) then begin
                SendAddItem(UserItem);
                WeightChanged();
                SysMsg('物品 ' + StdItem.Name + ' 已经自动取下。', c_Red, t_Hint);
                boTakeItem := True;
            end else begin
                Dispose(UserItem);
                if DropItemDown(@m_UseItems, 2, False, nil, Self) then begin
                  SysMsg('物品 ' + StdItem.Name + ' 自动取下失败,已丢弃。', c_Red, t_Hint);
                  boTakeItem := True;
                end;
            end;
            if boTakeItem then begin
                SendDelItems(@m_UseItems);
                m_UseItems.wIndex := 0;
                RecalcAbilitys(True);
            end;
            end;
          end else begin
            SendDelItems(@m_UseItems);
            m_UseItems.wIndex := 0;
            RecalcAbilitys(True);
          end;
      end;
      end;
    end;
except
    on E: Exception do
      MainOutMessage(sCheckItemExcept + E.Message);
end;
   if (m_DealCreat <> nil) and (m_DealCreat.m_boGhost) then m_DealCreat := nil;            //交易方死亡
if (m_dwEatTalismanTick > 0) and (NowTick > m_dwEatTalismanTick) then begin
    m_dwEatTalismanTick := 0;
    SysMsg('辟邪丹效果已经消失,你将无法抵御魔气侵袭', c_Red, t_Hint);
    ExecuteScript(g_FunctionNPC, '@辟邪丹失效');
end;

if (not m_boDeath) then begin
    tObjCount := m_nGameGold;
    //自动减元宝
    if m_boDecGameGold and (NowTick - m_dwDecGameGoldTick > m_dwDecGameGoldTime) then begin
      m_dwDecGameGoldTick := NowTick;
      if m_nGameGold >= m_nDecGameGold then begin
      Dec(m_nGameGold, m_nDecGameGold);
      nInteger := m_nDecGameGold;
      end else begin
      nInteger := m_nGameGold;
      m_nGameGold := 0;
      m_boDecGameGold := False;
      MoveToHome();                                                                               //没有元宝可减了,就让他回城
      end;
      if g_boGameLogGameGold then begin
      AddGameDataLog(Format(g_sGameLogMsg, [LOG_GAMEGOLD, m_sMapName, m_nCurrX,
          m_nCurrY, m_sCharName, g_Config.sGameGoldName, nInteger, '-', 'Auto']));
      end;
    end;

    //自动加元宝
    if m_boIncGameGold and (NowTick - m_dwIncGameGoldTick > m_dwIncGameGoldTime) then begin
      m_dwIncGameGoldTick := NowTick;
      if m_nGameGold + m_nIncGameGold < g_Config.nHumanMaxGameGold {2000000} then begin
      Inc(m_nGameGold, m_nIncGameGold);
      nInteger := m_nIncGameGold;
      end else begin
      m_nGameGold := g_Config.nHumanMaxGameGold;
      nInteger := g_Config.nHumanMaxGameGold - m_nGameGold;
      m_boIncGameGold := False;
      end;
      if g_boGameLogGameGold then begin
      AddGameDataLog(Format(g_sGameLogMsg, [LOG_GAMEGOLD, m_sMapName, m_nCurrX,
          m_nCurrY, m_sCharName, g_Config.sGameGoldName, nInteger, '+', 'Auto']));
      end;
    end;

    //当前环境自动减元宝
    if not m_boDecGameGold and m_PEnvir.m_MapFlag.boDecGameGold then begin
      if NowTick - m_dwDecGameGoldTick > LongWord(m_PEnvir.m_MapFlag.nDECGAMEGOLDTIME * 1000) then begin
      m_dwDecGameGoldTick := NowTick;
      if m_nGameGold >= m_PEnvir.m_MapFlag.nDecGameGold then begin
          Dec(m_nGameGold, m_PEnvir.m_MapFlag.nDecGameGold);
          nInteger := m_PEnvir.m_MapFlag.nDecGameGold;
      end else begin
          nInteger := m_nGameGold;
          m_nGameGold := 0;
          m_boDecGameGold := False;
          MoveToHome();
      end;
      if g_boGameLogGameGold then begin
          AddGameDataLog(Format(g_sGameLogMsg, [LOG_GAMEGOLD, m_sMapName,
            m_nCurrX, m_nCurrY, m_sCharName, g_Config.sGameGoldName, nInteger, '-', 'Map']));
      end;
      end;
    end;
    //当前环境自动加元宝
    if not m_boIncGameGold and m_PEnvir.m_MapFlag.boIncGameGold then begin
      if NowTick - m_dwIncGameGoldTick > LongWord(m_PEnvir.m_MapFlag.nINCGAMEGOLDTIME * 1000) then begin
      m_dwIncGameGoldTick := NowTick;
      if m_nGameGold + m_PEnvir.m_MapFlag.nIncGameGold <= g_Config.nHumanMaxGameGold then begin
          Inc(m_nGameGold, m_PEnvir.m_MapFlag.nIncGameGold);
          nInteger := m_PEnvir.m_MapFlag.nIncGameGold;
      end else begin
          nInteger := g_Config.nHumanMaxGameGold - m_nGameGold;
          m_nGameGold := g_Config.nHumanMaxGameGold;
      end;
      if g_boGameLogGameGold then begin
          AddGameDataLog(Format(g_sGameLogMsg, [LOG_GAMEGOLD, m_sMapName,
            m_nCurrX, m_nCurrY, m_sCharName, g_Config.sGameGoldName, nInteger, '+', 'Map']));
      end;
      end;
    end;
    //发送元宝增加消息
    if tObjCount <> m_nGameGold then GameGoldChanged();

    //当前环境自动加游戏点
    if m_PEnvir.m_MapFlag.boINCGAMEPOINT then begin
      if (NowTick - m_dwIncGamePointTick > LongWord(m_PEnvir.m_MapFlag.nINCGAMEPOINTTIME * 1000)) then begin
      m_dwIncGamePointTick := NowTick;
      if m_nGamePoint + m_PEnvir.m_MapFlag.nINCGAMEPOINT <= 2000000 then begin
          Inc(m_nGamePoint, m_PEnvir.m_MapFlag.nINCGAMEPOINT);
          nInteger := m_PEnvir.m_MapFlag.nINCGAMEPOINT;
      end else begin
          m_nGamePoint := 2000000;
          nInteger := 2000000 - m_nGamePoint;
      end;
      if g_boGameLogGamePoint then begin
          AddGameDataLog(Format(g_sGameLogMsg, [LOG_GAMEPOINT, m_sMapName,
            m_nCurrX, m_nCurrY, m_sCharName, g_Config.sGamePointName, nInteger, '+', 'Map']));
      end;
      end;
    end;
    //减血
    if m_PEnvir.m_MapFlag.boDECHP and (m_dwEatTalismanTick = 0) and (NowTick - m_dwDecHPTick > LongWord(m_PEnvir.m_MapFlag.nDECHPTIME * 1000)) then begin
      m_dwDecHPTick := NowTick;
      if m_WAbil.dwHP > m_PEnvir.m_MapFlag.nDECHPPOINT then begin
      Dec(m_WAbil.dwHP, m_PEnvir.m_MapFlag.nDECHPPOINT);
      end else begin
      m_WAbil.dwHP := 0;
      end;

      boNeedRecalc := True;
    end;

    //加血
    if m_PEnvir.m_MapFlag.boINCHP and (NowTick - m_dwIncHPTick > LongWord(m_PEnvir.m_MapFlag.nINCHPTIME * 1000)) then begin
      m_dwIncHPTick := NowTick;
      if m_WAbil.dwHP + m_PEnvir.m_MapFlag.nDECHPPOINT < m_WAbil.dwMaxHP then begin
      Inc(m_WAbil.dwHP, m_PEnvir.m_MapFlag.nDECHPPOINT);
      end else begin
      m_WAbil.dwHP := m_WAbil.dwMaxHP;
      end;
      boNeedRecalc := True;
    end;
end;

//地图延迟跳转
if m_PEnvir.m_MapFlag.boDelayGoto and (GetTickCount - m_dwDelayGotoTick > LongWord(m_PEnvir.m_MapFlag.nDelayGotoTime * 1000)) then begin
    m_dwDelayGotoTick := NowTick;
    if m_PEnvir.m_MapFlag.sDelayGotoLable <> '' then ExecuteScript(g_ManageNPC, m_PEnvir.m_MapFlag.sDelayGotoLable);
end;

//降饥饿点
if (not m_boDeath) and g_Config.boHungerSystem and ((NowTick - m_dwDecHungerPointTick) > 1000) then begin
    m_dwDecHungerPointTick := NowTick;
    if m_nHungerStatus > 0 then begin
      tObjCount := GetMyStatus();
      Dec(m_nHungerStatus);
      if tObjCount <> GetMyStatus() then
      RefMyStatus();
    end else if g_Config.boHungerDecHP then begin
      //减少涨HP,MP
      Dec(m_nHealthTick, 60);
      Dec(m_nSpellTick, 10);
      m_nSpellTick := _Max(0, m_nSpellTick);
      Dec(m_nPerHealth);
      Dec(m_nPerSpell);

      if m_WAbil.dwHP > m_WAbil.dwHP div 100 then begin
      Dec(m_WAbil.dwHP, _Max(1, m_WAbil.dwHP div 100));
      end else begin
      if m_WAbil.dwHP <= 2 then m_WAbil.dwHP := 0;
      end;
      boNeedRecalc := True;
    end;
end;

if boNeedRecalc then HealthSpellChanged();

try
    if (not m_boDeath) and (m_nHuanjingIdx <> 0) and (m_dwHuanjingTick + g_Config.nHuanjingDecLingli < NowTick) then begin
      m_dwHuanjingTick := NowTick;
      for i := m_ItemList.Count - 1 downto 0 do begin
      UserItem := pTUserItem(m_ItemList);
      if UserItem.MakeIndex = m_nHuanjingIdx then begin
          if UserItem.Dura > 0 then Dec(UserItem.Dura);
          if UserItem.Dura = 2 then
            SysMsg('幻镜中的灵力即将消耗殆尽,如不及时补充幻镜就将碎裂', c_Red, t_Hint);
          if (UserItem.Dura = 0) then begin
            UserItem.btValue := 1;
            tm := MakeLong(MakeWord(UserItem.btValue, UserItem.btValue),
            MakeWord(UserItem.btValue, UserItem.btValue));
            if tm = 0 then
            m_sScriptParam := '1'                                                            //领取次数
            else
            m_sScriptParam := IntToStr((DateTimeToWolTIme(Now) - tm + 1) div g_Config.nHuanjingGetGift);
            m_sScriptParam := IntToStr(UserItem.Dura);                                           //幻境灵力
            m_sScriptParam := IntToStr(UserItem.btValue);
            //幻境状态 0正常 1破碎
            m_sScriptParam := m_PEnvir.m_sMapName;                                             //地图名
            m_sScriptParam := IntToStr(UserItem.btValue);
            //幻境镶嵌宝石类型1 2 3 表示   0普通幻境
            m_sScriptParam := IntToStr(UserItem.MakeIndex);                                    //幻境ID
            ExecuteScript(g_FunctionNPC, '@天关幻镜奖励');
            SendDefMessage(34980, 0, 769, 300, 3000, '');
            m_nHuanjingIdx := 0;
          end;
          SendUpdateItem(UserItem);
          SendDefMessage(34980, UserItem.MakeIndex, 769, 300, 3000, '');
          Break;
      end;
      end;
    end;
except
    on E: Exception do
      MainOutMessage(sExceptionMsg6 + E.Message);
end;

if (not m_boDeath) and (NowTick - m_dwDecAntvPowerTick > 60 * 1000) then begin
    m_dwDecAntvPowerTick := NowTick;
    try
      for i := Low(THumItems) to High(THumItems) do begin
      if (m_UseItems.wIndex > 0) then begin
          if (m_UseItems.Evil.MakeIndex <> 0) and (m_UseItems.Evil.sName <> '') then begin
            if (m_UseItems.Evil.wPower - g_Config.nAntiEvilPowerDecSpeed) < 0 then
            m_UseItems.Evil.wPower := 0
            else
            Dec(m_UseItems.Evil.wPower, g_Config.nAntiEvilPowerDecSpeed);
            if m_UseItems.Evil.wPower < 10 then begin
            if m_UseItems.Evil.wPower <= 0 then begin
                FillChar(m_UseItems.Evil, SizeOf(TEvil), #0);
                SendUpdateItem(@m_UseItems);
                SendDefMessage(SM_ITEMEVIL, Integer(Self), LoWord(m_UseItems.MakeIndex), HiWord(m_UseItems.MakeIndex), 0, '');
                StdItem := UserEngine.GetStdItem(m_UseItems.wIndex);
                if (StdItem <> nil) then
                  SysMsg(Format('你的%s镇魔值随着时间渐渐变弱,%s上的心魔已经逃逸。', ), c_Red, t_Hint);
                // RecalcLevelAbilitys();
                RecalcAbilitys();
                SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
                SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
            end else
                SysMsg('你装备中的心魔' + m_UseItems.Evil.sName + '即将逃逸,请使用镇魔符增加镇魔值', c_Red, t_Hint);
            end;
            SendDefMessage(SM_ANTIEVILPOWER, m_UseItems.MakeIndex, m_UseItems.Evil.wPower, i, 0, '');
          end;

          //神兵宝甲神力值增加//////
          if m_UseItems.IsGod and
            (((m_UseItems.btItemExt < 100) and (i = U_WEAPON)) or
            ((m_UseItems.btValue < 100) and (i = U_DRESS))) then begin
            Inc(m_UseItems.btValue);
            if (m_UseItems.btValue >= m_UseItems.btValue) then begin
            m_UseItems.btValue := 0;
            if (i = U_DRESS) then begin
                m_UseItems.btValue := _MIN(m_UseItems.btValue + m_UseItems.God_UseVal, 100);
                SendGodUseVal(1, m_UseItems.btValue);
            end else if (i = U_WEAPON) and (m_UseItems.btValue = 0) then begin
                m_UseItems.btItemExt := _MIN(m_UseItems.btItemExt + m_UseItems.btValue, 100);
                SendGodUseVal(0, m_UseItems.btItemExt);
                if m_UseItems.btItemExt >= 100 then begin
                  m_UseItems.btValue := 1;
                  SysMsg('您处于暴走模式,接下来的攻击将会暴击', c_Red, t_Hint);
                end;
            end;
            end;
          end;                                                                                    //if m_UseItems.IsGod and (m_UseItems.btItemExt < 100) then begin

      end;
      end;
    except
      on E: Exception do
      MainOutMessage(sExceptionMsg7 + E.Message);
    end;
end;

if (not m_boDeath) and (NowTick - m_dwRateTick > 1000) then begin
    m_dwRateTick := NowTick;
    //检测元神和自己是否处于同一个地图
    if m_boPneuma and (m_PneumaObject <> nil) and not (m_PneumaObject.m_boDeath or m_PneumaObject.m_boGhost) and
      ((m_PneumaObject.m_PEnvir <> m_PEnvir) or
      (abs(m_nCurrX - m_PneumaObject.m_nCurrX) > 15) or
      (abs(m_nCurrY - m_PneumaObject.m_nCurrY) > 15)) then begin

      SendMsg(Self, CM_3079, 0, 0, 0, 0, '');
    end;

    if m_dwButchItemTime > 0 then begin
      Dec(m_dwButchItemTime);
      if (m_dwButchItemTime = 0) and (m_ButchItem.BaseObject > 0) and (m_ButchItem.PlayObject > 0) then begin
      g_PacketManage3.Init;
      g_PacketManage3.WriteInteger(m_ButchItem.PlayObject);
      g_PacketManage3.WriteInteger(m_ButchItem.BaseObject);
      g_PacketManage3.WriteInteger(0);
      g_PacketManage3.WriteInteger($05);
      g_PacketManage3.WriteByte(1);
      g_PacketManage3.WriteByte(m_btDirection);
      g_PacketManage3.FillWrite(5, 0);
      g_PacketManage3.WriteByte(1);
      SendDefMessage(2161, Integer(self), 0, 0, 0, g_PacketManage3.GetMsg, True);
      m_sScriptParam := TBaseObject(m_ButchItem.BaseObject).m_sCharName;
      ExecuteScript(g_FunctionNPC, '@采集结束_' + IntToStr(m_ButchItem.nID));
      if TBaseObject(m_ButchItem.BaseObject).m_Abil.MAC > 0 then
          TBaseObject(m_ButchItem.BaseObject).Die;            
      end;
    end;

    if m_dwKillMonExpRateTime > 0 then begin
      Dec(m_dwKillMonExpRateTime);
      if m_dwKillMonExpRateTime = 0 then begin
      m_nKillMonExpRate := 100;
      SysMsg(sExpRateNorm, c_Red, t_Hint);
      end;
    end;

    if m_dwKillMonExpLoitRateTime > 0 then begin
      Dec(m_dwKillMonExpLoitRateTime);
      if m_dwKillMonExpLoitRateTime = 0 then begin
      m_nKillMonExpLoitRate := 100;
      SysMsg(sExpLoitRateNorm, c_Red, t_Hint);
      end;
    end;

    if m_dwKillMonRepressDemonRateTime > 0 then begin
      Dec(m_dwKillMonRepressDemonRateTime);
      if m_dwKillMonRepressDemonRateTime = 0 then begin
      m_nKillMonRepressDemonRate := 100;
      SysMsg(sExpRepressDemonRateNorm, c_Red, t_Hint);
      end;
    end;

    if m_dwKillMonBurstRateTime > 0 then begin
      Dec(m_dwKillMonBurstRateTime);
      if m_dwKillMonBurstRateTime = 0 then begin
      m_nKillMonBurstRate := 100;
      SysMsg(sBurstRateNorm, c_Red, t_Hint);
      end;
    end;

    if m_dwPowerRateTime > 0 then begin
      Dec(m_dwPowerRateTime);
      if m_dwPowerRateTime = 0 then begin
      m_nPowerRate := 100;
      SysMsg(sPowerRateNorm, c_Red, t_Hint);
      end;
    end;

    if m_dwDefenceRateTime > 0 then begin
      Dec(m_dwDefenceRateTime);
      if m_dwDefenceRateTime = 0 then begin
      m_nDefenceRate := 100;
      SysMsg(sDefenceRateNorm, c_Red, t_Hint);
      end;
    end;
end;

//新增BUFF计时处理效果
if m_btRaceServer = RC_PLAYOBJECT then
begin
    for i := Low(m_btBuffArr) to High(m_btBuffArr) do begin
      if m_btBuffArr > 0 then begin
      if NowTick > (m_dwBuffArrTick) then begin
          m_btBuffArr := 0;
          m_sScriptParam := IntToStr(i);
          ExecuteScript(g_FunctionNPC, '@_结束_CHANGEMODE');
          case i of                                                                                 //
            1: begin
                m_boAdminMode := False;                                                             //管理员模式
                if g_Config.boShowScriptActionMsg then begin
                  if m_boAdminMode then
                  SysMsg(sGameMasterMode, c_Green, t_Hint)
                  else
                  SysMsg(sReleaseGameMasterMode, c_Green, t_Hint);
                end;
            end;
            2: begin
                m_boSuperMan := False;                                                            //无敌模式
                if g_Config.boShowScriptActionMsg then begin
                  if m_boSuperMan then
                  SysMsg(sSupermanMode, c_Green, t_Hint)
                  else
                  SysMsg(sReleaseSupermanMode, c_Green, t_Hint);
                end;
            end;
            3: begin
                m_boObMode := False;                                                                //隐身模式
                if g_Config.boShowScriptActionMsg then begin
                  if m_boObMode then
                  SysMsg(sObserverMode, c_Green, t_Hint)
                  else
                  SysMsg(g_sReleaseObserverMode, c_Green, t_Hint);
                end;
            end;
            4: begin
                m_boNoAttackMode := False;                                                          //禁止攻击模式
                if g_Config.boShowScriptActionMsg then begin
                  if m_boNoAttackMode then
                  SysMsg(sNoAttackMode, c_Green, t_Hint)
                  else
                  SysMsg(sCanAttackMode, c_Green, t_Hint);
                end;
            end;
            5: begin
                m_boParalysisMode := False;
                if g_Config.boShowScriptActionMsg then begin
                  if m_boParalysisMode then
                  SysMsg('进入麻痹状态', c_Red, t_Hint)
                  else
                  SysMsg('退出麻痹状态', c_Red, t_Hint);
                end;
            end;
            6: begin
                m_boUnParalysisMode := False;
                if g_Config.boShowScriptActionMsg then begin
                  if m_boUnParalysisMode then
                  SysMsg('进入防麻痹状态', c_Red, t_Hint)
                  else
                  SysMsg('退出防麻痹状态', c_Red, t_Hint);
                end;
            end;
            7: begin
                m_boMagicShieldMode := False;
                if g_Config.boShowScriptActionMsg then begin
                  if m_boMagicShieldMode then
                  SysMsg('进入护体状态', c_Red, t_Hint)
                  else
                  SysMsg('退出护体状态', c_Red, t_Hint);
                end;
            end;
            8: begin
                m_boUnMagicShieldMode := False;
                if g_Config.boShowScriptActionMsg then begin
                  if m_boUnMagicShieldMode then
                  SysMsg('进入防护体状态', c_Red, t_Hint)
                  else
                  SysMsg('退出防护体状态', c_Red, t_Hint);
                end;
            end;
            9: begin
                m_boRevivalMode := False;
                if g_Config.boShowScriptActionMsg then begin
                  if m_boRevivalMode then
                  SysMsg('进入重生状态', c_Red, t_Hint)
                  else
                  SysMsg('退出重生状态', c_Red, t_Hint);
                end;
            end;
            10: begin
                m_boUnRevivalMode := False;
                if g_Config.boShowScriptActionMsg then begin
                  if m_boUnRevivalMode then
                  SysMsg('进入防重生状态', c_Red, t_Hint)
                  else
                  SysMsg('退出防重生状态', c_Red, t_Hint);
                end;
            end;
            11: begin
                m_boParalysisModeEx := False;
                if g_Config.boShowScriptActionMsg then begin
                  if m_boParalysisModeEx then
                  SysMsg('进入超级麻痹状态', c_Red, t_Hint)
                  else
                  SysMsg('退出超级麻痹状态', c_Red, t_Hint);
                end;
            end;
            12: begin
                m_boMagicShieldModeEx := False;
                if g_Config.boShowScriptActionMsg then begin
                  if m_boMagicShieldModeEx then
                  SysMsg('进入超级护体状态', c_Red, t_Hint)
                  else
                  SysMsg('退出超级护体状态', c_Red, t_Hint);
                end;
            end;
            13: begin
                m_boRevivalModeEx := False;
                if g_Config.boShowScriptActionMsg then begin
                  if m_boRevivalModeEx then
                  SysMsg('进入超级重生状态', c_Red, t_Hint)
                  else
                  SysMsg('退出超级重生状态', c_Red, t_Hint);
                end;
            end;
            14: begin                                                                               //隐身模式
                m_boHideModeEx := False;
                m_wStatusTimeArr := 1;
                m_nCharStatus := GetCharStatus();
                StatusChanged();
            end;
            15: begin
                m_wStatusTimeArr := 1;
                m_nMagicStatus := GetMagicStatus();
                Status2Changed();
            end;
            16: begin                                                                               //被麻痹
                m_wStatusTimeArr := 1;
                m_nCharStatus := GetCharStatus();
                StatusChanged();
            end;
            17: begin
                m_boMcParalysisMode := False;
                if g_Config.boShowScriptActionMsg then begin
                  if m_boMcParalysisMode then
                  SysMsg('进入魔道麻痹状态', c_Red, t_Hint)
                  else
                  SysMsg('退出魔道麻痹状态', c_Red, t_Hint);
                end;
            end;
            18: begin
                m_boNeedKneel := False;
                SendRefMsg(RM_TURNTO, 0, 0, 0, 0, '');
            end;
            19: begin
                m_btRulerLevel := 0;
                FeatureChanged;
                SendRefMsg(RM_TURN,
                  m_btDirection,
                  m_nCurrX,
                  m_nCurrY,
                  CalcCent(m_WAbil.dwHP, m_WAbil.dwMaxHP),
                  GetShowName);
            end;
            20: begin
                m_boUnWater := False;
                if m_boRideOn then begin
                  if not CheckMapRideOn(m_PEnvir) then ClientRideOff;
                end;
            end;
            21: begin
                m_boHasBaGua := False;
                FeatureChanged;
            end;
            22: m_boStickMode := False;
            23: m_boRideDragonMode := False;
            24: m_boCanGetBackItem := True;
            25: m_boCanRun := True;
            26: m_boCanWalk := True;
            27: m_boCanDeal := True;
            28: m_boCanDrop := True;
            29: m_boCanUseItem := True;
            30: m_boCanHit := True;
            31: m_boCanSpell := True;
            32: begin
                m_boOfficerGodWings := False;
                FeatureChanged;
            end;
            33: begin
                m_btWalkLotus := 0;
                StatusChanged();
            end;
            34: begin
                m_boVehicleMaterial := False;
                StatusChanged();
            end;
            35: m_boRideOrthrusMode := False;
            36: begin
                m_btLoverTitle := 0;
                FeatureChanged;
            end;
            37: begin
                m_boSoaring := False;
                FeatureChanged;
            end;
            38: begin
                m_boGameManage := False;
                FeatureChanged;
            end;
            39: begin
                m_boFirstCarpenter := False;
                FeatureChanged;
            end;
            40: begin
                m_btColorSkill := 0;
                FeatureChanged;
            end;
            41: begin
                m_btKingTitle := 0;
                FeatureChanged;
            end;
            42: begin
                m_btLoverEvents := 0;
                StatusChanged();
            end;
            43: begin
                m_boBianShen := False;
                m_wBianshenImg := 0;
                m_wBianshenAppr := 0;
                m_boAttackMode := False;
                StatusChanged();
            end;
            44: begin
                m_HumanDisarm.boDisarm := False;
                m_HumanDisarm.nTime := 0;
                m_HumanDisarm.btRate := 0;
            end;
            45: begin
                m_boUnMcParalysis := false;
            end;
            46: begin
                m_boUnSafeZone := false;
            end;
            47: begin
                m_boRulerhalo := false;
                StatusChanged();
            end;
          end;
          if i > 4 then RecalcAbilitys;
      end;
      end;
    end;
end;


try                                                                                             //取得在线最高等级、PK、攻击力、魔法、道术 的人物
    if (g_HighLevelHuman = Self) and (m_boDeath or m_boGhost) then g_HighLevelHuman := nil;
    if (g_HighPKPointHuman = Self) and (m_boDeath or m_boGhost) then g_HighPKPointHuman := nil;
    if (g_HighDCHuman = Self) and (m_boDeath or m_boGhost) then g_HighDCHuman := nil;
    if (g_HighMCHuman = Self) and (m_boDeath or m_boGhost) then g_HighMCHuman := nil;
    if (g_HighSCHuman = Self) and (m_boDeath or m_boGhost) then g_HighSCHuman := nil;
    if (g_HighOnlineHuman = Self) and (m_boDeath or m_boGhost) then g_HighOnlineHuman := nil;

    if (m_btPermissionGM < 6) and not m_boDeath and not m_boGhost then begin
      //最高等级
      if (g_HighLevelHuman = nil) or (TPlayObject(g_HighLevelHuman).m_boGhost) then
      g_HighLevelHuman := Self
      else if m_Abil.level > TPlayObject(g_HighLevelHuman).m_Abil.level then
      g_HighLevelHuman := Self;
      //最高PK
      if (g_HighPKPointHuman = nil) or (TPlayObject(g_HighPKPointHuman).m_boGhost) then begin
      if m_nPkPoint > 0 then g_HighPKPointHuman := Self;
      end else if m_nPkPoint > TPlayObject(g_HighPKPointHuman).m_nPkPoint then
      g_HighPKPointHuman := Self;
      //最高攻击力
      if (g_HighDCHuman = nil) or (TPlayObject(g_HighDCHuman).m_boGhost)
      or (hiword(m_WAbil.DC) > hiword(TPlayObject(g_HighDCHuman).m_WAbil.DC)) then
      g_HighDCHuman := Self;
      //最高魔法
      if (g_HighMCHuman = nil) or (TPlayObject(g_HighMCHuman).m_boGhost)
      or (hiword(m_WAbil.MC) > HiWord(TPlayObject(g_HighMCHuman).m_WAbil.MC)) then
      g_HighMCHuman := Self;
      //最高道术
      if (g_HighSCHuman = nil) or (TPlayObject(g_HighSCHuman).m_boGhost)
      or (hiword(m_WAbil.SC) > HiWord(TPlayObject(g_HighSCHuman).m_WAbil.SC)) then
      g_HighSCHuman := Self;
      //最长在线时间
      if (g_HighOnlineHuman = nil) or (TPlayObject(g_HighOnlineHuman).m_boGhost)
      or (m_dwLogonTick < TPlayObject(g_HighOnlineHuman).m_dwLogonTick) then
      g_HighOnlineHuman := Self;
    end;
except
    on E: Exception do begin
      MainOutMessage(sExceptionMsg3);
    end;
end;

try
    if ((g_Config.boReNewChangeColor and (m_btReLevel > 0)) or m_boColorName)
      and (NowTick - m_dwReColorTick > g_Config.dwReNewNameColorTime) then begin
      m_dwReColorTick := NowTick;
      Inc(m_btReColorIdx);
      if m_btReColorIdx > High(g_Config.ReNewNameColor) then
      m_btReColorIdx := 0;
      m_btNameColor := g_Config.ReNewNameColor;
      RefNameColor;
    end;

    //检测侦听私聊对像
    if (m_GetWhisperHuman <> nil) then begin
      if m_GetWhisperHuman.m_boDeath or (m_GetWhisperHuman.m_boGhost) then
      m_GetWhisperHuman := nil;
    end;

    ProcessSpiritSuite();
except

end;

try                                                                                             //清除夫妻、师徒
    if NowTick - m_dwClearObjTick > 10000 then begin
      m_dwClearObjTick := NowTick;
      if (m_DearHuman <> nil) and (m_DearHuman.m_boDeath or
      m_DearHuman.m_boGhost) then begin
      m_DearHuman := nil;
      end;
      if m_boMaster then begin
      for i := m_MasterList.Count - 1 downto 0 do begin
          PlayObject := TPlayObject(m_MasterList.Items);
          if (PlayObject <> nil) and (PlayObject.m_boDeath or PlayObject.m_boGhost) then begin
            m_MasterList.Delete(i);
          end;
      end;
      end else begin
      if (m_MasterHuman <> nil) and (m_MasterHuman.m_boDeath or
          m_MasterHuman.m_boGhost) then begin
          m_MasterHuman := nil;
      end;
      end;
      {减少心魔宝宝镇魔值}
      if (m_nEvilFollowerPower > 0) and (g_Config.nEvilCtrl10SecDecPower {3} > 0) then begin
      if m_nEvilFollowerPower > g_Config.nEvilCtrl10SecDecPower * 1000 then begin
          Dec(m_nEvilFollowerPower, g_Config.nEvilCtrl10SecDecPower * 1000);
          SendDefMessage(CM_RECALLEVIL, Integer(Self), 3,
            LoWord(m_nEvilFollowerPower), HiWord(m_nEvilFollowerPower), '');
          ClearEvilFollower(5);
          if (m_nEvilFollowerPower <= 1000 * 2) and (m_nEvilFollowerPower >= 1000) then begin
            ClearEvilFollower(1);
            SysMsg('你所操控的心魔即将背叛,请立刻使用镇魔符震慑', c_Red, t_Hint);
          end;
          if m_nEvilFollowerPower <= 1000 * 1 then begin
            ClearEvilFollower(2);
          end;
      end else begin
          m_nEvilFollowerPower := 0;
          ClearEvilFollower(3);
      end;
      end;
    end;
except
    on E: Exception do begin
      MainOutMessage(sExceptionMsg4);
      MainOutMessage(E.Message);
    end;
end;

try
    if (m_nAutoGetExpPoint > 0) and ((m_AutoGetExpEnvir = nil) or
      (m_AutoGetExpEnvir = m_PEnvir)) and (NowTick - m_dwAutoGetExpTick > m_nAutoGetExpTime) then begin
      m_dwAutoGetExpTick := NowTick;
      if not m_boAutoGetExpInSafeZone or (m_boAutoGetExpInSafeZone and InSafeZone) then
      if m_boPneuma and (m_boPneumaEffMode) then
          //元神在灵珠状态不能获得经验
      else
          GetExp(m_nAutoGetExpPoint, 0, 0, False);
    end;
except
    MainOutMessage(sExceptionMsg5);
end;

//延时脚本命令DelayCall的处理
if m_DelayCall.Count > 0 then begin
    for i := m_DelayCall.Count - 1 downto 0 do begin
      DelayCall := pTDelayCall(m_DelayCall.Items);
      if DelayCall.dwCallTime > 0 then begin
      if (NowTick >= DelayCall.dwCallTick) then begin
          DelayCall.dwCallTick := DelayCall.dwCallTick + DelayCall.dwDelayTime;
          Dec(DelayCall.dwCallTime);
          if DelayCall.dwCallTime = 0 then DelayCall.dwReleaseTick := NowTick;
          TmpNpc := UserEngine.FindMerchant(DelayCall.NPC);
          if TmpNpc = nil then
            TmpNpc := UserEngine.FindNPC(DelayCall.NPC);
          if TmpNpc <> nil then begin
            m_nScriptGotoCount := 0;
            TmpNpc.GotoLable(Self, DelayCall.sLabel, False);
          end;
          Break;
      end;
      end else begin
      if (DelayCall.dwReleaseTick > 0) and (GetTickCount - DelayCall.dwReleaseTick > 60 * 1000) then begin
          Dispose(pTDelayCall(m_DelayCall.Items));
          m_DelayCall.Delete(i);
          Break;
      end;
      end;
    end;
end;

//延时脚本命令(一柱香)SetTimer的处理
if (m_dwTimerLong > 0) then begin
    if (NowTick - m_dwTimerTick >= m_dwTimerLong * 1000) then begin
      m_dwTimerLong := 0;
      SendDefMessage(1833, 0, 0, 0, 0, '');
      if (m_sTimerLabel <> '') then
      ExecuteScript(g_ManageNPC, m_sTimerLabel);
    end;
end;

//延时脚本命令DelayGoto的处理
if (m_dwDelayLong > 0) and (NowTick - m_dwDelayTick >= m_dwDelayLong) then begin
    m_dwDelayLong := 0;
    if (m_sTimeGotoLable <> '') then begin
      if (m_TimeDelayNpc <> nil) then try
      m_nScriptGotoCount := 0;
      TNormNpc(m_TimeDelayNpc).GotoLable(Self, m_sTimeGotoLable, False);
      finally

      end;
    end;
end;

//脱机泡点的人物执行任意走动
//GetFrontPosition(nX, nY);
if m_boOfflineGetGamePoint and (m_nautologintype=0) and (not m_boPneuma) and g_Config.boOfflineMove and (m_wShopItemCount = 0) and (GetTickCount - m_dwMoveTick > 3200) then begin
    if Random(8) > 0 then begin
      //获取安全内一个任意坐标

      if Random(6) = 0 then m_btDirection := Random(8);
      if GetFrontPosition(nX, nY) then begin
      if m_PEnvir.CanWalk(nX, nY, False) and InSafeZone(m_PEnvir, nX, nY) then begin            //可以移动,检查是否在安全区
          if Random(3) = 0 then
            Runto(m_btDirection, False)
          else
            WalkTo(m_btDirection, False);
      end else begin
          TurnTo(Random(8));
      end;
      end;
      { //随机喊话
      if (m_sAutoSayMsg <> '') and (Random(200) = 0) and (m_sAutoSayMsg <> '@') then
      ProcessSayMsg(m_sAutoSayMsg, 1);
      }
    end;
    m_dwMoveTick := GetTickCount;
end;
   if m_boOfflineGetGamePointand (m_nautologintype<>0) and (not m_boPneuma) and g_Config.boOfflineMove and (m_wShopItemCount = 0) {and (GetTickCount - m_dwMoveTick >100)} then begin
      if Think then begin
      inherited;
      Exit;
      end;
//   MainOutMessage('不-: ' + inttostr(GetTickCount));
   if (m_TargetCret <> nil) then begin
    if getAInoa(m_TargetCret.m_sCharName) thenbegin
   DelTargetCreat();
      //MainOutMessage('不--攻击: ' + m_TargetCret.m_sCharName);
    end;
   end;
      if (m_TargetCret = nil) and((GetTickCount - m_dwSearchEnemyTick) > 2000) then begin
      m_dwSearchEnemyTick := GetTickCount();
      SearchTarget();
      end;

      if m_boWalkWaitLocked then begin
      if (GetTickCount - m_dwWalkWaitTick) > m_dwWalkWait then begin
          m_boWalkWaitLocked := False;
      end;
      end;





    m_dwMoveTick := GetTickCount;
end;
//恐惧
if (m_wStatusTimeArr > 0) and (GetTickCount - m_dwMoveTick > 450) and (m_wShopItemCount = 0) and (not m_boCatapultAttackMode) then begin
    case Random(80) of                                                                              //变换方向
      0..10: GetBackPosition(nX, nY);
      20..30: GetLeftPosition(nX, nY);
      50..60: GetRightPosition(nX, nY);
    else
      GetFrontPosition(nX, nY);
    end;
    m_btDirection := GetNextDirection(m_nCurrX, m_nCurrY, nX, nY);
    if m_PEnvir.MoveToMovingObject(m_nCurrX, m_nCurrY, Self, nX, nY, False) > 0 then begin
      m_nCurrX := nX;
      m_nCurrY := nY;
      SendRefMsg(RM_RUSH, MakeWord(m_btDirection, 5), m_nCurrX, m_nCurrY, CalcCent(m_WAbil.dwHP, m_WAbil.dwMaxHP), '')
    end else
      m_btDirection := Random(8);
    m_dwMoveTick := GetTickCount;
end;

try
    MagFieryDragonRun();                                                                            //火龙附体
except
    MainOutMessage(' TPlayObject::Run -> 战争旋风');
end;
inherited Run;
end;

//发送进入游戏公告





function TPlayObject.gotopoint(smapName: string;nx,ny:integer): Boolean;
var
nC:integer;
begin

   if not m_boWalkWaitLocked and (Integer(GetTickCount - m_dwWalkTick) > 600) then begin
      m_dwWalkTick := GetTickCount();
      Inc(m_nWalkCount);
      if m_nWalkCount > m_nWalkStep then begin
          m_nWalkCount := 0;
          m_boWalkWaitLocked := True;
          m_dwWalkWaitTick := GetTickCount();
      end;
       m_boMission:=true;
       m_nMissionX:= nx   ;
       m_nMissionY:=ny   ;
      if not m_boRunAwayMode then begin
          if not m_boNoAttackMode then begin
            if m_TargetCret <> nil then begin

            if actAttackTarget then begin
                inherited;
                Exit;
            end;

            end else begin
            m_nTargetX := -1;
            if m_boMission then begin
                m_nTargetX := m_nMissionX;
                m_nTargetY := m_nMissionY;
            end;
            end;
          end;


      end else begin
          if (m_dwRunAwayTime > 0) and ((GetTickCount - m_dwRunAwayStart) > m_dwRunAwayTime) then begin
            m_boRunAwayMode := False;
            m_dwRunAwayTime := 0;
          end;
      end;


      if (m_nTargetX <> -1) then begin
          if (m_TargetCret <> nil) then begin
            nC := abs(m_nCurrX - m_TargetCret.m_nCurrX) + abs(m_nCurrY - m_TargetCret.m_nCurrY);
            if not m_boCanRemoteHit or (nC < 4) or (nC > 7) then
            GotoTargetXY();
          end else
            GotoTargetXY();
      end else begin

          if (m_TargetCret = nil) and (m_Master = nil) then
            Wondering()
          else if (m_Master <> nil) and (m_Master.m_TargetCret <> nil) then
            SetTargetCreat(m_Master.m_TargetCret);                                                //设置攻击目标为主人的攻击目标
      end;
      end;

    end;





function TPlayObject.GetBagItemCount(sItemName: string): Integer;
var
i                                     : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
nIndex                              : Integer;
begin
Result := 0;
if sItemName = '' then Exit;

nIndex := UserEngine.GetStdItemIdx(sItemName);
if nIndex > 0 then begin
    StdItem := UserEngine.GetStdItem(nIndex);
    if StdItem = nil then Exit;

    for i := m_ItemList.Count - 1 downto 0 do begin
      UserItem := pTUserItem(m_ItemList.Items);
      if UserItem = nil then Exit;
      if UserItem.wIndex = nIndex then begin
      if CheckSPCode(StdItem.Reserved, RE_ALLOWPILE) then begin
          Inc(Result, UserItem.Dura);
      end else begin
          Inc(Result, 1);
      end;
      end;
    end;
end;
end;

function TPlayObject.Think(): Boolean;
var
nOldX, nOldY                        : Integer;
nIdx                                  : Integer;
nX, nY                              : Integer;
nAmuletAC                           : Integer;
tCode                                 : Integer;
resourcestring
sExceptionMsg                         = 'function TAIPlayer.Think:: => Code = %d';
begin
Result := False;
tCode := 0;
if (GetTickCount - m_dwThinkTick) > 1 * 1000 then begin
    try
      tCode := 1;
      m_dwThinkTick := GetTickCount();
      if m_PEnvir.GetXYObjCount(m_nCurrX, m_nCurrY) >= 2 then m_boDupMode := True;

      {设置攻击目标}
      if (m_TargetCret = nil) and (m_LastHiter <> nil) and IsProperTarget(m_LastHiter) then
      SetTargetCreat(m_LastHiter);
      tCode := 2;
      {跟随主人攻击}

      tCode := 3;
      if not IsProperTarget(m_TargetCret) then m_TargetCret := nil;
      if m_boDupMode then begin
      nOldX := m_nCurrX;
      nOldY := m_nCurrY;
      WalkTo(Random(8), False);
      if (nOldX <> m_nCurrX) or (nOldY <> m_nCurrY) then begin
          m_boDupMode := False;
          Result := True;
          SendRefMsg(SM_204, 0, 0, 0, 0, '');
          Exit;
      end;
      end;
      {心魔逃跑、使用非攻击性技能}
      if m_boHolySeize then Exit;
      tCode := 4;
      {金刚护体}
      if not Result and (m_MagicSkills <> nil) and (m_nHushenDura = 0) then
      Result := DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, Self);
      {护身真气}
      {if not Result and (m_MagicSkills <> nil) and (m_nHushenDura = 0) then
      Result := DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, Self); }
      {魔法盾}
      if not Result and (m_MagicSkills <> nil) and (m_wStatusTimeArr = 0) then
      Result := DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, Self);
      {风影盾}
      if not Result and (m_MagicSkills <> nil) and (m_wStatusTimeArr = 0) then
      Result := DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, Self);
      tCode := 5;
      {风火轮-攻击性技能}
      if not Result and (m_TargetCret <> nil) and (m_MagicSkills <> nil) and (m_wStatusTimeArr = 0) then
      Result := DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, Self);
      tCode := 6;
      {幽灵盾}
      if not Result and (m_MagicSkills <> nil) then begin
      if (m_wStatusTimeArr = 0) then
          Result := DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, Self)
      else if (m_Master <> nil) and not m_Master.m_boGhost and (m_Master.m_wStatusTimeArr = 0) then
          Result := DoSpell(m_MagicSkills, m_Master.m_nCurrX, m_Master.m_nCurrY, m_Master);
      end;
      tCode := 7;
      {神圣战甲术}
      if not Result and (m_MagicSkills <> nil) and (GetBagItemCount('道符')>0)then begin
      if (m_wStatusTimeArr = 0) then
          Result := DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, Self)
      else if (m_Master <> nil) and not m_Master.m_boGhost and (m_Master.m_wStatusTimeArr = 0) then
          Result := DoSpell(m_MagicSkills, m_Master.m_nCurrX, m_Master.m_nCurrY, m_Master);
      end;
      tCode := 8;
      {解毒术}
      if not Result and (m_MagicSkills <> nil) then begin
      if m_wStatusTimeArr <> 0 then
          Result := DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, Self)
      else if (m_Master <> nil) and not m_Master.m_boGhost and (m_Master.m_wStatusTimeArr <> 0) then
          Result := DoSpell(m_MagicSkills, m_Master.m_nCurrX, m_Master.m_nCurrY, m_Master);
      end;
      tCode := 9;
      {神光术}
      if not Result and (m_MagicSkills <> nil) then begin
      if (m_wStatusTimeArr <> 0) or (m_wStatusTimeArr <> 0) then
          Result := DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, Self)
      else if (m_Master <> nil) and not m_Master.m_boGhost and ((m_Master.m_wStatusTimeArr <> 0) or (m_Master.m_wStatusTimeArr <> 0)) then
          Result := DoSpell(m_MagicSkills, m_Master.m_nCurrX, m_Master.m_nCurrY, m_Master);
      end;
      tCode := 10;

      {强化骷髅术}
      if not Result and (m_MagicSkills <> nil) and (m_SlaveList.Count < 2) then begin
      Result := DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, Self);
      end;
      {召唤神兽}
      if not Result and (m_MagicSkills <> nil) and (m_SlaveList.Count < 1) then begin
      Result := DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, Self);
      end;
      {骷髅召唤术}
      if not Result and (m_MagicSkills <> nil) and (m_SlaveList.Count < 1) then begin
      Result := DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, Self);
      end;

      tCode := 11;
      {心魔逃跑}
      if not Result and (Random(g_Config.nEvilEsCapeRate {10}) = 0) and
      (m_LastHiter <> nil) and (m_WAbil.dwHP / m_WAbil.dwMaxHP < Round(g_Config.nEvilEsCapeHP / 100)) and (GetTickCount - dwLastEscapeTick > 5000) then begin
      if (abs(m_nCurrX - m_LastHiter.m_nCurrX) <= 2) and (abs(m_nCurrY - m_LastHiter.m_nCurrY) <= 2) then begin
          if m_Master <> nil then
            m_Master.GetRightPosition(nX, nY)
          else begin
            nX := m_nCurrX + Random(g_Config.nEvilEsCapeRange {30}) + Random(3);
            nY := m_nCurrY + Random(g_Config.nEvilEsCapeRange {30}) + Random(3);
            if m_PEnvir.CanWalk(nX, nY, False) then begin
            SpaceMove(m_PEnvir.m_sMapName, nX, nY, 0, nil);
            end;
            if Result then begin
            DelTargetCreat;
            m_LastHiter := nil;
            dwLastEscapeTick := GetTickCount;                                                   //防止连续逃跑导致显示错误
            end;
          end;
          if Result and (g_Config.nEvilEsCapeHP / 100 > m_WAbil.dwHP / m_WAbil.dwMaxHP) then begin//逃跑后,血量恢复百分比
            m_WAbil.dwHP := Round(m_WAbil.dwMaxHP * g_Config.nEvilEsCapeHP / 100);
            HealthSpellChanged;
          end;
      end;
      end;

      if not Result and (m_TargetCret = nil) then begin                                             //非攻击状态自动使用技能加血
      if GetTickCount - m_dwMagicAttackTick > m_dwMagicAttackInterval then begin
          {群体治疗术}
          if (m_MagicSkills <> nil) and (m_btJob = 2) then begin
            if (m_Master <> nil) and not m_Master.m_boGhost and (m_Master.m_WAbil.dwHP / m_Master.m_WAbil.dwMaxHP < 0.95) then begin
            if DoSpell(m_MagicSkills, m_Master.m_nCurrX, m_Master.m_nCurrY, m_Master) then begin
                Result := True;
            end;
            end else if (m_WAbil.dwHP / m_WAbil.dwMaxHP < 0.95) then begin
            if DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, nil) then begin
                Result := True;
            end;
            end;
          end;
          {治疗术}
          if not Result and (m_MagicSkills <> nil) and (m_btJob = 2) then begin
            if (m_Master <> nil) and not m_Master.m_boGhost and (m_Master.m_WAbil.dwHP / m_Master.m_WAbil.dwMaxHP < 0.95) then begin
            if DoSpell(m_MagicSkills, m_Master.m_nCurrX, m_Master.m_nCurrY, m_Master) then begin
                Result := True;
            end;
            end else if (m_WAbil.dwHP / m_WAbil.dwMaxHP < 0.95) then begin
            if DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, nil) then begin
                Result := True;
            end;
            end;
          end;
      end;
      end;
      if Result then begin
      m_dwMagicAttackTick := GetTickCount;
      m_dwHitTick := GetTickCount();
      m_boCanRemoteHit := True;
      end;
    except
      on E: Exception do begin
      MainOutMessage(Format(sExceptionMsg, ));
      MainOutMessage(E.Message);
      end;
    end;
end;
end;



procedure TPlayObject.SetTargetXY(nX, nY: Integer);
begin
m_nTargetX := nX;
m_nTargetY := nY;
end;
//获得魔法的Spell

function TPlayObject.GetMagicSpell(UserMagic: pTUserMagic): Integer;
begin
Result := Round(UserMagic.MagicInfo.wSpell / (UserMagic.MagicInfo.btTrainLv + 1) * (UserMagic.btLevel + 1)) + UserMagic.MagicInfo.btDefSpell;
end;
//物理攻击

procedure TPlayObject.Attack(TargeTBaseObject: TBaseObject; nDir: Integer);

function IsEnoughMP(UserMagic: pTUserMagic): Boolean;
begin
    if g_Config.boEvilNotDecMP then
      Result := True
    else
      Result := m_WAbil.dwMP >= UserMagic.MagicInfo.btDefSpell + GetMagicSpell(UserMagic);
end;
var
wIdent                              : Word;
nMagicID                              : Integer;
pMagic                              : pTUserMagic;
begin
{找一个攻击模式}
wIdent := 0;
nMagicID := 0;
pMagic := nil;
m_btDirection := nDir;
if TargeTBaseObject <> nil then begin
    if (GetPoseCreate = TargeTBaseObject) then begin
      if (Random(5) = 0) then begin
      {狮子吼}
      if (m_MagicSkills <> nil) and IsEnoughMP(m_MagicSkills) then begin
          pMagic := m_MagicSkills;
          DoSpell(pMagic, m_nCurrX, m_nCurrY, TargeTBaseObject);
          Exit;
      end
      {突斩}
      else if (m_MagicSkills <> nil) and IsEnoughMP(m_MagicSkills) then
          pMagic := m_MagicSkills
      {野蛮}
      else if (m_MagicSkills <> nil) and IsEnoughMP(m_MagicSkills) then
          pMagic := m_MagicSkills;
      {野蛮、突斩}
      if pMagic <> nil then begin
          if (GetTickCount - m_dwDoMotaeboTick) > 3 * 1000 then begin
            m_dwDoMotaeboTick := GetTickCount();
            DamageSpell(GetSpellPoint(pMagic));
            // HealthSpellChanged();                                          //心魔不需要发送MP消息
            DoMotaebo(m_btDirection, pMagic.btLevel, pMagic.GetMagIdx);
          end;
          Exit;
      end;
      end;

      if (pMagic = nil) then begin
      nDir := m_btDirection;
      if (m_MagicSkills <> nil) and IsEnoughMP(m_MagicSkills) then                        //破盾
          AttackDir(nil, 13, nDir)
      else if (m_MagicSkills <> nil) and IsEnoughMP(m_MagicSkills) then                   //破击
          AttackDir(nil, 12, nDir)
      else if (m_MagicSkills <> nil) and IsEnoughMP(m_MagicSkills) then       //强化攻杀剑法
          AttackDir(nil, 18, nDir)
      else if (m_MagicSkills <> nil) and IsEnoughMP(m_MagicSkills) then                   //雷霆剑
          AttackDir(nil, 15, nDir)
      else if (m_MagicSkills <> nil) and IsEnoughMP(m_MagicSkills) then                   //抱月刀
          AttackDir(nil, 14, nDir)
      else if (m_MagicSkills <> nil) and (Random(8) < m_MagicSkills.btLevel + 1) then   //血影刀法
          AttackDir(nil, 17, nDir)
      else if (m_MagicSkills <> nil) and (Random(8) < m_MagicSkills.btLevel + 1) then   //残影刀法
          AttackDir(nil, 16, nDir)
      else if (m_MagicSkills <> nil) and (Random(10) < m_MagicSkills.btLevel + 1) then    //烈火剑法
          AttackDir(nil, 7, nDir)
      else if (m_MagicSkills <> nil) and (Random(8) < m_MagicSkills.btLevel + 1) then   //半月弯刀
          AttackDir(nil, 5, nDir)
      else if (m_MagicSkills <> nil) and (Random(10) < m_MagicSkills.btLevel + 1) then    //刺杀剑术
          AttackDir(nil, 4, nDir)
      else if (m_MagicSkills <> nil) and (Random(10) < m_MagicSkills.btLevel + 1) then      //攻杀剑法
          AttackDir(nil, 3, nDir)
      else
          AttackDir(nil, Random(3), nDir);                                                          //普通攻击

      if (m_MagicSkills <> nil) and (m_UseItems.Dura > 0) then begin
          Dec(m_btAttackSkillCount);
          if m_btAttackSkillPointCount = m_btAttackSkillCount then begin
            m_boPowerHit := True;
          end;
          if m_btAttackSkillCount <= 0 then begin
            m_btAttackSkillCount := 7 - m_MagicSkills.btLevel;
            m_btAttackSkillPointCount := Random(m_btAttackSkillCount);
          end;
      end else if (m_MagicSkills <> nil) and (m_UseItems.Dura > 0) then begin
          Dec(m_btAttackSkillCount);
          if m_btAttackSkillPointCount = m_btAttackSkillCount then begin
            m_boPowerHit := True;
          end;
          if m_btAttackSkillCount <= 0 then begin
            m_btAttackSkillCount := 7 - m_MagicSkills.btLevel;
            m_btAttackSkillPointCount := Random(m_btAttackSkillCount);
          end;
      end else if (m_MagicSkills <> nil) and (m_UseItems.Dura > 0) then begin
          Dec(m_btAttackSkillCount);
          if m_btAttackSkillPointCount = m_btAttackSkillCount then begin
            m_boPowerHit := True;
          end;
          if m_btAttackSkillCount <= 0 then begin
            m_btAttackSkillCount := 7 - m_MagicSkills.btLevel;
            m_btAttackSkillPointCount := Random(m_btAttackSkillCount);
          end;
      end;
      Dec(m_nHealthTick, 30);
      Dec(m_nSpellTick, 100);
      m_nSpellTick := _MAX(0, m_nSpellTick);
      Dec(m_nPerHealth, 2);
      Dec(m_nPerSpell, 2);
      end;
      m_dwHitTick := GetTickCount();
    end;
end;
end;

function TPlayObject.actAttackTarget(): Boolean;
var
bt06, nCount                        : Byte;
begin
Result := False;
if m_TargetCret = nil then Exit;
if m_boHolySeize then Exit;
{检查有没有HP恢复的技能,若有且可以使用,则使用该技能}
if GetTickCount - m_dwMagicAttackTick > m_dwMagicAttackInterval then begin
    if (m_MagicSkills <> nil) and (m_btJob = 2) then begin
      if (m_Master <> nil) and not m_Master.m_boGhost and (m_Master.m_WAbil.dwHP / m_Master.m_WAbil.dwMaxHP < 0.5) then begin
      if DoSpell(m_MagicSkills, m_Master.m_nCurrX, m_Master.m_nCurrY, m_Master) then begin
          Result := True;
      end;
      end else if (m_WAbil.dwHP / m_WAbil.dwMaxHP < 0.5) then begin
      if DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, nil) then begin
          Result := True;
      end;
      end;
    end;
//MainOutMessage('物品名字重复: ' + m_TargetCret.m_sCharName);
    {检查在是否在攻击范围内,使用远程攻击的技能}
    if not Result and (abs(m_nCurrX - m_TargetCret.m_nCurrX) < 8) and (abs(m_nCurrY - m_TargetCret.m_nCurrY) < 8) then begin

      {强化施毒术}
      if not Result and (m_MagicSkills <> nil) and ((m_TargetCret.m_wStatusTimeArr = 0) or (m_TargetCret.m_wStatusTimeArr = 0)) then
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
      {施毒术}
      if not Result and (m_MagicSkills <> nil) and ((m_TargetCret.m_wStatusTimeArr = 0) or (m_TargetCret.m_wStatusTimeArr = 0)) then
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);

      {强化诅咒术}
      if not Result and (m_MagicSkills <> nil) and (Random(12) = 0) and ((m_TargetCret.m_wStatusTimeArr = 0) or (m_TargetCret.m_wStatusTimeArr = 0)) then
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
      {诅咒术}
      if not Result and (m_MagicSkills <> nil) and (Random(12) = 0) and ((m_TargetCret.m_wStatusTimeArr = 0) or (m_TargetCret.m_wStatusTimeArr = 0)) then
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
      {狂龙紫电}
      if not Result and (m_MagicSkills <> nil)and ((GetTickCount -m_MagicSkills.dwSkillTimeTick)>900)then    begin
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
         m_MagicSkills.dwSkillTimeTick:=GetTickCount;
      end;
      {流星火雨}
      if not Result and (m_MagicSkills <> nil) then
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
      {雷电术}
      if not Result and (m_MagicSkills <> nil) and ((GetTickCount -m_MagicSkills.dwSkillTimeTick)>m_MagicSkills.MagicInfo.dwDelayTime) then begin
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
      m_MagicSkills.dwSkillTimeTick:=GetTickCount;
      end;
      {幽冥火咒}
      if not Result and (m_MagicSkills <> nil) and ((GetTickCount -m_MagicSkills.dwSkillTimeTick)>m_MagicSkills.MagicInfo.dwDelayTime) thenbegin
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
      m_MagicSkills.dwSkillTimeTick:=GetTickCount;
      end;
      {灵魂火符}
      if not Result and (m_MagicSkills <> nil) and ((GetTickCount -m_MagicSkills.dwSkillTimeTick)>m_MagicSkills.MagicInfo.dwDelayTime)then   begin
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
      m_MagicSkills.dwSkillTimeTick:=GetTickCount;
      end;
      {冰旋风}
      if not Result and (m_MagicSkills <> nil) then
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
      {五雷轰}
      if not Result and (m_MagicSkills <> nil) then
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
      {冰龙破}
      if not Result and (m_MagicSkills <> nil) then
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
      {冰箭术}
      if not Result and (m_MagicSkills <> nil) then
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
      {冰咆哮}
      if not Result and (m_MagicSkills <> nil) then
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
      {地狱雷光}
      if not Result and (m_MagicSkills <> nil) then
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
      {爆裂火焰}
      if not Result and (m_MagicSkills <> nil) then
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
      {火墙}
      if not Result and (m_MagicSkills <> nil) then
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
      {强化火球}
      if not Result and (m_MagicSkills <> nil) then
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
      {小火球}
      if not Result and (m_MagicSkills <> nil) then
      Result := DoSpell(m_MagicSkills, m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY, m_TargetCret);
    end;
end;

   //如果可以使用远程攻击
if Result then begin
//    MainOutMessage('自动躲避: 1' );
    m_boCanRemoteHit := True;
    m_dwMagicAttackTick := GetTickCount;
    m_dwHitTick := GetTickCount();
    if m_Master <> nil then begin                                                                   //重新设置目标坐标
      m_nTargetX := -1;
    end;
//    Exit;
end elsebegin
    m_boCanRemoteHit := False;
//MainOutMessage('自动躲避: 2' );
end;
//法师不近身攻击
//   MainOutMessage('自动躲避: '+inttostr(abs(m_nCurrX - m_TargetCret.m_nCurrX))+ inttostr(abs(m_nCurrY - m_TargetCret.m_nCurrY)));
if (m_TargetCret <> nil) and
    ((m_btJob = 1) or (m_btJob = 2))and
    (abs(m_nCurrX - m_TargetCret.m_nCurrX) < 4) and (abs(m_nCurrY - m_TargetCret.m_nCurrY) < 4) then
begin
    AutoAvoid();                                                                                    //自动躲避
    if (m_TargetCret.m_PEnvir <> m_PEnvir) then DelTargetCreat();
    Exit;
end;

if not Result and GetAttackDir(m_TargetCret, bt06) then begin                                     //物理攻击
    if (GetTickCount - m_dwHitTick) > m_nNextHitTime then begin
      m_dwHitTick := GetTickCount();
      m_dwTargetFocusTick := GetTickCount();
      m_dwMagicAttackTick := GetTickCount;
      if not Result then
      Attack(m_TargetCret, bt06);
      BreakHolySeizeMode();
    end;
    Result := True;
end else begin
    if (m_TargetCret.m_PEnvir = m_PEnvir) then begin                                                //法师远程攻击
      SetTargetXY(m_TargetCret.m_nCurrX, m_TargetCret.m_nCurrY);
    end else begin
      DelTargetCreat();
    end;
end;
end;

{行走到目标}

procedure TPlayObject.GotoTargetXY;
var
i                                     : Integer;
nDir                                  : Integer;
n10                                 : Integer;
n14                                 : Integer;
n20                                 : Integer;
nOldX                                 : Integer;
nOldY                                 : Integer;
nX, nY                              : Integer;
boRun                                 : Boolean;
begin
boRun := False;

   MainOutMessage('走到目标: '+inttostr(m_nCurrY)+'-    '+inttostr(m_nTargetY) );
if ((m_nCurrX <> m_nTargetX) or (m_nCurrY <> m_nTargetY)) then begin
    n10 := m_nTargetX;
    n14 := m_nTargetY;
    dwTick3F4 := GetTickCount();
    nDir := DR_DOWN;
    if n10 > m_nCurrX then begin
      nDir := DR_RIGHT;
      if n14 > m_nCurrY then nDir := DR_DOWNRIGHT;
      if n14 < m_nCurrY then nDir := DR_UPRIGHT;
    end else begin
      if n10 < m_nCurrX then begin
      nDir := DR_LEFT;
      if n14 > m_nCurrY then nDir := DR_DOWNLEFT;
      if n14 < m_nCurrY then nDir := DR_UPLEFT;
      end else begin
      if n14 > m_nCurrY then nDir := DR_DOWN
      else if n14 < m_nCurrY then nDir := DR_UP;
      end;
    end;
    nOldX := m_nCurrX;
    nOldY := m_nCurrY;

    if (abs(m_nCurrX - m_nTargetX) > 3) or (abs(m_nCurrY - m_nTargetY) > 3) then begin
      if m_PEnvir.GetNextPosition(m_nCurrX, m_nCurrY, nDir, 2, nX, nY) then boRun := True;
    end;
    if boRun then boRun := runto(nDir, False);
    if not boRun then WalkTo(nDir, False);
    n20 := Random(3);
    for i := DR_UP to DR_UPLEFT do begin
      if (nOldX = m_nCurrX) and (nOldY = m_nCurrY) then begin
      if n20 <> 0 then Inc(nDir)
      else if nDir > 0 then Dec(nDir)
      else nDir := DR_UPLEFT;
      if (nDir > DR_UPLEFT) then nDir := DR_UP;
      WalkTo(nDir, False);
      end;
    end;

    if ((nOldX = m_nCurrX) and (nOldY = m_nCurrY)) then begin
      if m_boWalking then begin
      SendRefMsg(SM_204, 0, 0, 0, 0, '');
      m_boWalking := False;
      end;
    end else
      m_boWalking := True;
end else begin
    m_nTargetX := -1;
    if m_boWalking then begin
      SendRefMsg(SM_204, 0, 0, 0, 0, '');
      m_boWalking := False;
    end;
end;
end;

{检测指定方向和范围内坐标的怪物数量}

function TPlayObject.CheckTargetXYCount(nX, nY, nRange: Integer): Integer;
var
BaseObject                            : TBaseObject;
i, nC, n10                            : Integer;
begin
Result := 0;
n10 := nRange;
for i := 0 to m_VisibleActors.Count - 1 do begin
    BaseObject := TBaseObject(pTVisibleBaseObject(m_VisibleActors.Items).BaseObject);
    if BaseObject <> nil then begin
      if not BaseObject.m_boDeath then begin
      if IsProperTarget(BaseObject) then begin
          if ((BaseObject.m_boHideMode = False) or (m_boCoolEye = True)) and (BaseObject.m_boHideModeEx = False) then begin
            nC := abs(nX - BaseObject.m_nCurrX) + abs(nY - BaseObject.m_nCurrY);
            if nC <= n10 then begin
            Inc(Result);
            if Result > 2 then Break;
            end;
          end;
      end;
      end;
    end;
end;
end;

function TPlayObject.CheckTargetXYCountOfDirection(nX, nY, nDir, nRange: Integer): Integer;
var
BaseObject                            : TBaseObject;
i, nC, n10                            : Integer;
begin
Result := 0;
n10 := 2;
for i := 0 to m_VisibleActors.Count - 1 do begin
    BaseObject := TBaseObject(pTVisibleBaseObject(m_VisibleActors.Items).BaseObject);
    if BaseObject <> nil then begin
      if not BaseObject.m_boDeath then begin
      if IsProperTarget(BaseObject) and (not BaseObject.m_boHideMode) then begin
          case nDir of
            DR_UP: begin
                if (abs(nX - BaseObject.m_nCurrX) <= nRange) and ((BaseObject.m_nCurrY - nY) in ) then Inc(Result);
            end;
            DR_UPRIGHT: begin
                if ((BaseObject.m_nCurrX - nX) in ) and ((BaseObject.m_nCurrY - nY) in ) then Inc(Result);
            end;
            DR_RIGHT: begin
                if ((BaseObject.m_nCurrX - nX) in ) and (abs(nY - BaseObject.m_nCurrY) <= nRange) then Inc(Result);
            end;
            DR_DOWNRIGHT: begin
                if ((BaseObject.m_nCurrX - nX) in ) and ((nY - BaseObject.m_nCurrY) in ) then Inc(Result);
            end;
            DR_DOWN: begin
                if (abs(nX - BaseObject.m_nCurrX) <= nRange) and ((nY - BaseObject.m_nCurrY) in ) then Inc(Result);
            end;
            DR_DOWNLEFT: begin
                if ((nX - BaseObject.m_nCurrX) in ) and ((nY - BaseObject.m_nCurrY) in ) then Inc(Result);
            end;
            DR_LEFT: begin
                if ((nX - BaseObject.m_nCurrX) in ) and (abs(nY - BaseObject.m_nCurrY) <= nRange) then Inc(Result);
            end;
            DR_UPLEFT: begin
                if ((nX - BaseObject.m_nCurrX) in ) and ((BaseObject.m_nCurrY - nY) in ) then Inc(Result);
            end;
          end;
          if Result > 2 then Break;
      end;
      end;
    end;
end;
end;

procedure TPlayObject.GotoTargetXYRange();
var
n10                                 : Integer;
n14                                 : Integer;
begin
if CheckTargetXYCount(m_nCurrX, m_nCurrY, 10) < 1 then begin
    n10 := abs(m_TargetCret.m_nCurrX - m_nCurrX);
    n14 := abs(m_TargetCret.m_nCurrY - m_nCurrY);
    if n10 > 4 then Dec(n10, 5) else n10 := 0;
    if n14 > 4 then Dec(n14, 5) else n14 := 0;
    if m_TargetCret.m_nCurrX > m_nCurrX then m_nTargetX := m_nCurrX + n10;
    if m_TargetCret.m_nCurrX < m_nCurrX then m_nTargetX := m_nCurrX - n10;
    if m_TargetCret.m_nCurrY > m_nCurrY then m_nTargetY := m_nCurrY + n14;
    if m_TargetCret.m_nCurrY < m_nCurrY then m_nTargetY := m_nCurrY - n14;

    m_boRunAwayMode := True;
    m_dwRunAwayStart := GetTickCount();
    m_dwRunAwayTime := 2 * 1000;
//    GotoTargetXY();
end;
end;

{自动躲避}

function TPlayObject.AutoAvoid(): Boolean;

function GetAvoidDir(): Integer;
var
    n10                                 : Integer;
    n14                                 : Integer;
begin
    n10 := m_TargetCret.m_nCurrX;
    n14 := m_TargetCret.m_nCurrY;
    Result := DR_DOWN;
    if n10 > m_nCurrX then begin
      Result := DR_LEFT;
      if (n14 > m_nCurrY) then
      Result := DR_DOWNLEFT
      else if Random(5) = 0 then
      Result := DR_UPLEFT;
    end else begin
      if n10 < m_nCurrX then begin
      Result := DR_RIGHT;
      if n14 > m_nCurrY then Result := DR_DOWNRIGHT
      else if Random(5) = 0 then Result := DR_UPRIGHT;
      //if n14 < m_nCurrY then Result := DR_UPRIGHT;
      end else begin
      if n14 > m_nCurrY then Result := DR_UP
      else
          if n14 < m_nCurrY then Result := DR_DOWN;
      end;
    end;
end;

function SearchNextDir(var nTargetX, nTargetY: Integer): Boolean;
var
    i                                 : Integer;
    nDir                              : Integer;
    n01                                 : Integer;
    n02                                 : Integer;
    n03                                 : Integer;
    n04                                 : Integer;
    n05                                 : Integer;
    n06                                 : Integer;
    n07                                 : Integer;
    n08                                 : Integer;
    n10                                 : Integer;
    boGotoL2                            : Boolean;
label
    L001;
label
    L002;
label
    L003;
begin
    Result := False;
    if not Result then begin
      nDir := GetAvoidDir;
      boGotoL2 := False;
      goto L001;
    end;

    L002:
    if not Result then begin
      n10 := 0;
      while True do begin
      Inc(n10);
      nDir := Random(8);
      if nDir in then Break;
      if n10 > 8 then Break;
      end;
      goto L001;
    end;

    L001:
    n01 := 0;
    n02 := 0;
    n03 := 0;
    n04 := 0;
    n05 := 0;
    n06 := 0;
    n07 := 0;
    n08 := 0;
    while True do begin
      if nDir > DR_UPLEFT then Break;
      case nDir of
      DR_UP: begin
            if m_PEnvir.CanWalkEx(nTargetX, nTargetY, True) and (CheckTargetXYCountOfDirection(nTargetX, nTargetY, nDir, 5) = 0) then begin
            Inc(nTargetY, 10 - n01);
            Result := True;
            Break;
            end else begin
            if n01 >= 10 then begin
                nTargetX := m_nCurrX;
                nTargetY := m_nCurrY;
                Inc(nDir);
                Continue;
            end;
            Inc(nTargetY);
            Inc(n01);
            Continue;
            end;
          end;
      DR_UPRIGHT: begin
            if m_PEnvir.CanWalkEx(nTargetX, nTargetY, True) and (CheckTargetXYCountOfDirection(nTargetX, nTargetY, nDir, 5) = 0) then begin
            Inc(nTargetX, 10 - n02);
            Inc(nTargetY, 10 - n02);
            Result := True;
            Break;
            end else begin
            if n02 >= 10 then begin
                nTargetX := m_nCurrX;
                nTargetY := m_nCurrY;
                Inc(nDir);
                Continue;
            end;
            Inc(nTargetX);
            Inc(nTargetY);
            Inc(n02);
            Continue;
            end;
          end;
      DR_RIGHT: begin
            if m_PEnvir.CanWalkEx(nTargetX, nTargetY, True) and (CheckTargetXYCountOfDirection(nTargetX, nTargetY, nDir, 5) = 0) then begin
            Inc(nTargetX, 10 - n03);
            Result := True;
            Break;
            end else begin
            if n03 >= 10 then begin
                nTargetX := m_nCurrX;
                nTargetY := m_nCurrY;
                Inc(nDir);
                Continue;
            end;
            Inc(nTargetX);
            Inc(n03);
            Continue;
            end;
          end;
      DR_DOWNRIGHT: begin
            if m_PEnvir.CanWalkEx(nTargetX, nTargetY, True) and (CheckTargetXYCountOfDirection(nTargetX, nTargetY, nDir, 5) = 0) then begin
            Inc(nTargetX, 10 - n04);
            Dec(nTargetY, 10 - n04);
            Result := True;
            Break;
            end else begin
            if n04 >= 10 then begin
                nTargetX := m_nCurrX;
                nTargetY := m_nCurrY;
                Inc(nDir);
                Continue;
            end;
            Inc(nTargetX);
            Dec(nTargetY);
            Inc(n04);
            Continue;
            end;
          end;
      DR_DOWN: begin
            if m_PEnvir.CanWalkEx(nTargetX, nTargetY, True) and (CheckTargetXYCountOfDirection(nTargetX, nTargetY, nDir, 5) = 0) then begin
            Dec(nTargetY, 10 - n05);
            Result := True;
            Break;
            end else begin
            if n05 >= 10 then begin
                nTargetX := m_nCurrX;
                nTargetY := m_nCurrY;
                Inc(nDir);
                Continue;
            end;
            Dec(nTargetY);
            Inc(n05);
            Continue;
            end;
          end;
      DR_DOWNLEFT: begin
            if m_PEnvir.CanWalkEx(nTargetX, nTargetY, True) and (CheckTargetXYCountOfDirection(nTargetX, nTargetY, nDir, 5) = 0) then begin
            Dec(nTargetX, 10 - n06);
            Dec(nTargetY, 10 - n06);
            Result := True;
            Break;
            end else begin
            if n06 >= 10 then begin
                nTargetX := m_nCurrX;
                nTargetY := m_nCurrY;
                Inc(nDir);
                Continue;
            end;
            Dec(nTargetX);
            Dec(nTargetY);
            Inc(n06);
            Continue;
            end;
          end;
      DR_LEFT: begin
            if m_PEnvir.CanWalkEx(nTargetX, nTargetY, True) and (CheckTargetXYCountOfDirection(nTargetX, nTargetY, nDir, 5) = 0) then begin
            Dec(nTargetX, 10 - n07);
            Result := True;
            Break;
            end else begin
            if n07 >= 10 then begin
                nTargetX := m_nCurrX;
                nTargetY := m_nCurrY;
                Inc(nDir);
                Continue;
            end;
            Dec(nTargetX);
            Inc(n07);
            Continue;
            end;
          end;
      DR_UPLEFT: begin
            if m_PEnvir.CanWalkEx(nTargetX, nTargetY, True) and (CheckTargetXYCountOfDirection(nTargetX, nTargetY, nDir, 5) = 0) then begin
            Dec(nTargetX, 10 - n08);
            Inc(nTargetY, 10 - n08);
            Result := True;
            Break;
            end else begin
            if n08 >= 10 then begin
                nTargetX := m_nCurrX;
                nTargetY := m_nCurrY;
                Inc(nDir);
                Continue;
            end;
            Dec(nTargetX);
            Inc(nTargetY);
            Inc(n08);
            Continue;
            end;
          end;
      end;
    end;
    if (not boGotoL2) and (not Result) then begin
      boGotoL2 := True;
      goto L002;
    end;
end;
var
n10                                 : Integer;
n14                                 : Integer;
n20                                 : Integer;
nOldX                                 : Integer;
nOldY                                 : Integer;
n16                                 : Integer;
nLoopCount                            : Integer;
begin
if not m_boCanRemoteHit then Exit;
   MainOutMessage('自动躲避: ' );
if (GetTickCount - m_dwAutoAvoidTick > 3 * 1000) then begin
    m_dwAutoAvoidTick := GetTickCount();
    if m_TargetCret <> nil then begin
      n10 := 0;
      if CheckTargetXYCount(m_nCurrX, m_nCurrY, 5) > 0 then begin
      while True do begin
          Inc(n10);
          m_nTargetX := m_nCurrX;
          m_nTargetY := m_nCurrY;
          if SearchNextDir(m_nTargetX, m_nTargetY) then begin
            m_boRunAwayMode := True;
            m_dwRunAwayStart := GetTickCount();
            m_dwRunAwayTime := 2 * 1000;
          end;
            //GotoTargetXY();
          if CheckTargetXYCount(m_nCurrX, m_nCurrY, 5) = 0 then Break;
          if n10 >= 1 then Break;
      end;
      end;
      GotoTargetXYRange();
    end;
end;
end;

{无行为目标}

procedure TPlayObject.UpdatenoatcktActors(BaseObject: TBaseObject);                                    //004B939C
var
I                                     : Integer;
boIsVisible                           : Boolean;
VisibleBaseObject                     : pTVisibleBaseObject;
begin
boIsVisible := False;
// if (BaseObject.m_btRaceServer = RC_PLAYOBJECT) or (BaseObject.m_Master <> nil) then
//    m_boIsVisibleActive:=True;//如果是人物或宝宝则置TRUE
for I := 0 to m_noatcktActors.Count - 1 do
begin
    VisibleBaseObject := m_noatcktActors.Items;
    if VisibleBaseObject.BaseObject = BaseObject then
    begin
      VisibleBaseObject.nVisibleFlag := 1;
      boIsVisible := True;
      break;
    end;
end;
if boIsVisible then
    exit;
New(VisibleBaseObject);
VisibleBaseObject.nVisibleFlag := 2;
VisibleBaseObject.BaseObject := BaseObject;
m_noatcktActors.Add(VisibleBaseObject);
end;

function TPlayObject.canatackTarget(BaseObject:TBaseObject): Boolean;


var
I                                     : Integer;
noatackBaseObject                     : pTVisibleBaseObject;
begin
   Result := true;
for I := 0 to m_noatcktActors.Count - 1 do
begin
    noatackBaseObject := m_noatcktActors.Items;
    if (TBaseObject(noatackBaseObject.BaseObject)=BaseObject) then
    begin
      Result := false;
      break;
    end;
end;
end;

procedure TPlayObject.Wondering();

var
nX, nY,ncode,nDir,bx,by: Integer;

begin
m_boAIStart:=true;
m_nround:=20;
if m_boAIStart and
    (m_TargetCret = nil) and
    (not m_boGhost) and
    (not m_boDeath) and
    (not m_boFixedHideMode) and
    (not m_boStoneMode) and
    (m_wStatusTimeArr = 0) then begin
   try


   MainOutMessage(Format('%s往回走:(%d / %d)', ));


    if (abs(m_nCurrX - start_x) + abs(m_nCurry - start_y) >m_nround) thenbegin

    ifm_nMoveFailCount> 10 then   begin
      MapRandomMove(m_PEnvir.m_sMapName, 0,nil);
      m_nMoveFailCount:=0;
    end;

    bx:=start_x+4-random(8) ;
   by:=start_y+4-random(8) ;
            nDir := GetNextDirection(m_nCurrX, m_nCurrY, bx, by);
            m_PEnvir.GetNextPosition(start_x, start_y, nDir, 2, m_nTargetX, m_nTargetY);

            if not runto(nDir, false) thenGotoTargetXY();
            Inc(m_nMoveFailCount);
             //    MainOutMessage(Format('%s往回:(%d / %d/ %d)', ));
      exit;
    //MainOutMessage(Format('%s往回走:(%d / %d)', ));
    end;

    //if not m_PointManager.Finish then begin
    nX := m_nCurrX;
    nY := m_nCurrY;
    //MainOutMessage(Format('TAIObject.Wondering0:(%d / %d)', ));
      //m_PointManager.SetThroughPoint(m_nCurrX, m_nCurrY);
    if (Length(m_Path) > 0) and (m_nPostion < Length(m_Path)) then begin
      if not GotoNextOne(m_Path.X, m_Path.Y, True) then begin
      m_Path := nil;
      m_nPostion := -1;
      Inc(m_nMoveFailCount);
      Inc(m_nPostion);
      end else begin
      m_nMoveFailCount := 0;
      //MainOutMessage(m_sCharName + ' GotoNextOne FindPath:' + IntToStr(Length(m_Path)));
      Exit;
      end;
    end else begin
      m_Path := nil;
      m_nPostion := -1;
    end;
    ncode:=0;
    if m_PointManager.GetPoint(nX, nY) then begin
      if (abs(nX - m_nCurrX) > 2) or (abs(nY - m_nCurrY) > 2) then begin
      g_FindPath.BaseObject := Self;
      m_Path := g_FindPath.FindPath(m_PEnvir, m_nCurrX, m_nCurrY, nX, nY, True, False);
      m_nPostion := 0;
      ncode:=2;
      //MainOutMessage(m_sCharName + ' FindPath:' + IntToStr(Length(m_Path)));
      if (Length(m_Path) > 0) and (m_nPostion < Length(m_Path)) then begin
          if not GotoNextOne(m_Path.X, m_Path.Y, True) then begin
            m_Path := nil;
            m_nPostion := -1;
            Inc(m_nMoveFailCount);
          end else begin
            m_nMoveFailCount := 0;
            Inc(m_nPostion);
            Exit;
          end;
       ncode:=3;
      end else begin
          m_Path := nil;
          m_nPostion := -1;
          Inc(m_nMoveFailCount);
      end;
      end else begin
      if GotoNextOne(nX, nY, True) then begin
          m_nMoveFailCount := 0;
      end else begin
          Inc(m_nMoveFailCount);
      end;
      end;
      //MainOutMessage(Format('%s TAIObject.Wondering1:(%d / %d)', ));
      //if GotoNextOne(nX, nY, True) then MainOutMessage(Format('%s TAIObject.Wondering2:(%d / %d)', )) else MainOutMessage(Format('%s TAIObject.Wondering3:(%d / %d)', ));
    end else Stop;
    //end else Stop;
   except

    MainOutMessage(Format('Wonderingai:(%d )', ));

   end;


end;




{
begin
if (Random(30) = 0) then begin
    if (Random(4) = 1) then TurnTo(Random(8))
    else begin
      WalkTo(m_btDirection, False);
      m_boWalking := True;
    end;
end else if m_boWalking then begin
    SendRefMsg(SM_204, 0, 0, 0, 0, '');
    m_boWalking := False;
end; }
end;


procedure TPlayObject.Stop;
begin
if m_boAIStart then begin
    m_boAIStart := False;
    m_ManagedEnvir := nil;
    m_nMoveFailCount := 0;
    m_Path := nil;
    m_nPostion := -1;
    //MainOutMessage(m_sCharName + ' TAIObject.Stop:' + IntToStr(m_PointManager.Count));
    if g_FunctionNPC <> nil then begin
      m_nScriptGotoCount := 0;
      g_FunctionNPC.GotoLable(Self, '@AIStop', False);
    end;
end;
end;
function TPlayObject.RunToNext(nX, nY: Integer): Boolean;
begin
Result := RunTo(GetNextDirection(m_nCurrX, m_nCurrY, nX, nY), False);
end;

function TPlayObject.WalkToNext(nX, nY: Integer): Boolean;
begin
Result := WalkTo(GetNextDirection(m_nCurrX, m_nCurrY, nX, nY), False);
end;

function TPlayObject.GotoNextOne(nX, nY: Integer; boRun: Boolean): Boolean;
var
I, nStep: Integer;
Path: TPath;
begin
Result := False;
if (abs(nX - m_nCurrX) <= 2) and (abs(nY - m_nCurrY) <= 2) then begin
    if (abs(nX - m_nCurrX) <= 1) and (abs(nY - m_nCurrY) <= 1) then begin
      Result := WalkToNext(nX, nY);
    end else begin
      Result := RunToNext(nX, nY);
    end;
end;

if not Result then begin
    g_FindPath.BaseObject := Self;
    Path := g_FindPath.FindPath(m_PEnvir, m_nCurrX, m_nCurrY, nX, nY, boRun, False);

    if Length(Path) > 0 then begin
      for I := 0 to Length(Path) - 1 do begin
      if (Path.X <> m_nCurrX) or (Path.Y <> m_nCurrY) then begin
          if (abs(Path.X - m_nCurrX) >= 2) or (abs(Path.Y - m_nCurrY) >= 2) then begin
            Result := RunToNext(Path.X, Path.Y);
          end else begin
            Result := WalkToNext(Path.X, Path.Y);
          end;
          break;
      end;
      end;
      Path := nil;
    end;
end;

m_RunPos.nAttackCount := 0;
end;
procedure TPlayObject.SearchTarget;
var
BaseObject, BaseObject18            : TBaseObject;
i, nC, n10                            : Integer;
begin
BaseObject18 := nil;
n10 := 999;

for i := 0 to m_VisibleActors.Count - 1 do begin
    BaseObject := TBaseObject(pTVisibleBaseObject(m_VisibleActors.Items).BaseObject);
    if BaseObject.m_boDeath then Continue;
    if IsProperTarget(BaseObject) and (not BaseObject.m_boHideMode) and (not getAInoa(BaseObject.m_sCharName)) then begin
      nC := abs(m_nCurrX - BaseObject.m_nCurrX) + abs(m_nCurrY - BaseObject.m_nCurrY);
      if nC < n10 then begin
      n10 := nC;
      BaseObject18 := BaseObject;
      end;
    end;
end;
if BaseObject18 <> nil then SetTargetCreat(BaseObject18);
end;



procedure TPlayObject.RunNotice;                                                                  //004DA588
var
Msg                                 : TProcessMessage;
nCode, nOrd                           : Integer;
resourcestring
sExceptionMsg                         = ' TPlayObject::RunNotice';
begin
nCode := 0;
if m_boEmergencyClose or m_boKickFlag or m_boSoftClose then begin
    if m_boKickFlag then SendDefMessage(SM_OUTOFCONNECTION, 0, 0, 0, 0, '');
    MakeGhost();
end else begin
    try
      if not m_boSendNotice then begin
      FeatureChanged;
      SendNotice();
      //m_boSendNotice := True;
      m_dwWaitLoginNoticeOKTick := GetTickCount();
      end else begin
      //      if GetTickCount - m_dwWaitLoginNoticeOKTick > 1200 * 1000 then begin
      //          m_boEmergencyClose := True;
      //      end;
      while GetMessage(@Msg) do begin
          if Msg.wIdent = CM_LOGINNOTICEOK then begin
            m_boLoginNoticeOK := True;
            m_dwRunTick := 0;
            m_dwSearchTick := 0;
            m_boFixedHideMode := False;
            m_boFilterSendMsg := GetDisableSendMsgList(m_sCharName);
            m_boCanDeal := True;
            m_boCanDrop := True;
            m_boCanGetBackItem := True;
            m_boCanWalk := True;
            m_boCanRun := True;
            m_boCanHit := True;
            m_boCanSpell := True;
            m_boCanUseItem := True;

            if g_Config.boPasswordLockSystem then begin                                             //密码保护系统
            if m_boPasswordLocked then begin
                m_boCanGetBackItem := not g_Config.boLockGetBackItemAction;
            end;
            if g_Config.boLockHumanLogin and m_boLockLogon and m_boPasswordLocked then begin
                m_boCanDeal := not g_Config.boLockDealAction;
                m_boCanDrop := not g_Config.boLockDropAction;
                m_boCanUseItem := not g_Config.boLockUserItemAction;
                m_boCanWalk := not g_Config.boLockWalkAction;
                m_boCanRun := not g_Config.boLockRunAction;
                m_boCanHit := not g_Config.boLockHitAction;
                m_boCanSpell := not g_Config.boLockSpellAction;
                m_boCanSendMsg := not g_Config.boLockSendMsgAction;
                m_boObMode := g_Config.boLockInObModeAction;
                m_boAdminMode := g_Config.boLockInObModeAction;
                SysMsg(g_sActionIsLockedMsg + ' 开锁命令: @' + g_GameCommand.UnLock.sCmd, c_Red, t_Hint);
                if not ExecuteScript(g_FunctionNPC, '@仓库锁定') then
                  SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0,
                  g_sActionIsLockedMsg + #13#10#13#10
                  + '仓库开锁命令: @' + g_GameCommand.UNLOCKSTORAGE.sCmd +
                  #13#10
                  + '仓库加锁命令: @' + g_GameCommand.Lock.sCmd + #13#10
                  + '设置密码命令: @' + g_GameCommand.SETPASSWORD.sCmd + #13#10
                  + '修改密码命令: @' + g_GameCommand.CHGPASSWORD.sCmd);
            end;
            end;

            ExecuteScript(g_ManageNPC, '@LoginNotice');

            if g_Config.boClassicServer then begin
            SendDefMessage(SM_SRVVERSION, Integer(Self), 0, 0, 0, m_VersionManage.ServerVerSion);
            end else begin
            m_BattleVal.BattleVal := m_BattleVal.nMinVal + m_BattleVal.nMinVal +
                m_BattleVal.nMinVal + m_BattleVal.nMinVal + m_BattleVal.nMinVal;
            SendDefMessage(SM_BATTLEVAL, Integer(Self), m_BattleVal.BattleVal, 0, 0,
                EnCodeBuffer(@m_BattleVal, SizeOf(TBattleData)), True);

            if g_Config.boTimeBackServer then
                SendDefMessage(SM_SRVVERSION, Integer(Self), 256, 2, 0, m_VersionManage.ServerVerSion);

            if g_Config.boMagicCityServer then
                SendDefMessage(SM_SRVVERSION, Integer(Self), 256, 5, 0, m_VersionManage.ServerVerSion);
{$IF DEMONSERVER = 1}
            if g_Config.boNightMareServer then
                SendDefMessage(SM_SRVVERSION, Integer(Self), 256, 5, 2, m_VersionManage.ServerVerSion);
{$IFEND}
                if g_Config.botimeServer then
                SendDefMessage(SM_SRVVERSION, Integer(Self), 256, 7, 0, m_VersionManage.ServerVerSion);         //时长区
            end;

            if m_boPneuma and (m_PneumaObject <> nil) then begin
            SendRefMsg(RM_TURN,
                m_btDirection,
                m_nCurrX,
                m_nCurrY,
                CalcCent(m_WAbil.dwHP, m_WAbil.dwMaxHP),
                GetShowName);

            SendRefMsg(RM_510, 1, 0, $16, 0, '');                                                 //元神出现的效果
            if m_PneumaObject is TPlayObject then begin
                if TPlayObject(m_PneumaObject).m_nPneumaLastX <> -1 then begin
                  TPlayObject(m_PneumaObject).m_nPneumaLastX := -1;
                  nOrd := DWORD(Self);
                  m_PneumaObject.SendRefMsg(RM_510, LoWord(nOrd), HiWord(nOrd), 126, 0, '');
                  TPlayObject(m_PneumaObject).ExecuteScript(g_FunctionNPC, '@元神切换触发');
                end;
            end;
            end;
          end;
          Operate(@Msg);
      end;
      end;
    except
      MainOutMessage(sExceptionMsg);
    end;
end;
end;

procedure TPlayObject.ScatterBagItems(ItemOfCreat: TBaseObject);
var
i, DropWide, nRate                  : Integer;
DelList                               : TStringList;
boDropall                           : Boolean;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
tm                                    : DWORD;
resourcestring
sExceptionMsg                         = ' TPlayObject::ScatterBagItems';
begin
if m_btRaceServer <> RC_PLAYOBJECT then begin
    inherited ScatterBagItems(ItemOfCreat);
    Exit;
end;

DelList := nil;
if m_boAngryRing or m_boNoDropItem then Exit;                                                   //不死戒指

boDropall := False;
DropWide := 5;
if g_Config.boDieRedScatterBagAll and (PKLevel >= 2) then begin
    boDropall := True;
end;
try
    for i := m_ItemList.Count - 1 downto 0 do begin
      UserItem := pTUserItem(m_ItemList);
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem <> nil then begin
      nRate := g_Config.nDieScatterBagRate;

      if ItemOfCreat <> nil then begin
          if (g_Config.boAttachedSoulAbil) then
            nRate := _MAX(0, nRate - m_HumScatterBagAddRate);                                       //附魂
      end;

      if boDropall or (Random(nRate {3}) = 0) or (CheckSPCode(StdItem.Reserved, RE_SCATTER)) then begin
          if DropItemDown(UserItem, DropWide, True, ItemOfCreat, Self) then begin
            if m_btRaceServer = RC_PLAYOBJECT then begin
            if DelList = nil then DelList := TStringList.Create;
            DelList.AddObject(StdItem.Name, TObject(UserItem.MakeIndex));
            end;
            Dispose(UserItem);
            m_ItemList.Delete(i);
          end;
      end;
      end;
    end;
    if DelList <> nil then begin
      SendMsg(Self, RM_SENDDELITEMLIST, 0, Integer(DelList), 0, 0, '');
    end;
except
    on E: Exception do begin
      MainOutMessage(sExceptionMsg);
      MainOutMessage(E.Message);
    end;
end;
end;

procedure TPlayObject.SearchViewRange;
var
i                                     : Integer;
nStartX                               : Integer;
nEndX                                 : Integer;
nStartY                               : Integer;
nEndY                                 : Integer;
n18                                 : Integer;
n1C                                 : Integer;
nIdx                                  : Integer;
n24                                 : Integer;
MapCellInfo                           : pTMapCellinfo;
OSObject                              : pTOSObject;
BaseObject                            : TBaseObject;
MapItem                               : pTMapItem;
MapEvent                              : TEvent;
VisibleBaseObject                     : pTVisibleBaseObject;
VisibleMapItem                        : pTVisibleMapItem;
nCheckCode                            : Integer;
RidePet                               : TRidePet;
resourcestring
sExceptionMsg1                        = ' TPlayObject::SearchViewRange Code:%d';
sExceptionMsg2                        = ' TPlayObject::SearchViewRange 1-%d %s %s %d %d %d';
begin
if m_PEnvir = nil then begin
    MainOutMessage('SearchViewRange nil PEnvir');
    Exit;
end;

//if m_boOfflineGetGamePoint then Exit;

n24 := 0;
try
    nCheckCode := 2;
    for i := m_VisibleItems.Count - 1 downto 0 do begin
      pTVisibleMapItem(m_VisibleItems.Items).nVisibleFlag := 0;
    end;
    nCheckCode := 3;
    for i := m_VisibleEvents.Count - 1 downto 0 do begin
      TEvent(m_VisibleEvents.Items).nVisibleFlag := 0;
    end;
    nCheckCode := 4;
    for i := m_VisibleActors.Count - 1 downto 0 do begin
      pTVisibleBaseObject(m_VisibleActors.Items).nVisibleFlag := 0;
    end;
    nCheckCode := 5;
except
    MainOutMessage(Format(sExceptionMsg1, ));
    KickException();
end;
nCheckCode := 6;
nStartX := m_nCurrX - m_nViewRange;
nEndX := m_nCurrX + m_nViewRange;
nStartY := m_nCurrY - m_nViewRange;
nEndY := m_nCurrY + m_nViewRange;
try
    nCheckCode := 7;
    for n18 := nStartX to nEndX do begin
      nCheckCode := 8;
      for n1C := nStartY to nEndY do begin
      nCheckCode := 9;
      if m_PEnvir.GetMapCellInfo(n18, n1C, MapCellInfo) and
          (MapCellInfo.ObjList <> nil) then begin
          nCheckCode := 10;
          n24 := 1;
          nIdx := 0;
          while (True) do begin
            nCheckCode := 11;
            if MapCellInfo.ObjList.Count <= nIdx then Break;
            OSObject := MapCellInfo.ObjList.Items;
            nCheckCode := 12;
            if OSObject = nil then begin                                                            //释放对象
            MapCellInfo.ObjList.Delete(i);
            if MapCellInfo.ObjList.Count > 0 then Continue;
            nCheckCode := 121;
            MapCellInfo.ObjList.free;
            MapCellInfo.ObjList := nil;
            Break;
            end;
            if OSObject <> nil then begin
            nCheckCode := 13;
            if OSObject.btType = OS_MOVINGOBJECT then begin
                nCheckCode := 14;
                if (GetTickCount - OSObject.dwAddTime) >= 60 * 1000 then begin
                  Dispose(OSObject);
                  MapCellInfo.ObjList.Delete(nIdx);
                  if MapCellInfo.ObjList.Count > 0 then Continue;
                  MapCellInfo.ObjList.free;
                  MapCellInfo.ObjList := nil;
                  Break;
                end;
                nCheckCode := 15;
                BaseObject := TBaseObject(OSObject.CellObj);
                if BaseObject <> nil then begin
                  nCheckCode := 16;
                  if not BaseObject.m_boGhost and not
                  BaseObject.m_boFixedHideMode and not BaseObject.m_boObMode then begin
                  nCheckCode := 17;
                  if (m_btRaceServer < RC_ANIMAL) or
                      (m_Master <> nil) or
                      m_boCrazyMode or
                      m_boWantRefMsg or
                      ((BaseObject.m_Master <> nil) and (abs(BaseObject.m_nCurrX - m_nCurrX) <= 3) and (abs(BaseObject.m_nCurrY - m_nCurrY) <= 3)) or
                      (BaseObject.m_btRaceServer = RC_PLAYOBJECT) then begin
                      nCheckCode := 18;
                      UpdateVisibleGay(BaseObject);
                      nCheckCode := 19;
                  end;
                  end;
                end;
            end;
            nCheckCode := 20;
            if m_btRaceServer = RC_PLAYOBJECT then begin
                if OSObject.btType = OS_ITEMOBJECT then begin
                  nCheckCode := 21;

                  if (not pTMapItem(OSObject.CellObj).boForbidClear) and (((m_PEnvir <> nil) and m_PEnvir.m_boClearItem) or ((GetTickCount - OSObject.dwAddTime) > g_Config.dwClearDropOnFloorItemTime)) then begin
                  nCheckCode := 22;
                  Dispose(pTMapItem(OSObject.CellObj));
                  MapCellInfo.ObjList.Delete(nIdx);
                  Dispose(OSObject);                                                            //修正内存错误
                  nCheckCode := 23;
                  if MapCellInfo.ObjList.Count > 0 then Continue;
                  nCheckCode := 24;
                  MapCellInfo.ObjList.free;
                  MapCellInfo.ObjList := nil;
                  Break;
                  end;
                  nCheckCode := 25;
                  MapItem := pTMapItem(OSObject.CellObj);
                  nCheckCode := 28;
                  UpdateVisibleItem(n18, n1C, MapItem);
                  if (MapItem.OfBaseObject <> nil) or (MapItem.DropBaseObject <> nil) then begin
                  nCheckCode := 29;
                  if (GetTickCount - MapItem.dwCanPickUpTick) > g_Config.dwFloorItemCanPickUpTime {2 * 60 * 1000} then begin
                      nCheckCode := 30;
                      MapItem.OfBaseObject := nil;
                      MapItem.DropBaseObject := nil;
                  end else begin
                      nCheckCode := 31;
                      if TBaseObject(MapItem.OfBaseObject) <> nil then begin
                        nCheckCode := 32;
                        if TBaseObject(MapItem.OfBaseObject).m_boGhost then
                        MapItem.OfBaseObject := nil;
                      end;
                      nCheckCode := 33;
                      if TBaseObject(MapItem.DropBaseObject) <> nil then begin
                        nCheckCode := 34;
                        if TBaseObject(MapItem.DropBaseObject).m_boGhost then
                        MapItem.DropBaseObject := nil;
                      end;
                      nCheckCode := 35;
                  end;
                  end;
                end;
                nCheckCode := 36;
                if OSObject.btType = OS_EVENTOBJECT then begin
                  nCheckCode := 37;
                  MapEvent := TEvent(OSObject.CellObj);
                  if MapEvent.m_boVisible then begin
                  nCheckCode := 38;
                  UpdateVisibleEvent(n18, n1C, MapEvent);
                  end;
                  nCheckCode := 39;
                end;
            end
            end;                                                                                    //004B9B81 if OSObject <> nil then begin
            Inc(nIdx);
          end;                                                                                    //while (True) do begin
      end;
      end;                                                                                          //for n1C:= n10 to n14do begin
    end;                                                                                          //for n18:= n8 to nC do begin
except
    on E: Exception do begin
      MainOutMessage(Format(sExceptionMsg2, [n24, m_sCharName, m_sMapName,
      m_nCurrX, m_nCurrY, nCheckCode]));
      MainOutMessage(E.Message);
      KickException();
    end;
end;
nCheckCode := 40;
n24 := 2;
try
    n18 := 0;
    while (True) do begin
      if m_VisibleActors.Count <= n18 then Break;
      nCheckCode := 41;
      VisibleBaseObject := m_VisibleActors.Items;
      nCheckCode := 42;
      if VisibleBaseObject.nVisibleFlag = 0 then begin
      nCheckCode := 43;
      if m_btRaceServer = RC_PLAYOBJECT then begin
          nCheckCode := 44;
          BaseObject := TBaseObject(VisibleBaseObject.BaseObject);
          nCheckCode := 45;
          if not BaseObject.m_boFixedHideMode and (not BaseObject.m_boGhost) then begin             //01/21 修改防止人物退出时发送重复的消息占用带宽,人物进入隐身模式时人物不消失问题
            nCheckCode := 46;
            SendMsg(BaseObject, RM_DISAPPEAR, 0, 0, 0, 0, '');
          end;
          nCheckCode := 47;
      end;
      m_VisibleActors.Delete(n18);
      nCheckCode := 48;
      Dispose(VisibleBaseObject);
      nCheckCode := 49;
      Continue;
      end;
      nCheckCode := 50;
      if (m_btRaceServer = RC_PLAYOBJECT) and (VisibleBaseObject.nVisibleFlag = 2) then begin
      nCheckCode := 51;
      BaseObject := TBaseObject(VisibleBaseObject.BaseObject);
      nCheckCode := 52;
      if BaseObject <> Self then begin
          nCheckCode := 53;
          if BaseObject.m_boDeath then begin
            nCheckCode := 54;
            if BaseObject.m_boSkeleton then begin
            nCheckCode := 55;
            SendMsg(BaseObject, RM_SKELETON, BaseObject.m_btDirection,
                BaseObject.m_nCurrX, BaseObject.m_nCurrY, 0, '');
            nCheckCode := 56;
            end else begin
            nCheckCode := 57;
            SendMsg(BaseObject, RM_DEATH, BaseObject.m_btDirection, BaseObject.m_nCurrX, BaseObject.m_nCurrY, 0, BaseObject.GetShowName);
            nCheckCode := 58;
            end;
          end else begin
            nCheckCode := 59;
            SendMsg(BaseObject, RM_TURN, BaseObject.m_btDirection, BaseObject.m_nCurrX, BaseObject.m_nCurrY, CalcCent(BaseObject.m_WAbil.dwHP, BaseObject.m_WAbil.dwMaxHP), BaseObject.GetShowName);

            nCheckCode := 60;
            if (BaseObject.m_btRaceServer = RC_PLAYOBJECT) then begin
            nCheckCode := 61;
            if TPlayObject(BaseObject).m_boRideOn and
                TPlayObject(BaseObject).m_boRideFightOn then begin
                nCheckCode := 62;
                RidePet.nFeature := BaseObject.GetFeature(Self);
                nCheckCode := 63;
                if BaseObject.m_boPneuma and (BaseObject.m_PneumaObject <> nil) then begin
                  RidePet.btState := 1 + TPlayObject(BaseObject.m_PneumaObject).m_PetInfo.btRideFightSpeed;
                  RidePet.btSoul := TPlayObject(BaseObject.m_PneumaObject).m_PetInfo.btSoul;
                end else begin
                  RidePet.btState := 1 + TPlayObject(BaseObject).m_PetInfo.btRideFightSpeed;
                  RidePet.btState := 1 + TPlayObject(BaseObject).m_PetInfo.btSoul;
                end;
                nCheckCode := 64;
                SendMsg(BaseObject, RM_SITDOWN, BaseObject.m_btDirection,
                  MakeLong(BaseObject.m_nCurrX, BaseObject.m_nCurrY),
                  BaseObject.GetFeature(Self), 1, EnCodeBuffer(@RidePet, SizeOf(TRidePet)));
            end;
            end;
            nCheckCode := 65;
          end;
      end;
      end;
      Inc(n18);
    end;
except
    on E: Exception do begin
      MainOutMessage(Format(sExceptionMsg2, [n24, m_sCharName, m_sMapName,
      m_nCurrX, m_nCurrY, nCheckCode]));
      KickException();
    end;
end;
try
    i := 0;
    while (True) do begin
      if m_VisibleItems.Count <= i then Break;
      VisibleMapItem := m_VisibleItems.Items;
      if VisibleMapItem.nVisibleFlag = 0 then begin
      SendMsg(Self, RM_ITEMHIDE, 0, Integer(VisibleMapItem.MapItem),
          VisibleMapItem.nX, VisibleMapItem.nY, '');
      m_VisibleItems.Delete(i);
      Dispose(VisibleMapItem);
      Continue;
      end;                                                                                          //004B9F6C
      if VisibleMapItem.nVisibleFlag = 2 then begin
      SendMsg(Self, RM_ITEMSHOW, VisibleMapItem.wLooks, Integer(VisibleMapItem.MapItem), VisibleMapItem.nX, VisibleMapItem.nY, VisibleMapItem.sName);
      end;
      Inc(i);
    end;
    i := 0;
    while (True) do begin
      if m_VisibleEvents.Count <= i then Break;
      MapEvent := m_VisibleEvents.Items;
      if MapEvent.nVisibleFlag = 0 then begin
      SendMsg(Self, RM_HIDEEVENT, 0, Integer(MapEvent), MapEvent.m_nX,
          MapEvent.m_nY, '');
      m_VisibleEvents.Delete(i);
      Continue;
      end;
      if MapEvent.nVisibleFlag = 2 then begin
      SendMsg(Self, RM_SHOWEVENT,
          MapEvent.m_nEventType,
          Integer(MapEvent),
          MakeLong(MapEvent.m_nX, MapEvent.m_nEventParam),
          MapEvent.m_nY,
          '');
      end;
      Inc(i);
    end;
    //清理物品结束
    if ((m_PEnvir <> nil) and m_PEnvir.m_boClearItem) then
      m_PEnvir.m_boClearItem := False;
except
    MainOutMessage(m_sCharName + ',' +
      m_sMapName + ',' +
      IntToStr(m_nCurrX) + ',' +
      IntToStr(m_nCurrY) + ',' +
      ' SearchViewRange 3');

    KickException();
end;
end;

///////兼容客户端/////////Begin////////////////////

{发送添加交易物品}

procedure TPlayObject.SendAddDealItem(UserItem: pTUserItem);
begin
if UserItem = nil then Exit;
SendDefMessage(SM_DEALADDITEM_OK, 0, 0, 0, 0, '');
if (m_DealCreat <> nil) and (m_DealCreat.m_btRaceServer = RC_PLAYOBJECT) then begin
    //必须在这里就要保证下面的安全
    if Assigned(TPlayObject(m_DealCreat).m_VersionManage) then
    try
      TPlayObject(m_DealCreat).m_VersionManage.OnSendAddDealItem(Self, UserItem);
    except
      MainOutMessage(Format('TPlayObject::OnSendAddDealItem SoftVersionDate:%d', ));
    end;

    //    if (TPlayObject(m_DealCreat).m_nSoftVersionDateEx = 0) then begin
    //      VER19990SendAddDealItem(UserItem);
    //    end else begin
    //      VER19990SendAddDealItem(UserItem);
    //    end;

    m_DealCreat.m_DealLastTick := GetTickCount();
    m_DealLastTick := GetTickCount();
end;
end;

{删除交易框物品}

procedure TPlayObject.SendDelDealItem(UserItem: pTUserItem);
begin
if UserItem = nil then Exit;
SendDefMessage(SM_DEALDELITEM_OK, 0, 0, 0, 0, '');
if (m_DealCreat <> nil) and (m_DealCreat.m_btRaceServer = RC_PLAYOBJECT) then begin

    if Assigned(TPlayObject(m_DealCreat).m_VersionManage) then
    try
      TPlayObject(m_DealCreat).m_VersionManage.OnSendDelDealItem(Self, UserItem);
    except
      MainOutMessage(Format('TPlayObject::OnSendDelDealItem SoftVersionDate:%d', ));
    end;

    //    if (TPlayObject(m_DealCreat).m_nSoftVersionDateEx = 0) then begin
    //      VER19990SendDelDealItem(UserItem);
    //    end else begin
    //      VER19990SendDelDealItem(UserItem);
    //    end;

    m_DealCreat.m_DealLastTick := GetTickCount();
    m_DealLastTick := GetTickCount();
end;
end;

{获取玩家包裹物品数据}

procedure TPlayObject.ClientQueryBagItems;
begin
if Assigned(m_VersionManage) then
try
    m_VersionManage.OnQueryBagItems(Self);
except
    MainOutMessage(Format('TPlayObject::OnQueryBagItems SoftVersionDate:%d', ));
end;

if m_boBagSend then
    ClientSendBagOrder();                                                                           {包裹顺序}
end;

//处理添加包裹物品命令

procedure TPlayObject.SendAddItem(UserItem: pTUserItem);
begin
{兼容客户端}
if UserItem = nil then Exit;
if Assigned(m_VersionManage) then
try
    m_VersionManage.OnSendAddItem(Self, UserItem);
except
    MainOutMessage(Format('TPlayObject::OnSendAddItem SoftVersionDate:%d', ));
end;
end;

{发送删除的物品}

procedure TPlayObject.SendDelItems(UserItem: pTUserItem);
begin
if UserItem = nil then Exit;
if Assigned(m_VersionManage) then
try
    m_VersionManage.OnSendDelItems(Self, UserItem);
except
    MainOutMessage(Format('TPlayObject::OnSendDelItems SoftVersionDate:%d', ));
end;

end;

{更新物品数据}

procedure TPlayObject.SendUpdateItem(UserItem: pTUserItem; boDelay: Boolean = True);
begin
if UserItem = nil then Exit;
if Assigned(m_VersionManage) then
try
    m_VersionManage.OnSendUpdateItem(Self, UserItem, boDelay);
except
    MainOutMessage(Format('TPlayObject::OnSendUpdateItem SoftVersionDate:%d', ));
end;

end;

//查询玩家装备

procedure TPlayObject.ClientQueryUserState(BaseObject: TBaseObject; nX, nY: Integer);
resourcestring
sExceptionMsg                         = ' TPlayObject::ClientQueryUserState Code = %d';
var
UserItem                              : pTUserItem;
Hum                                 : TPlayObject;
nCheckCode                            : Integer;
begin
nCheckCode := 0;
try
    if BaseObject = nil then Exit;
    nCheckCode := 1;
    if not (BaseObject is TPlayObject) then Exit;
    //    {只允许查看玩家和心魔的装备}
    //    if (BaseObject.m_btRaceServer <> RC_PLAYOBJECT) then Exit;

      {只允许查看夺宝心魔的装备}
    //    if (BaseObject.m_btRaceServer = RC_EVIL) and (BaseObject.m_btRaceImg <> 253) then Exit;

      //关灯模式

    if (m_PEnvir.m_MapFlag.boSECRET and ((m_PEnvir.m_MapFlag.btSECRETRule and SECRET_RULE_DISABLEQUERY) <> 0)) then
    begin
      SysMsg('该地图不允许查看对手信息', c_Red, t_Hint);
      Exit;
    end;

    if (BaseObject.m_btRaceServer = RC_PLAYOBJECT) then begin
      if (TPlayObject(BaseObject).m_boSecretMode) and (not TPlayObject(BaseObject).m_boCheckItem) then begin
      SysMsg('对方处于神秘人模式,不允许查看装备信息', c_Red, t_Hint);
      Exit;
      end;
    end;

    nCheckCode := 2;
    {查看死亡玩家的装备}
    if (nX = 0) and (nY = 0) then begin
      if (BaseObject <> nil) and (not BaseObject.m_boGhost) then begin
      nX := BaseObject.m_nCurrX;
      nY := BaseObject.m_nCurrY;
      end;
    end;
    nCheckCode := 3;
    if (not CretInNear10XY(BaseObject, nX, nY)) then Exit;

    nCheckCode := 4;
    if Assigned(m_VersionManage) then
    try
      m_VersionManage.OnQueryUserState(Self, BaseObject);
    except
      MainOutMessage(Format('TPlayObject::OnQueryUserState SoftVersionDate:%d', ));
    end;

    nCheckCode := 5;
    if (BaseObject.m_btRaceServer = RC_PLAYOBJECT) then begin
      with TPlayObject(BaseObject) do
      begin
      //发送骑站数据
      nCheckCode := 6;
      if m_boRideOn then begin
          if m_boPneuma and (m_PneumaObject <> nil) then begin
            Hum := TPlayObject(BaseObject.m_PneumaObject);                                          //元神骑乘
            Hum.GetUserItemByMakeIndex(Hum.m_PetInfo.nMakeIndex, UserItem);
          end else begin
            GetUserItemByMakeIndex(m_PetInfo.nMakeIndex, UserItem);                              //本体骑乘
          end;

          Self.SendPetAttribute(TPlayObject(BaseObject), 1, UserItem);
      end;
      nCheckCode := 7;
      //发送魂佑灵兽信息
      if m_boBeast then begin
          GetUserItemByMakeIndex(m_PetInfo.nMakeIndex, UserItem);
          Self.SendPetAttribute(TPlayObject(BaseObject), 0, UserItem);
      end;
      end;

      nCheckCode := 8;


      nCheckCode := 9;
      SendDemonDanInfo(0, BaseObject);
      SendConstellationStarLv(BaseObject);
      nCheckCode := 10;

      {脚本触发}
      m_sScriptParam := BaseObject.m_sCharName;
      ExecuteScript(g_FunctionNPC, '@查询玩家装备');
    end;
except
    on E: Exception do begin
      MainOutMessage(Format(sExceptionMsg, ));
      MainOutMessage(E.Message);
    end;
end;
end;

{发送宠物包裹数据}

procedure TPlayObject.SendPetBagItems;
begin
SendDefMessage(SM_PETBAGSIZE, Integer(Self), 0, m_nPetShopSize, m_nPetBagSize, '');
if Assigned(m_VersionManage) then
try
    m_VersionManage.OnSendPetBagItems(Self);
except
    MainOutMessage(Format('TPlayObject::OnSendPetBagItems SoftVersionDate:%d', ));
end;
end;

procedure TPlayObject.SendAddPetItem(UserItem: pTUserItem);
begin
if Assigned(m_VersionManage) then
try
    m_VersionManage.OnSendAddPetItem(Self, UserItem);
except
    MainOutMessage(Format('TPlayObject::OnSendAddPetItem SoftVersionDate:%d', ));
end;
end;

{发送仓库物品列表}

procedure TPlayObject.SendSaveItemList(nBaseObject: Integer; boFast: Boolean);
begin
if Assigned(m_VersionManage) then
try
    m_VersionManage.OnSendSaveItemList(Self, nBaseObject, boFast);
except
    MainOutMessage(Format('TPlayObject::OnSendSaveItemList SoftVersionDate:%d', ));
end;
end;

//发送身上物品

procedure TPlayObject.SendUseitems;
begin
if Assigned(m_VersionManage) then
try
    m_VersionManage.OnSendUseitems(Self);
except
    MainOutMessage(Format('TPlayObject::OnSendUseitems SoftVersionDate:%d', ));
end;
end;

//发送内视装备物品

procedure TPlayObject.SendEntopticItems;
begin
if Assigned(m_VersionManage) then
try
    m_VersionManage.OnSendEntopticItems(Self);
except
    MainOutMessage(Format('TPlayObject::OnSendEntopticItems SoftVersionDate:%d', ));
end;
end;

//发送我的摊位物品列表给某个玩家

procedure TPlayObject.SendShopItems(BaseObject: TBaseObject; opcode: word);
var
PlayObject                            : TPlayObject;
begin
if not (BaseObject is TPlayObject) then Exit;
PlayObject := BaseObject as TPlayObject;
if Assigned(PlayObject.m_VersionManage) then
try
    PlayObject.m_VersionManage.OnSendShopItems(Self, PlayObject, opcode);
except
    MainOutMessage(Format('TPlayObject::OnSendShopItems SoftVersionDate:%d', ));
end;

//if (PlayObject.m_nSoftVersionDateEx = 0) then begin
//    VER19990SendShopItems(PlayObject,opcode);
//end else begin
//    VER19990SendShopItems(PlayObject,opcode);
//end;

end;

procedure TPlayObject.SendTigerItem();
begin
if m_boPneuma and not m_boInosculatePneuma then Exit;

if Assigned(m_VersionManage) then
try
    m_VersionManage.OnSendTigerItem(Self);
except
    MainOutMessage(Format('TPlayObject::OnSendTigerItem SoftVersionDate:%d', ));
end;
end;

///////兼容客户端////////END/////////////////////

procedure TPlayObject.SendAddMagic(UserMagic: pTUserMagic);                                       //004D12F4
var
ClientMagic                           : TClientMagic;
pMagicOrder                           : string;
begin
UserMagic.GetClientMagic(@ClientMagic);
m_defMsg := MakeDefaultMsg(SM_ADDMAGIC, 0, 0, 0, 1);
SendSocket(@m_defMsg, EnCodeBuffer(@ClientMagic, SizeOf(TClientMagic)));

//处理铁血神技技能顺序
{if UserMagic.GetMagIdx in then begin
    pMagicOrder := ReverseString(m_MagicOrder);
    if UserMagic.GetMagIdx in then
      pMagicOrder := pMagicOrder + '1';
    if UserMagic.GetMagIdx in then
      pMagicOrder := pMagicOrder + '2';
    if UserMagic.GetMagIdx in then
      pMagicOrder := pMagicOrder + '3';
    if UserMagic.GetMagIdx in then
      pMagicOrder := pMagicOrder + '4';

    m_MagicOrder := ReverseString(pMagicOrder);
    SendDefMessage(1650, 0, HexToInt('$' + m_MagicOrder), 220, 0, '');
end;
       }
end;

//发送给客户端调整点数值

procedure TPlayObject.SendAdjustBonus;
var
sSENDMSG                              : string;
begin
m_defMsg := MakeDefaultMsg(SM_ADJUST_BONUS, m_nBonusPoint, 0, 0, 0);
sSENDMSG := '';
case m_btJob of
    0: sSENDMSG := EnCodeBuffer(@g_Config.BonusAbilofWarr, SizeOf(TNakedAbility))
      + '/' +
      EnCodeBuffer(@m_BonusAbil, SizeOf(TNakedAbility)) + '/' +
      EnCodeBuffer(@g_Config.NakedAbilofWarr, SizeOf(TNakedAbility));
    1: sSENDMSG := EnCodeBuffer(@g_Config.BonusAbilofWizard,
      SizeOf(TNakedAbility)) + '/' +
      EnCodeBuffer(@m_BonusAbil, SizeOf(TNakedAbility)) + '/' +
      EnCodeBuffer(@g_Config.NakedAbilofWizard, SizeOf(TNakedAbility));
    2: sSENDMSG := EnCodeBuffer(@g_Config.BonusAbilofTaos, SizeOf(TNakedAbility))
      + '/' +
      EnCodeBuffer(@m_BonusAbil, SizeOf(TNakedAbility)) + '/' +
      EnCodeBuffer(@g_Config.NakedAbilofTaos, SizeOf(TNakedAbility));
end;
SendSocket(@m_defMsg, sSENDMSG);
end;

procedure TPlayObject.SendChangeGuildName;
begin
if m_MyGuild <> nil then begin
    SendDefMessage(SM_CHANGEGUILDNAME, 0, TGuild(m_MyGuild).btGuildFlag, 0, 0, TGuild(m_MyGuild).sGuildName + '/' + m_sGuildRankName);
end else begin
    SendDefMessage(SM_CHANGEGUILDNAME, 0, 0, 0, 0, '');
end;
end;

//直接发送消息(消息已经处理完毕)

procedure TPlayObject.SendDefMessage(wIdent: word; nRecog: Integer; nParam,
nTag, nSeries: word; sMsg: string; boEn: Boolean);                                                //004CAD6C
begin
m_defMsg := MakeDefaultMsg(wIdent, nRecog, nParam, nTag, nSeries);
if sMsg <> '' then
begin
    if boEn then
      SendSocket(@m_defMsg, sMsg)
    else
      SendSocket(@m_defMsg, EnCodeString(sMsg));
end
else
    SendSocket(@m_defMsg, '');
end;

procedure TPlayObject.SendDelItemList(ItemList: TStringList);
var
i                                     : Integer;
s10                                 : string;
begin
s10 := '';
for i := 0 to ItemList.Count - 1 do begin
    s10 := s10 + ItemList.Strings + '/' +
      IntToStr(Integer(ItemList.Objects)) + '/';
end;
m_defMsg := MakeDefaultMsg(SM_DELITEMS, 0, 0, 0, ItemList.Count);
SendSocket(@m_defMsg, EnCodeString(s10));

SendDelayMsg(Self, CM_QUERYBAGITEMS, 0, 0, 0, 0, '', 300);
end;

procedure TPlayObject.SendDelMagic(UserMagic: pTUserMagic);
var
pMagicOrder                           : string;
i, nMaxLen                            : Integer;
MyMagic                               : pTUserMagic;
begin
//处理铁血神技技能顺序

m_defMsg := MakeDefaultMsg(SM_DELMAGIC, UserMagic.GetMagIdx, 0, 0, 1);
SendSocket(@m_defMsg, '')
end;

//装载并发送好友列表

procedure TPlayObject.SendFiendList(const b: ShortInt = -1);
var
i                                     : Integer;
sMsg, sAmbit                        : string;
ClanAmbit                           : pTClanAmbit;
begin
//发送好友名单
if (b = -1) or (b = 0) then begin
    sMsg := '';
    for i := 0 to m_FriendsList.Count - 1 do begin
      sMsg := sMsg + m_FriendsList + '/';
    end;
    if Length(sMsg) > 0 then
      SendDefMessage(SM_SENDFRIENDS, 0, 0, 0, 0, sMsg);
end;
//发送师傅名单
if (b = -1) or (b = 1) then begin
    if (Length(m_sMasterName) > 0) and (not m_boMaster) then
      SendDefMessage(SM_SENDFRIENDS, 0, 1, 0, 0, m_sMasterName);
end;
//发送徒弟名单
if (b = -1) or (b = 2) then begin
    sMsg := '';
    if m_boMaster then begin
      for i := 1 to 3 do begin
      if m_sMasterName <> '' then
          sMsg := sMsg + m_sMasterName + '/';
      end;
      SendDefMessage(SM_SENDFRIENDS, 0, 2, 0, 0, sMsg);
    end;
end;
//发送配偶名单
if (b = -1) or (b = 3) then begin
    if (Length(m_sDearName) > 0) then
      SendDefMessage(SM_SENDFRIENDS, 0, 3, 0, 0, m_sDearName);
end;

//发送宗族名单
if (b = -1) or (b = 4) then begin
    sMsg := '';
    if (m_MyClan <> nil) then begin
      with TClan(m_MyClan) do begin
      sMsg := Format('%s/%s/%d,%d,%d,%d/', );
      for i := 0 to m_MemberList.Count - 1 do begin
          ClanAmbit := pTClanAmbit(m_MemberList.GetValues(m_MemberList.Keys));
          if (ClanAmbit.Ambit > 2) then begin
            if (ClanAmbit.Ambit mod 2) = 0 then
            sAmbit := '2'
            else
            sAmbit := '1';
          end else
            sAmbit := '0';
          sMsg := Format('%s%s,%d,%d/%s/', ])
      end;
      end;
      SendDefMessage(SM_SENDFRIENDS, 0, 4, 0, 0, sMsg);
    end;
end;
end;

procedure TPlayObject.SendGroupMembers;
var
i                                     : Integer;
PlayObject                            : TPlayObject;
sSENDMSG                              : string;
begin
sSENDMSG := '';
for i := 0 to m_GroupMembers.Count - 1 do begin
    PlayObject := TPlayObject(m_GroupMembers.Objects);
    sSENDMSG := sSENDMSG + PlayObject.m_sCharName + '/';
end;
for i := 0 to m_GroupMembers.Count - 1 do begin
    PlayObject := TPlayObject(m_GroupMembers.Objects);
    PlayObject.SendDefMessage(SM_GROUPMEMBERS, 0, 0, 0, 0, sSENDMSG);
end;
end;

procedure TPlayObject.SendGuildTowerInfo();
var
sGuildJobMsg                        : string;
i, ii, j, nTowerGrade               : Integer;
nPermission                           : Integer;
resourcestring
sOfficialMsg                        = '%d/%d/%d/%d/%d/%s/';
begin
if m_MyGuild = nil then Exit;
try
    nTowerGrade := _MIN(10, TGuild(m_MyGuild).btTowerGrade);
    if nTowerGrade > 0 then begin
      sGuildJobMsg := TGuild(m_MyGuild).GetChiefName + '/';
      for i := 1 to 10 do begin
      sGuildJobMsg := sGuildJobMsg + Format(sOfficialMsg, , nGuildOfficialCountMax, btGuildOfficialCrony, nGuildOfficialPrice, sGuildOfficial]);
      end;
      if (m_nGuildRankNo in ) then nPermission := nGuildOfficialPermission else nPermission := 1024;

      g_LargePacketManage.Init;
      g_LargePacketManage.WriteBuffer(m_GuildTowerInfo, SizeOf(TGuildTowerInfo));
      g_LargePacketManage.WriteString(sGuildJobMsg);
      m_defMsg := MakeDefaultMsg(SM_GUILDOFFICIAL, m_nGuildGold, nTowerGrade, nPermission, 0);
      SendSocket(@m_defMsg, g_LargePacketManage.GetMsg);
    end;
except
    on E: Exception do begin
      MainOutMessage('procedure TPlayObject.SendGuildTowerInfo');
      MainOutMessage(E.Message);
    end;
end;
end;

procedure TPlayObject.SendGuildTowerRes();
var
Guild                                 : TGuild;
TowerRes                              : TGuildTowerRes;
begin
if m_MyGuild = nil then Exit;
Guild := TGuild(m_MyGuild);
TowerRes := Guild.GuildTowerRes;
TowerRes.nOreMax := 3000;
TowerRes.nGemMax := 3000;
TowerRes.nWoodMax := 3000;
TowerRes.nBarMax := 3000;
TowerRes.nRockMax := 3000;
m_defMsg := MakeDefaultMsg(SM_GUILDTOWER, Guild.dwGuildGold, 1, 0, 0);
SendSocket(@m_defMsg, EnCodeBuffer(@TowerRes, SizeOf(TGuildTowerRes)));
end;

procedure TPlayObject.SendLogon;
var
MessageBodyL                        : TMessageBodyL;
nRecog, nMaxDamage                  : Integer;
begin
m_defMsg := MakeDefaultMsg(SM_NEWMAP, Integer(Self), m_nCurrX, m_nCurrY, 10240);
SendSocket(@m_defMsg, EnCodeString(m_PEnvir.m_MapFlag.sClientMapName));

MessageBodyL.nFeature := GetFeatureToLong(Self);
MessageBodyL.nCharStatus := m_nCharStatus;
if m_boAllowGroup then
    MessageBodyL.nFlag := MakeLong(MakeWord(1, 0), GetGender)
else
    MessageBodyL.nFlag := MakeLong(0, GetGender);
MessageBodyL.nDressShape := m_nDressShape;

m_defMsg := MakeDefaultMsg(SM_LOGON, Integer(Self), m_nCurrX, m_nCurrY, MakeWord(m_btDirection, m_btGender));
SendSocket(@m_defMsg, EnCodeBuffer(@MessageBodyL, SizeOf(TMessageBodyL)));


end;

procedure TPlayObject.SendMagic_LvExp_Msg(const UserMagic: pTUserMagic; dwDelay: LongWord);
begin
Assert(UserMagic <> nil, 'TPlayObject::SendMagic_LvExp_Msg');
if UserMagic.GetMagIdx = 184 then begin
    //终极连击需要发送添加的技能的消息来更新最高连击点...
    SendAddMagic(UserMagic);
    Exit;
end;
SendDelayMsg(Self, RM_MAGIC_LVEXP,
    0,
    UserMagic.GetMagIdx,
    UserMagic.btLevel,
    UserMagic.nTranPoint,
    '',
    dwDelay);
end;

//地图描述命令的处理

procedure TPlayObject.SendMapDescription;
var
nMUSICID                              : Integer;
sMapDesc                              : string;
begin
nMUSICID := 0;
if m_PEnvir.m_MapFlag.boMUSIC then nMUSICID := m_PEnvir.m_MapFlag.nMUSICID;

if m_sMapNewDesc <> '' then
    sMapDesc := m_sMapNewDesc
else
    sMapDesc := m_PEnvir.m_sMapDesc;
if m_boFlyer then
    SendDefMessage(SM_MAPDESCRIPTION, nMUSICID, 0, 0, 0, sMapDesc + '上空')
else
    SendDefMessage(SM_MAPDESCRIPTION, nMUSICID, 0, 0, 0, sMapDesc)
end;

//上线时,发送我的好友到客户端,同时向在线好友发送我的状态
//state=0 表示下线或隐身

procedure TPlayObject.SendMeOnlineState(State: byte; b: ShortInt = -1);
var
i                                     : Integer;
sOtherName                            : string;
Hum                                 : TPlayObject;
begin
if (b = -1) or (b = 0) then begin
    for i := 0 to m_FriendsList.Count - 1 do begin
      //检查对方的状态
      sOtherName := m_FriendsList;
      Hum := UserEngine.GetPlayObject(sOtherName);
      //对方在线
      if (Hum <> nil) and (not Hum.m_boDeath) and (not Hum.m_boGhost) then begin
      if (Hum.m_MyGuild <> nil) then
          sOtherName := sOtherName + Chr($00) + TGuild(Hum.m_MyGuild).sGuildName;

      if State <> 0 then
          SendDefMessage(SM_PLAYERONLINE, State, 0, MakeWord(Hum.m_btAmbitLevel, Hum.m_btAmbitKind), MakeWord(Hum.m_WAbil.level, Hum.m_btJob), sOtherName);

      //向对方发送好友上/下线消息
      sOtherName := m_sCharName;
      if (m_MyGuild <> nil) then
          sOtherName := sOtherName + Chr($00) + TGuild(m_MyGuild).sGuildName;
      Hum.SendDefMessage(SM_PLAYERONLINE, State, 0, MakeWord(m_btAmbitLevel, m_btAmbitKind), MakeWord(m_WAbil.level, m_btJob), sOtherName);
      end;
    end;
end;

//发送师傅上线通知
if (b = -1) or (b = 1) then begin
    if m_boMaster then begin
      for i := 1 to 3 do begin
      if m_sMasterName = '' then Continue;
      sOtherName := m_sMasterName;
      Hum := UserEngine.GetPlayObject(sOtherName);
      if (Hum <> nil) and (not Hum.m_boDeath) and (not Hum.m_boGhost) then begin
          if (Hum.m_MyGuild <> nil) then
            sOtherName := sOtherName + Chr($00) + TGuild(Hum.m_MyGuild).sGuildName;
          if State <> 0 then                                                                        //发送给自己 师傅在线
            SendDefMessage(SM_PLAYERONLINE, State, 2, MakeWord(Hum.m_btAmbitLevel, Hum.m_btAmbitKind), MakeWord(Hum.m_WAbil.level, Hum.m_btJob), sOtherName);

          //向对方发送上线消息                                                                        //发送给师傅,徒弟上线
          sOtherName := m_sCharName;
          if (m_MyGuild <> nil) then
            sOtherName := sOtherName + Chr($00) + TGuild(m_MyGuild).sGuildName;
          Hum.SendDefMessage(SM_PLAYERONLINE, State, 1, MakeWord(m_btAmbitLevel, m_btAmbitKind), MakeWord(m_WAbil.level, m_btJob), sOtherName);
      end;
      end;
    end;
end;

//发送徒弟上线通知
if (b = -1) or (b = 2) then begin
    if not m_boMaster and (m_sMasterName <> '') then begin
      sOtherName := m_sMasterName;
      Hum := UserEngine.GetPlayObject(sOtherName);
      if (Hum <> nil) and (not Hum.m_boDeath) and (not Hum.m_boGhost) then begin
      if (Hum.m_MyGuild <> nil) then
          sOtherName := sOtherName + Chr($00) + TGuild(Hum.m_MyGuild).sGuildName;
      if State <> 0 then                                                                        //发送给自己 师傅在线
          SendDefMessage(SM_PLAYERONLINE, State, 1, MakeWord(Hum.m_btAmbitLevel, Hum.m_btAmbitKind), MakeWord(Hum.m_WAbil.level, Hum.m_btJob), sOtherName);

      //向对方发送上线消息                                                                        //发送给师傅,徒弟上线
      sOtherName := m_sCharName;
      if (m_MyGuild <> nil) then
          sOtherName := sOtherName + Chr($00) + TGuild(m_MyGuild).sGuildName;
      Hum.SendDefMessage(SM_PLAYERONLINE, State, 2, MakeWord(m_btAmbitLevel, m_btAmbitKind), MakeWord(m_WAbil.level, m_btJob), sOtherName);
      end;
    end;
end;

//发送夫妻上线通知
if (b = -1) or (b = 3) then begin
    if (m_DearHuman <> nil) and (not m_DearHuman.m_boDeath) and (not m_DearHuman.m_boGhost) then begin
      sOtherName := m_sDearName;
      if (m_DearHuman.m_MyGuild <> nil) then
      sOtherName := sOtherName + Chr($00) + TGuild(m_DearHuman.m_MyGuild).sGuildName;
      if State <> 0 then
      SendDefMessage(SM_PLAYERONLINE, State, 3, MakeWord(m_DearHuman.m_btAmbitLevel, m_DearHuman.m_btAmbitKind), MakeWord(m_DearHuman.m_WAbil.level, m_DearHuman.m_btJob), sOtherName);

      //向对方发送上线消息
      sOtherName := m_sCharName;
      if (m_MyGuild <> nil) then
      sOtherName := sOtherName + Chr($00) + TGuild(m_MyGuild).sGuildName;
      m_DearHuman.SendDefMessage(SM_PLAYERONLINE, State, 3, MakeWord(m_btAmbitLevel, m_btAmbitKind), MakeWord(m_WAbil.level, m_btJob), sOtherName);
    end;
end;

//宗族消息
if (b = -1) or (b = 4) then begin
    if (m_MyClan <> nil) then begin
      for i := 0 to TClan(m_MyClan).m_MemberList.Count - 1 do begin
      sOtherName := TClan(m_MyClan).m_MemberList.Keys;
      Hum := UserEngine.GetPlayObject(sOtherName);
      //对方在线
      if (Hum <> nil) and (not Hum.m_boDeath) and (not Hum.m_boGhost) then begin
          if (Hum.m_MyGuild <> nil) then
            sOtherName := sOtherName + Chr($00) + TGuild(Hum.m_MyGuild).sGuildName;

          if State <> 0 then
            SendDefMessage(SM_PLAYERONLINE, State, 4, MakeWord(Hum.m_btAmbitLevel, Hum.m_btAmbitKind), MakeWord(Hum.m_WAbil.level, Hum.m_btJob), sOtherName);

          //向对方发送好友上/下线消息
          sOtherName := m_sCharName;
          if (m_MyGuild <> nil) then
            sOtherName := sOtherName + Chr($00) + TGuild(m_MyGuild).sGuildName;
          Hum.SendDefMessage(SM_PLAYERONLINE, State, 4, MakeWord(m_btAmbitLevel, m_btAmbitKind), MakeWord(m_WAbil.level, m_btJob), sOtherName);
      end;
      end;
    end;
end;
end;

procedure TPlayObject.SendNearbyGuildMemberList;
var
i                                     : Integer;
Str                                 : string;
BaseObjectList                        : TList;
BaseObject                            : TBaseObject;
begin
Str := '';
BaseObjectList := TList.Create;
m_PEnvir.GetRangeBaseObject(m_nCurrX, m_nCurrY, 10, True, BaseObjectList);
for i := 0 to BaseObjectList.Count - 1 do begin
    BaseObject := TBaseObject(BaseObjectList.Items);
    if (BaseObject.m_btRaceServer <> RC_PLAYOBJECT) then Continue;
    if (BaseObject.m_boPneuma) or (BaseObject = Self) or (BaseObject.m_MyGuild <> m_MyGuild) then Continue;
    Str := Str + BaseObject.m_sCharName + '/' + IntToStr(BaseObject.m_nGuildGold) + '/';
end;
BaseObjectList.free;
if Str <> '' then begin
    SendDefMessage(SM_GUILDOFFICIALPLAYER, 0, 0, 0, 0, Str);
end;
end;

//极品阁

procedure TPlayObject.SendNonSuchPavilion(nSerial: Integer);
var
G                                     : TGuild;
i, nCount                           : Integer;
UserItem                              : pTUserItem;
boView                              : Boolean;
begin
if m_MyGuild = nil then Exit;
G := TGuild(m_MyGuild);
if not G.boTowerStatus then begin
    SendDefMessage(SM_TREASUREPAVILION, 0, 4, 0, 0, '通灵塔资源不足被封闭,无法进入极品阁。');
    Exit;
end;
try
    boView := False;
    nCount := Length(G.m_TreasurePavilion);
    for i := 0 to nCount - 1 do begin
      if G.m_TreasurePavilion.btPos = nSerial then begin
      boView := (G.m_TreasurePavilion.btState = 4);
      Break;
      end;
    end;

    m_boInNonSuchPavilion := False;
    if not boView then begin
      GetUserItemByName('灵皓石', UserItem);
      if UserItem = nil then begin
      SendDefMessage(SM_TREASUREPAVILION, 0, 4, 0, 0, '您包裹内没有灵皓石,请到商城购买。');
      Exit;
      end else begin
      m_boInNonSuchPavilion := True;
      SendDelItems(UserItem);
      DelBagItem(UserItem.MakeIndex, '灵皓石');
      WeightChanged;
      m_sScriptParam := IntToStr(nSerial);
      ExecuteScript(g_GuildTowerNPC, '@进入极品阁');
      end;
    end;

    if Assigned(m_VersionManage) then
    try
      m_VersionManage.OnSendNonSuchPavilion(Self, G);
    except
      MainOutMessage(Format('TPlayObject::OnSendNonSuchPavilion SoftVersionDate:%d', ));
    end;

except
    on E: Exception do begin
      MainOutMessage('procedure TPlayObject.SendTreasurePavilion');
      MainOutMessage(E.Message);
    end;
end;
end;

//发送公告

procedure TPlayObject.SendNotice;                                                                   //004DA490
resourcestring
sExceptionMsg                         = ' TPlayObject::SendNotice Code=%d';
type
TREC = packed record
    n: byte;
    m: word;
end;
var
LoadList                              : TStringList;
sNoticesg                           : string;
Rec                                 : array of TREC;
i, nCode, nType                     : Integer;
nCheckCode                            : Integer;
MessageBodyW                        : TMessageBodyW;
begin
{$IF COUNTRYSYSTEM = 1}
//根据官职等级获得官职名称
if m_boPneuma and (m_PneumaObject <> nil) then begin
    m_btCountry := m_PneumaObject.m_btCountry;
end;
if (m_btCountry > 0) and (g_OffPosList.Count > 0) then begin
    if m_btOfficialPos >= g_OffPosList.Count then
      m_sOffName := g_OffPosList
    else
      m_sOffName := g_OffPosList;
end;
{$IFEND}
nCheckCode := 0;
try
    SendDefMessage(1667, -1, 0, 0, 0, '');                                                          //未知
    {未知}
    QuerySubAbility();

    if g_Config.boClassicServer then begin
      SendDefMessage(SM_SRVVERSION, Integer(Self), 0, 0, 0, m_VersionManage.ServerVerSion);
    end else begin
      if g_Config.boTimeBackServer then
      SendDefMessage(SM_SRVVERSION, Integer(Self), 256, 2, 0, m_VersionManage.ServerVerSion);

      if g_Config.boMagicCityServer then
      SendDefMessage(SM_SRVVERSION, Integer(Self), 256, 5, 0, m_VersionManage.ServerVerSion);
{$IF DEMONSERVER = 1}
      if g_Config.boNightMareServer then
      SendDefMessage(SM_SRVVERSION, Integer(Self), 256, 5, 2, m_VersionManage.ServerVerSion);
{$IFEND}
      if g_Config.botimeServer then
      SendDefMessage(SM_SRVVERSION, Integer(Self), 256, 7, 0, m_VersionManage.ServerVerSion);      //时长区
    end;

    FillChar(Rec, SizeOf(TREC) * 6, 0);
    Rec.n := $0A;
    Rec.n := $19;
    Rec.n := $2D;
    Rec.n := $4B;
    Rec.n := $96;
    Rec.n := $FA;
    m_defMsg := MakeDefaultMsg(1840, Integer(Self), 3, 0, 6);
    SendSocket(@m_defMsg, EnCodeBuffer(@Rec, SizeOf(TREC) * 6));

    SendDefMessage(SM_1809, 0, 0, 0, 2, '');                                                      //未知
    nCheckCode := 1;
    if m_boPneuma then begin
      SendDefMessage(SM_BAGSIZE, Integer(Self), 0, m_nBagSize, 0, '');
    end;
    nCheckCode := 2;

    SendDefMessage(1096, 0, 1, 0, 0, '');

    if not m_boPneuma then begin
      SendDefMessage(SM_PERSONALSIGN, Integer(Self), 1, 0, m_wPersonalCode, m_sPersonalSign);
      SendDefMessage(SM_PERSONALSIGN, Integer(Self), 2, 0, 0, m_sTmpRank);
    end else
      SendDefMessage(SM_TASKINFO, 0, 0, 0, 0, '');
    nCheckCode := 5;
    m_nCharStatus := GetCharStatus();
    nCheckCode := 6;
    m_nMagicStatus := GetMagicStatus();
    nCheckCode := 7;
    //发送地图信息
    m_defMsg := MakeDefaultMsg(SM_NEWMAP, Integer(Self), m_nCurrX, m_nCurrY, 10240);                // nObjCount);
    SendSocket(@m_defMsg, EnCodeString(m_PEnvir.m_MapFlag.sClientMapName));
    nCheckCode := 9;
    SendMapDescription;
    nCheckCode := 10;
    //发送名字
    SendDefMessage(SM_9609, Integer(Self), 0, 0, 0, m_sCharName);
    m_defMsg := MakeDefaultMsg(SM_USERNAME, Integer(Self), GetCharColor(Self), 0, 0);
    SendSocket(@m_defMsg, EnCodeString(GetShowName));
    nCheckCode := 11;
    //发送公告信息
    ExecuteScript(g_FunctionNPC, '@Notice');
    nCheckCode := 12;
    if not m_boSendNotice then begin
      nCheckCode := 14;
      LoadList := TStringList.Create;
      Noticeanager.GetNoticesg('Notice', LoadList);
      sNoticesg := '';
      for i := 0 to LoadList.Count - 1 do begin
      sNoticesg := sNoticesg + LoadList.Strings + #$20#$1B;
      end;
      LoadList.free;
      nCheckCode := 15;
      if g_FunctionNPC <> nil then
      sNoticesg := g_FunctionNPC.GetLineVariableText(Self, sNoticesg);
      SendDefMessage(SM_SENDNOTICE, Integer(Self), 257, 38, 0, sNoticesg);

      m_boSendNotice := True;
    end;
    ExecuteScript(g_ManageNPC, '@_历_活跃_HOME');
    if (g_Config.boMagicCityServer){$IF DEMONSERVER = 1} or (g_Config.boNightMareServer){$IFEND} then begin
      ExecuteScript(g_ManageNpc, '@_活力值_MAIN');
    end;
    if g_Config.boTimeBackServer then begin
      SendDefMessage(SM_SRVVERSION, Integer(Self), 256, 2, 0, m_VersionManage.ServerVerSion);
    end else if g_Config.boMagicCityServer then begin
      SendDefMessage(SM_SRVVERSION, Integer(Self), 256, 5, 0, m_VersionManage.ServerVerSion);
{$IF DEMONSERVER = 1}
    end else if g_Config.boNightMareServer then begin
      SendDefMessage(SM_SRVVERSION, Integer(Self), 256, 5, 2, m_VersionManage.ServerVerSion);
{$IFEND}
    end else if g_Config.botimeServer then begin
      SendDefMessage(SM_SRVVERSION, Integer(Self), 256, 7, 0, m_VersionManage.ServerVerSion);      //时长区
    end else begin
      SendDefMessage(SM_SRVVERSION, Integer(Self), 0, 0, 0, m_VersionManage.ServerVerSion);
      //发送练体信息

    end;

    //发送宗族徽记
    if (m_ClanInsignia.sClanName <> '') and (m_ClanInsignia.sGuildName <> '') and (m_ClanInsignia.sInsignia <> '') then begin
      g_PacketManage3.Init;
      g_PacketManage3.WriteInteger(1);
      g_PacketManage3.WriteInteger(Integer(Self));
      g_PacketManage3.WriteString(m_ClanInsignia.sClanName, SizeOf(m_ClanInsignia.sClanName));
      g_PacketManage3.WriteByte(0);
      g_PacketManage3.WriteString(m_ClanInsignia.sGuildName, SizeOf(m_ClanInsignia.sGuildName));
      g_PacketManage3.WriteByte(0);
      g_PacketManage3.WriteString(m_ClanInsignia.sInsignia, SizeOf(m_ClanInsignia.sInsignia));
      g_PacketManage3.WriteByte(0);
      g_PacketManage3.WriteInteger(m_ClanInsignia.Time);
      SendDefMessage(2119, Integer(Self), 0, 0, 0, g_PacketManage3.GetMsg(), True);
    end;

    i := GetFeatureToLong(Self);
    m_defMsg := MakeDefaultMsg(SM_FEATURECHANGED, Integer(Self), LoWord(i), HiWord(i), GetGender);
    SendSocket(@m_defMsg, GetFeatureChangedMsg());
    nCheckCode := 18;
    nCode := 0;
    nType := 0;
    if not g_Config.boClassicServer then begin                                                      //修为系统

      if g_Config.boClientRedPacket then
      nCode := nCode + 32;
      if g_Config.boClientPreferential then
      nType := 8;
      if g_Config.boClientBackUserExp then
      nType := nType + 1;
      SendDefMessage(SM_816, nType, 0, MakeWord(15, nCode), 0, '');
    end else begin
      SendDefMessage(SM_816, 0, 1, 15, 0, '');
    end;

    if g_Config.boClientNewCelebration then begin
      g_PacketManage3.Init;
      g_PacketManage3.WriteInteger(1);
      g_PacketManage3.WriteInteger($0F);
      g_PacketManage3.WriteInteger(1);
      SendDefMessage(2193, Integer(Self), 0, 0, 0, g_PacketManage3.GetMsg, True);
    end;

    if g_RedPacketList.Count > 0 then begin                                                         //发送红包信息
      for I := 0 to g_RedPacketList.Count - 1 do
      SendRedPacketWindow(I);
    end;

    if not m_boPneuma then begin
      //发送任务信息
      SendTaskList;
      //发送天元心法属性
      ClientQueryMentalAbilitys(Self);
      //发送仙官信息
      SendCentsOfficerInfo();
      //元气值
      SendDefMessage(SM_VITALITY, Integer(Self), m_wVitaLity, m_Abil.wMaxVitaLity, 0, '');
      //发送宗族信息
      SendFiendList(4);

    end;
except
    on E: Exception do begin
      MainOutMessage(Format(sExceptionMsg, ));
      MainOutMessage(E.Message);
    end;
end;
end;

procedure TPlayObject.SendPetInfo(State: byte);
var
i, nExp                               : Integer;
PetInfo                               : TPetInfo;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
btType, btReLive                      : byte;
begin
FillChar(PetInfo, SizeOf(TPetInfo), #0);
case State of
    1: begin                                                                                        //刚放出
      PetInfo.nMakeIndex := m_PetInfo.nMakeIndex;
      PetInfo.sCharName := m_PetInfo.sCharName;
      btType := m_PetInfo.btType;
      btReLive := m_PetInfo.btReLive;
      PetInfo.btLevel := m_PetInfo.wLevel;
      end;
    3: begin                                                                                        //摆摊
      PetInfo.nMakeIndex := m_PetInfo.nMakeIndex;
      PetInfo.sCharName := m_PetInfo.sCharName;
      btType := m_PetInfo.btType;
      btReLive := m_PetInfo.btReLive;
      PetInfo.btLevel := m_PetInfo.wLevel;
      end;
    2, 6: begin                                                                                     //骑乘
      PetInfo.nMakeIndex := m_PetInfo.nMakeIndex;
      PetInfo.sCharName := m_PetInfo.sCharName;
      btType := m_PetInfo.btType;
      btReLive := m_PetInfo.btReLive;
      PetInfo.btLevel := m_PetInfo.wLevel;
      end;
    7, 8: begin                                                                                     //元神骑乘
      PetInfo.nMakeIndex := m_PetInfo.nMakeIndex;
      PetInfo.sCharName := m_PetInfo.sCharName;
      btType := m_PetInfo.btType;
      btReLive := m_PetInfo.btReLive;
      PetInfo.btLevel := m_PetInfo.wLevel;
      end;
    9: begin
      PetInfo.nMakeIndex := m_PetInfo.nMakeIndex;
      PetInfo.sCharName := m_PetInfo.sCharName;
      btType := m_PetInfo.btType;
      btReLive := m_PetInfo.btReLive;
      PetInfo.btLevel := m_PetInfo.wLevel;
      end;
    10: begin                                                                                       //魂佑附体
      PetInfo.nMakeIndex := m_PetInfo.nMakeIndex;
      PetInfo.sCharName := m_PetInfo.sCharName;
      btType := m_PetInfo.btType;
      btReLive := m_PetInfo.btReLive;
      PetInfo.btLevel := m_PetInfo.wLevel;
      end;
end;

GetUserItemByMakeIndex(PetInfo.nMakeIndex, UserItem);
if (UserItem <> nil) then begin
    PetInfo.wExp := UserItem.dwExp;
    PetInfo.dwVil := MakeLong(MakeWord(UserItem.btValue, UserItem.btValue), MakeWord(UserItem.btValue, UserItem.btValue));
    PetInfo.dwExp := UserItem.dwExp;
    StdItem := UserEngine.GetStdItem(UserItem.wIndex);
    if StdItem <> nil then begin
      PetInfo.btType := MakeWord(UserItem.btValue + StdItem.AniCount * 8, 0);
    end;
end;

PetInfo.btKind := UserItem.btValue;
PetInfo.bt1 := 9;
PetInfo.dw1 := 0;
PetInfo.btHP := 100;
PetInfo.dw2 := 0;
PetInfo.dw3 := 0;
PetInfo.dw4 := 0;
PetInfo.dw5 := 0;
PetInfo.btState := State;                                                                         //刚放出是1,骑上是2 摆摊是39探宝

if (m_Pet <> nil) then begin
    PetInfo.wHP := CalcCent(m_Pet.m_WAbil.dwHP, m_Pet.m_WAbil.dwMaxHP);
    PetInfo.wMaxHP := 100;
    PetInfo.dwMaxExp := GetPetUpExp(btReLive, PetInfo.btLevel);
end;
PetInfo.bt2 := 0;
PetInfo.dw7 := 0;
PetInfo.bt2 := 0;
PetInfo.int64Exp := UserItem.dwExp;
PetInfo.int64MaxExp := GetPetUpExp(btReLive, PetInfo.btLevel);

m_defMsg := MakeDefaultMsg(34977, 0, 356, 1, 0);
SendSocket(@m_defMsg, EnCodeBuffer(@PetInfo, SizeOf(TPetInfo)));
end;

procedure TPlayObject.SendScriptItemPic(sMsg: string; nParam: Integer);
var
sName                                 : string;
StdItem                               : pTStdItem;
StdItem80                           : TStdItem;
UserItem                              : TUserItem;
begin
if sMsg = '' then Exit;
sName := Trim(DeCodeString(sMsg));
StdItem := UserEngine.GetStdItem(sName);
if StdItem = nil then Exit;
StdItem80 := StdItem^;

m_defMsg := MakeDefaultMsg(CM_ITEMPIC, Integer(Self), nParam, 0, 0);
FillChar(UserItem, SizeOf(TUserItem), #0);
UserItem.MakeIndex := 1;
UserItem.wIndex := UserEngine.GetStdItemIdx(sName);
UserItem.Dura := StdItem80.DuraMax;
UserItem.DuraMax := StdItem80.DuraMax;

if Assigned(m_VersionManage) then
try
    SendSocket(@m_defMsg, m_VersionManage.OnGetClientItemToMsg(Self, @UserItem));
except
    MainOutMessage(Format('TPlayObject::OnGetClientItemToMsg SoftVersionDate:%d', ));
end;

end;

//发送消息到RunGate

procedure TPlayObject.SendSocket(DefMsg: pTDefaultMessage; sMsg: string);
//004CAB38
var
MsgHdr                              : TMsgHeader;
nSendBytes                            : Integer;
tBuff                                 : PChar;
resourcestring
sExceptionMsg                         = ' TPlayObject::SendSocket..';
sFindMsg1                           = '玩家名字:%s,发送封包Ident:%d Recog:%d Param:%d Tag:%d Series:%d Msg:%s';
begin
if (m_btRaceServer <> RC_PLAYOBJECT) then Exit;
if m_nSocket = -1 then Exit;
if m_boOfflineGetGamePoint and (DefMsg <> nil) and (DefMsg.Ident <> SM_OUTOFCONNECTION) then Exit;

tBuff := nil;
try
    MsgHdr.dwCode := RUNGATECODE;
    MsgHdr.nSocket := m_nSocket;
    MsgHdr.wGSocketIdx := m_nGSocketIdx;
    MsgHdr.wIdent := GM_DATA;

    if DefMsg <> nil then begin
      if sMsg <> '' then begin
      MsgHdr.nLength := Length(sMsg) + SizeOf(TDefaultMessage) + 1;
      nSendBytes := MsgHdr.nLength + SizeOf(TMsgHeader);
      GetMem(tBuff, nSendBytes + SizeOf(Integer));
      Move(nSendBytes, tBuff^, SizeOf(Integer));
      Move(MsgHdr, tBuff, SizeOf(TMsgHeader));
      Move(DefMsg^, tBuff, SizeOf(TDefaultMessage));
      Move(sMsg, tBuff, Length(sMsg) + 1);
      end else begin
      MsgHdr.nLength := SizeOf(TDefaultMessage);
      nSendBytes := MsgHdr.nLength + SizeOf(TMsgHeader);
      GetMem(tBuff, nSendBytes + SizeOf(Integer));
      Move(nSendBytes, tBuff^, SizeOf(Integer));
      Move(MsgHdr, tBuff, SizeOf(TMsgHeader));
      Move(DefMsg^, tBuff, SizeOf(TDefaultMessage));
      end;
    end else begin
      if sMsg <> '' then begin
      MsgHdr.nLength := -(Length(sMsg) + 1);
      nSendBytes := abs(MsgHdr.nLength) + SizeOf(TMsgHeader);
      GetMem(tBuff, nSendBytes + SizeOf(Integer));
      Move(nSendBytes, tBuff^, SizeOf(Integer));
      Move(MsgHdr, tBuff, SizeOf(TMsgHeader));
      Move(sMsg, tBuff, Length(sMsg) + 1);
      end;
    end;
    if not RunSocket.AddGateBuffer(m_nGateIdx, tBuff) then begin
      FreeMem(tBuff);
    end;
except
    MainOutMessage(sExceptionMsg);
end;
end;

procedure TPlayObject.SendTaskList;
var
i, m                                  : Integer;
w                                     : word;
TaskDesc                              : string;
TaskTitle, Taskaim                  : string;
pTask                                 : PTTask;
begin
//发送任务列表
SendDefMessage(SM_TASKINFO, 0, 0, 0, 0, Format(sTaskInfo, ));
for i := 0 to m_TaskList.Count - 1 do begin
    pTask := PTTask(m_TaskList);
    if pTask^.Step <= 0 then Continue;
    TaskDesc := UserEngine.GetTaskStepInfo(pTask^.TaskID, pTask^.Step, TaskTitle, Taskaim);

    TaskDesc := '{Task title=' + TaskTitle + '}' + TaskDesc + '</Task>';
    if Taskaim <> '' then
      TaskDesc := TaskDesc + '<aim>' + Taskaim + '</aim>';

    if g_FunctionNPC <> nil then
      TaskDesc := g_FunctionNPC.GetLineVariableText(Self, TaskDesc);

    m := UserEngine.GetMainTask(pTask^.TaskID);

    w := HiWord(pTask^.Step);
    if (w = 0) or (HiByte(w) = 2) then
      SendDefMessage(SM_TASKINFO, pTask^.TaskID, 0, 0, MakeWord(1, m), TaskDesc)
    else
      SendDefMessage(SM_TASKINFO, pTask^.TaskID, LoByte(w), 0, MakeWord(3, m), TaskDesc);         //刷新的五色任务
end;
end;

procedure TPlayObject.SendTigerInfo();
var
i, nValue, nFelement                  : Integer;
begin
if m_btJob = 3 then Exit;                                                                         //妖士是没有虎王

if (m_TorDDM.Tiger.DB.level > 0) or (m_TorDDM.Tiger.DB.Exp > 0) then begin
    g_LargePacketManage.Init;
    g_LargePacketManage.WriteWord(m_TorDDM.Tiger.DB.level);
    g_LargePacketManage.WriteDWORD(m_TorDDM.Tiger.DB.Exp);
    g_LargePacketManage.WriteDWORD(m_TorDDM.Tiger.Abil.MaxExp);

    nValue := 0;
    nFelement := 1;
    for i := 0 to 4 do begin
      g_LargePacketManage.WriteByte(m_TorDDM.Tiger.DB.FelementAbil);
      if (m_TorDDM.Tiger.DB.FelementAbil > nValue) then begin
      nValue := m_TorDDM.Tiger.DB.FelementAbil;
      nFelement := i + 1;
      end;
    end;

    for i := 0 to 8 do begin
      g_LargePacketManage.WriteByte(m_TorDDM.Tiger.DB.SkillLevel);                               //虎王的9个基本技能
    end;

    if m_TorDDM.Tiger.DB.Dragon > 0 then begin
      for i := 0 to 7 do begin
      g_LargePacketManage.WriteByte(m_TorDDM.Tiger.DB.DragonSkillLevel);                     //八个龙王技能
      end;
    end;

    g_LargePacketManage.WriteByte(nFelement);
    g_LargePacketManage.WriteWord(m_TorDDM.Tiger.AddAbil.HP);
    g_LargePacketManage.WriteDWORD(m_TorDDM.Tiger.DB.ReCallTick);

    //虎王的数据
    if (m_TorDDM.Tiger.DB.Dragon = 0) then begin
      g_LargePacketManage.WriteWord(m_TorDDM.Tiger.Abil.DC);
      g_LargePacketManage.WriteWord(m_TorDDM.Tiger.Abil.DC2);
      g_LargePacketManage.WriteWord(m_TorDDM.Tiger.Abil.MC);
      g_LargePacketManage.WriteWord(m_TorDDM.Tiger.Abil.MC2);
      g_LargePacketManage.WriteWord(m_TorDDM.Tiger.Abil.AC);
      g_LargePacketManage.WriteWord(m_TorDDM.Tiger.Abil.AC2);
      g_LargePacketManage.WriteWord(m_TorDDM.Tiger.Abil.MAC);
      g_LargePacketManage.WriteWord(m_TorDDM.Tiger.Abil.MAC2);
    end;
    g_LargePacketManage.WriteByte(m_TorDDM.Tiger.Abil.HitPoint);
    g_LargePacketManage.WriteByte(m_TorDDM.Tiger.Abil.MagicNicety);
    g_LargePacketManage.WriteByte(m_TorDDM.Tiger.Abil.SpeedPoint);
    g_LargePacketManage.WriteByte(m_TorDDM.Tiger.Abil.AntiMagic);

    if m_TorDDM.Tiger.DB.Dragon > 0 then begin
      g_LargePacketManage.WriteWord(0);
      g_LargePacketManage.WriteWord(0);                                                             //技能虚弱
      g_LargePacketManage.WriteWord(0);                                                             //技能霸体
      g_LargePacketManage.WriteWord(0);
      g_LargePacketManage.WriteWord(0);
      g_LargePacketManage.WriteWord(m_TorDDM.Tiger.AddAbil.HP);
      g_LargePacketManage.WriteWord(0);
      m_defMsg := MakeDefaultMsg(SM_DRAGONINFO, 0, 0, 0, 0);
    end else begin
      g_LargePacketManage.WriteWord(0);
      m_defMsg := MakeDefaultMsg(SM_TIGERINFO, 0, 0, 0, 0);
    end;
    SendSocket(@m_defMsg, g_LargePacketManage.GetMsg);
end;
end;

//珍宝阁

procedure TPlayObject.SendTreasurePavilion;
var
nCount, i, ii                         : Integer;
G                                     : TGuild;
begin
if m_MyGuild = nil then Exit;
try
    G := TGuild(m_MyGuild);
    if not G.boTowerStatus then begin
      SendDefMessage(SM_TREASUREPAVILION, 0, 4, 0, 0, '通灵塔资源不足被封闭,无法开启珍宝阁。');
      Exit;
    end;
    nCount := Length(G.m_TreasurePavilion);
    if nCount > 0 then begin
      g_LargePacketManage.Init;
      for i := 0 to nCount - 1 do begin
      g_LargePacketManage.WriteBuffer(G.m_TreasurePavilion, 11);
      g_LargePacketManage.WriteString(G.m_TreasurePavilion.sUserName);
      g_LargePacketManage.WriteString(G.m_TreasurePavilion.sItemName);
      end;

      m_defMsg := MakeDefaultMsg(SM_TREASUREPAVILION, 0, MakeWord(0, nCount), 0, 0);
      SendSocket(@m_defMsg, g_LargePacketManage.GetMsg);
    end else
      SendDefMessage(SM_TREASUREPAVILION, 0, 0, 0, 0, '');
except
    on E: Exception do begin
      MainOutMessage('procedure TPlayObject.SendTreasurePavilion');
      MainOutMessage(E.Message);
    end;
end;
end;

//发送本人物所学习了的技能列表

procedure TPlayObject.SendUseMagic();
var
i, nCount                           : Integer;
UserMagic                           : pTUserMagic;
ClientMagic                           : TClientMagic;
oClientMagic                        : ToClientMagic;
wCode                                 : word;
begin
nCount := 0;
wCode := $FFFF;
g_LargePacketManage.Init;

if m_boInosculatePneuma then begin
    //融合元神的技能
    for i := 0 to m_MagicList.Count - 1 do begin
      UserMagic := pTUserMagic(m_MagicList.Items);
      if (UserMagic^.btType in ) then begin
      UserMagic.GetClientMagic(@ClientMagic);
      g_LargePacketManage.WriteBuffer(ClientMagic, SizeOf(TClientMagic));
      Inc(nCount);
      end;
    end;
end else begin
    for i := 0 to m_MagicList.Count - 1 do begin
      UserMagic := pTUserMagic(m_MagicList.Items);
      if UserMagic^.btType < MAG_AMALGAMATION then begin
      UserMagic.GetClientMagic(@ClientMagic);





   if m_nSoftVersionDate < 20090402 then                                                            //1978使用
      g_LargePacketManage.WriteBuffer(ClientMagic, SizeOf(TOClientMagic)- 7)
      else

      g_LargePacketManage.WriteBuffer(ClientMagic, SizeOf(TClientMagic));

    //    MainOutMessage(Format('TPlayObject::SoftVersionDate:%d', ));
      Inc(nCount);
      end;

      if (UserMagic.GetMagIdx in ) then begin
      if UserMagic.btKey = 0 then begin
          case UserMagic.GetMagIdx of
            120: wCode := wCode xor 1;
            108: wCode := wCode xor 2;
            109: wCode := wCode xor 4;
            110: wCode := wCode xor 8;
            111: wCode := wCode xor $10;
            112: wCode := wCode xor $20;
            113: wCode := wCode xor $40;
            114: wCode := wCode xor $80;
            115: wCode := wCode xor $100;
          end;
      end;
      end;
    end;
end;

if nCount > 0 then begin
    m_defMsg := MakeDefaultMsg(SM_SENDMYMAGIC, 0, 0, 0, 0);
    SendSocket(@m_defMsg, g_LargePacketManage.GetMsg);
    if m_boPneuma then begin
      if (m_PneumaObject <> nil) and (m_PneumaObject is TPlayObject) then
      TPlayObject(m_PneumaObject).ClientMagic_All_LongWenGang_List(Self);
    end else
      ClientMagic_All_LongWenGang_List(Self);
end;

SendDefMessage(CM_MAGICSWITCH, Integer(Self), m_nCurrX, m_nCurrY, wCode, '');
end;

procedure TPlayObject.SetScriptLabel(sLabel: string);
begin
m_CanJmpScriptLableList.Clear;
m_CanJmpScriptLableList.Add(sLabel);
end;

//命令@MapInfo 地图号 X Y

procedure TPlayObject.ShowMapInfo(sMAP, sX, sY: string);
var
Map                                 : TEnvirnoment;
nX, nY                              : Integer;
MapCellInfo                           : pTMapCellinfo;
begin
nX := Str_ToInt(sX, 0);
nY := Str_ToInt(sY, 0);
if (sMAP <> '') and (nX >= 0) and (nY >= 0) then begin
    Map := g_MapManager.FindMap(sMAP);
    if Map <> nil then begin
      if Map.GetMapCellInfo(nX, nY, MapCellInfo) then begin
      SysMsg('标志: ' + IntToStr(MapCellInfo.chFlag), c_Green, t_Hint);
      if MapCellInfo.ObjList <> nil then begin
          SysMsg('对象数: ' + IntToStr(MapCellInfo.ObjList.Count), c_Green,
            t_Hint);
      end;
      end else begin
      SysMsg('取地图单元信息失败: ' + sMAP, c_Red, t_Hint);
      end;
    end;
end else begin
    SysMsg('请按正确格式输入: ' + g_GameCommand.MAPINFO.sCmd +
      ' 地图号 X Y', c_Green, t_Hint);
end;
end;

procedure TPlayObject.StartMapEventOfButch();
var
i                                     : Integer;
boGotoLabel                           : Boolean;
MapEvent                              : pTMapEvent;
begin
boGotoLabel := False;
for i := 0 to g_MapEventListOfButch.Count - 1 do begin
    MapEvent := pTMapEvent(g_MapEventListOfButch.Items);
    if MapEvent <> nil then begin
      if IsGotoLabel(MapEvent.m_sMapName,
      MapEvent.m_nCurrX,
      MapEvent.m_nCurrY,
      MapEvent.m_nRange,
      MapEvent.m_MapFlag.nQuestUnit,
      MapEvent.m_MapFlag.boOpen,
      MapEvent.m_Condition.sItemName,
      '*',
      MapEvent.m_Condition.boNeedGroup, MapEvent.m_nRandomCount) then begin
      boGotoLabel := True;
      Break;
      end;
    end;
end;
if boGotoLabel and (MapEvent <> nil) then begin
    case MapEvent.m_StartScript.nLable of
      0: ;
      1: begin
          ExecuteScript(g_FunctionNPC, MapEvent.m_StartScript.sLable);
      end;
    end;
end;
end;

procedure TPlayObject.StartMapEventOfDropItem(sItemName: string);
var
i                                     : Integer;
boGotoLabel                           : Boolean;
MapEvent                              : pTMapEvent;
begin
boGotoLabel := False;
for i := 0 to g_MapEventListOfDropItem.Count - 1 do begin
    MapEvent := pTMapEvent(g_MapEventListOfDropItem.Items);
    if MapEvent <> nil then begin
      if IsGotoLabel(MapEvent.m_sMapName,
      MapEvent.m_nCurrX,
      MapEvent.m_nCurrY,
      MapEvent.m_nRange,
      MapEvent.m_MapFlag.nQuestUnit,
      MapEvent.m_MapFlag.boOpen,
      MapEvent.m_Condition.sItemName,
      sItemName,
      MapEvent.m_Condition.boNeedGroup, MapEvent.m_nRandomCount) then begin
      boGotoLabel := True;
      Break;
      end;
    end;
end;
if boGotoLabel and (MapEvent <> nil) then begin
    case MapEvent.m_StartScript.nLable of
      0: ;
      1: begin
          ExecuteScript(g_FunctionNPC, MapEvent.m_StartScript.sLable);
      end;
    end;
end;
end;

procedure TPlayObject.StartMapEventOfMine();
var
i                                     : Integer;
boGotoLabel                           : Boolean;
MapEvent                              : pTMapEvent;
begin
boGotoLabel := False;
for i := 0 to g_MapEventListOfMine.Count - 1 do begin
    MapEvent := pTMapEvent(g_MapEventListOfMine.Items);
    if MapEvent <> nil then begin
      if IsGotoLabel(MapEvent.m_sMapName,
      MapEvent.m_nCurrX,
      MapEvent.m_nCurrY,
      MapEvent.m_nRange,
      MapEvent.m_MapFlag.nQuestUnit,
      MapEvent.m_MapFlag.boOpen,
      MapEvent.m_Condition.sItemName,
      '*',
      MapEvent.m_Condition.boNeedGroup, MapEvent.m_nRandomCount) then begin
      boGotoLabel := True;
      Break;
      end;
    end;
end;
if boGotoLabel and (MapEvent <> nil) then begin
    case MapEvent.m_StartScript.nLable of
      0: ;
      1: begin
          ExecuteScript(g_FunctionNPC, MapEvent.m_StartScript.sLable);
      end;
    end;
end;
end;

procedure TPlayObject.StartMapEventOfPickUpItem(sItemName: string);
var
i                                     : Integer;
boGotoLabel                           : Boolean;
MapEvent                              : pTMapEvent;
begin
boGotoLabel := False;
for i := 0 to g_MapEventListOfPickUpItem.Count - 1 do begin
    MapEvent := pTMapEvent(g_MapEventListOfPickUpItem.Items);
    if MapEvent <> nil then begin
      if IsGotoLabel(MapEvent.m_sMapName,
      MapEvent.m_nCurrX,
      MapEvent.m_nCurrY,
      MapEvent.m_nRange,
      MapEvent.m_MapFlag.nQuestUnit,
      MapEvent.m_MapFlag.boOpen,
      MapEvent.m_Condition.sItemName,
      sItemName,
      MapEvent.m_Condition.boNeedGroup, MapEvent.m_nRandomCount) then begin
      boGotoLabel := True;
      Break;
      end;
    end;
end;
if boGotoLabel and (MapEvent <> nil) then begin
    case MapEvent.m_StartScript.nLable of
      0: ;
      1: begin
          ExecuteScript(g_FunctionNPC, MapEvent.m_StartScript.sLable);
      end;
    end;
end;
end;

procedure TPlayObject.StartMapEventOfRun();
var
i                                     : Integer;
boGotoLabel                           : Boolean;
MapEvent                              : pTMapEvent;
begin
boGotoLabel := False;
for i := 0 to g_MapEventListOfRun.Count - 1 do begin
    MapEvent := pTMapEvent(g_MapEventListOfRun.Items);
    if MapEvent <> nil then begin
      if IsGotoLabel(MapEvent.m_sMapName,
      MapEvent.m_nCurrX,
      MapEvent.m_nCurrY,
      MapEvent.m_nRange,
      MapEvent.m_MapFlag.nQuestUnit,
      MapEvent.m_MapFlag.boOpen,
      MapEvent.m_Condition.sItemName,
      '*',
      MapEvent.m_Condition.boNeedGroup, MapEvent.m_nRandomCount) then begin
      boGotoLabel := True;
      Break;
      end;
    end;
end;
if boGotoLabel and (MapEvent <> nil) then begin
    case MapEvent.m_StartScript.nLable of
      0: ;
      1: begin
          ExecuteScript(g_FunctionNPC, MapEvent.m_StartScript.sLable);
      end;
    end;
end;
end;

procedure TPlayObject.StartMapEventOfWalk();
var
i                                     : Integer;
boGotoLabel                           : Boolean;
MapEvent                              : pTMapEvent;
begin
boGotoLabel := False;
for i := 0 to g_MapEventListOfWalk.Count - 1 do begin
    MapEvent := pTMapEvent(g_MapEventListOfWalk.Items);
    if MapEvent <> nil then begin
      if IsGotoLabel(MapEvent.m_sMapName,
      MapEvent.m_nCurrX,
      MapEvent.m_nCurrY,
      MapEvent.m_nRange,
      MapEvent.m_MapFlag.nQuestUnit,
      MapEvent.m_MapFlag.boOpen,
      MapEvent.m_Condition.sItemName,
      '*',
      MapEvent.m_Condition.boNeedGroup, MapEvent.m_nRandomCount) then begin
      boGotoLabel := True;
      Break;
      end;
    end;
end;
if boGotoLabel and (MapEvent <> nil) then begin
    case MapEvent.m_StartScript.nLable of
      0: ;
      1: begin
          ExecuteScript(g_FunctionNPC, MapEvent.m_StartScript.sLable);
      end;
    end;
end;
end;


procedure TPlayObject.StruckDamage(nDamage: Integer);
var
i, j                                  : Integer;
nDam                                  : Integer;
nDura, nOldDura                     : Integer;
StdItem                               : pTStdItem;
bo19                                  : Boolean;
AddItem                               : pTUserItem;
begin
if nDamage <= 0 then Exit;

nDam := Random(g_Config.nDamDuraRandom) + g_Config.nDamDuraValue;

if m_wStatusTimeArr > 0 then begin
    nDam := Round(nDam * (g_Config.nPosionDamagarmor / 10) {1.2});
end;

if m_boSuperMan then nDam := 0;                                                                   //无敌模式不掉持久

bo19 := False;
if m_UseItems.wIndex > 0 then begin
    StdItem := UserEngine.GetStdItem(m_UseItems.wIndex);
    if not CheckSPCode(StdItem.Reserved, RE_NODECDRUE) then begin                                 //物品控制-不掉持久
      nDura := m_UseItems.Dura;
      nOldDura := Round(nDura / 1000);
      Dec(nDura, nDam);
      if nDura <= 0 then begin
      //可以控制物品破碎
      if StdItem.Broken > 0 then begin
          New(AddItem);
          AddItem^ := m_UseItems;
          if AddItemToBag(AddItem) then
          begin
            SendDelItems(@m_UseItems);
            AddItem.btItemExt := 4;                                                            //物品破碎
            SendUpdateItem(AddItem);
            SendAddItem(AddItem);
            SendDefMessage(SM_TAKEOFF_OK, GetFeatureToLong(Self), GetGender, 0, 0, '');
            SysMsg(StdItem.Name + '持久过低,已破碎,已自动放入你的包裹!', c_Pink, t_Hint);

            m_UseItems.wIndex := 0;
            m_UseItems.MakeIndex := 0;
            FeatureChanged();
            m_UseItems.wIndex := 0;
            m_UseItems.Dura := 0;

            bo19 := True;
          end else begin
            Dispose(AddItem);
          end;
      end else begin
          SendDelItems(@m_UseItems);
          if StdItem.boGameLog = 1 then
            AddGameDataLog('3' + #9 +
            m_sMapName + #9 +
            IntToStr(m_nCurrX) + #9 +
            IntToStr(m_nCurrY) + #9 +
            m_sCharName + #9 +
            StdItem.Name + #9 +
            IntToStr(m_UseItems.MakeIndex) + #9 +
            'TRUE' + #9 +
            '0');

          m_UseItems.wIndex := 0;
          m_UseItems.MakeIndex := 0;
          FeatureChanged();

          m_UseItems.wIndex := 0;
          m_UseItems.Dura := 0;
          bo19 := True;
      end;
      end else begin
      m_UseItems.Dura := nDura;
      end;
      if nOldDura <> Round(nDura / 1000) then begin
      SendMsg(Self, RM_DURACHANGE, U_DRESS, nDura, m_UseItems.DuraMax, 0, '');
      end;
    end;
end;

for i := Low(THumItems) to High(THumItems) do begin
    if i in then Continue;

    if (m_UseItems.wIndex > 0) and (Random(8) = 0) then begin
      StdItem := UserEngine.GetStdItem(m_UseItems.wIndex);
      if StdItem = nil then Continue;
      if (StdItem.StdMode in ) and (StdItem.Shape = 150) then
      Continue;                                                                                 //时间物品不掉持久

      if CheckSPCode(StdItem.Reserved, RE_NODECDRUE) then
      Continue;                                                                                 //物品控制-不掉持久

      nDura := m_UseItems.Dura;
      nOldDura := Round(nDura / 1000);
      Dec(nDura, nDam);
      if nDura <= 0 then begin
      if StdItem.Broken > 0 then begin
          New(AddItem);
          AddItem^ := m_UseItems;
          if AddItemToBag(AddItem) then
          begin
            SendDelItems(@m_UseItems);
            AddItem.btItemExt := 4;                                                            //物品破碎
            SendUpdateItem(AddItem);
            SendAddItem(AddItem);
            SendDefMessage(SM_TAKEOFF_OK, GetFeatureToLong(Self), GetGender, 0, 0, '');
            SysMsg(StdItem.Name + '持久过低,已破碎,已自动放入你的包裹!', c_Pink, t_Hint);

            m_UseItems.wIndex := 0;
            m_UseItems.MakeIndex := 0;
            FeatureChanged();
            m_UseItems.wIndex := 0;
            m_UseItems.Dura := 0;

            bo19 := True;
          end else begin
            Dispose(AddItem);
          end;
      end else begin
          SendDelItems(@m_UseItems);

          if StdItem.boGameLog = 1 then
            AddGameDataLog('3' + #9 +
            m_sMapName + #9 +
            IntToStr(m_nCurrX) + #9 +
            IntToStr(m_nCurrY) + #9 +
            m_sCharName + #9 +
            StdItem.Name + #9 +
            IntToStr(m_UseItems.MakeIndex) + #9 +
            'TRUE' + #9 +
            '0');

          m_UseItems.wIndex := 0;
          m_UseItems.MakeIndex := 0;
          FeatureChanged();
          m_UseItems.wIndex := 0;
          m_UseItems.Dura := 0;
          bo19 := True;
      end;
      end else begin
      m_UseItems.Dura := nDura;
      {圣灵属性失效}
      if Round(nDura / m_UseItems.DuraMax) < Round(g_Config.nHolySpiritRate / 100) then begin
          if ((m_UseItems.btItemExt and EX_HOLY) = EX_HOLY) then begin
            Dec(m_UseItems.btItemExt, EX_HOLY);
            SendUpdateItem(@m_UseItems);
          end;
      end;
      end;
      if nOldDura <> Round(nDura / 1000) then begin
      SendMsg(Self, RM_DURACHANGE, i, nDura, m_UseItems.DuraMax, 0, '');
      end;
    end;
end;

if bo19 then RecalcAbilitys(True);

//盾牌减少伤害
if (m_btShiEldDefencePower > 0) and (g_Config.nShiEldDefenceRate > 0) then begin
    if (Random(g_Config.nShiEldDefenceRate) < 3) and (Random(g_Config.nShiEldLevelRate) < m_btShiEldDefenceLevel) then begin
      nDamage := Round(nDamage - (nDamage * m_btShiEldDefencePower / 100));
      SysMsg('恭喜你,本次盾牌成功分担部分伤害', c_Red, t_Hint);
    end;
end;

//圣王盾减少伤害
if (m_btShiEldExemptHurt > 0) and (g_Config.nShiEldDefenceRate > 0) then begin
    nDamage := Round(nDamage - (nDamage * g_Config.nShiEldExemptHurt / 100));
end;

//金刚护体承受的伤害超过血量的120%,触发金刚净化
if (m_wStatusTimeArr > 0) and m_boRideFightOn and
    (m_MagicSkills <> nil) and (m_MagicSkills <> nil) and (m_MagicSkills <> nil) then begin
    Inc(m_dwTotalDamage, nDamage);
    if ((m_MagicSkills.btKey = 1)) and ((m_dwTotalDamage / m_WAbil.dwMaxHP * 100) > 120) then begin
      //清除所有中毒效果
      nDam := m_PetInfo.wLevel + m_MagicSkills.btLevel + m_MagicSkills.btLevel + m_MagicSkills.btLevel;
      if (Random(g_Config.nMagJinGangPurifyRate) < nDam) then begin
      if m_wStatusTimeArr > 0 then m_wStatusTimeArr := 1;
      if m_wStatusTimeArr > 0 then m_wStatusTimeArr := 1;
      if m_wStatusTimeArr > 0 then m_wStatusTimeArr := 1;
      if m_wStatusTimeArr > 0 then m_wStatusTimeArr := 1;
      if m_wStatusTimeArr > 0 then m_wStatusTimeArr := 1;
      SendRefMsg(RM_510, 1, 0, 157, 0, '');
      SysMsg('金刚净化成功', c_Red, t_Hint);
      m_dwTotalDamage := 0;
      //技能经验
      TrainSkill(m_MagicSkills, Random(3) + 1, 1000);
      end;
    end;
end;

//火焰盾,触发抗拒火环效果
if m_boAbilMagBubbleDefence and m_boRideFightOn and (m_MagicSkills <> nil) and (m_MagicSkills.btKey = 1) then begin
    if (m_MagicSkills <> nil) and (m_MagicSkills <> nil) then begin
      nDam := m_PetInfo.wLevel + m_MagicSkills.btLevel + m_MagicSkills.btLevel + m_MagicSkills.btLevel;
      if (Random(g_Config.nMagFireShieldRate) < nDam) then begin
      DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, Self);
      end;
    end;
end;

//狂狮盾
if (m_wStatusTimeArr > 1) and m_boRideFightOn and (m_MagicSkills <> nil) and (m_MagicSkills.btKey = 1) then begin
    if (m_MagicSkills <> nil) and (m_MagicSkills <> nil) then begin
      nDam := m_PetInfo.wLevel + m_MagicSkills.btLevel + m_MagicSkills.btLevel + m_MagicSkills.btLevel;
      if (Random(g_Config.nMagLionShieldRate) < nDam) then begin
      DoSpell(m_MagicSkills, m_nCurrX, m_nCurrY, Self);
      //技能经验
      TrainSkill(m_MagicSkills, Random(3) + 1, 1000);
      end;
    end;
end;

//被攻击增加元气
if (m_btRaceServer = RC_PLAYOBJECT) and
    ((TPlayObject(Self).m_btPneumaSex > 0) or
    (TPlayObject(Self).m_Dan.SoulBaby.wKind > 0) or
    (not g_Config.boNoPneumaAddVitaLity) or
    (m_btJob = 3))
    then begin
    if (g_Config.nVitaLityAddSpeed > 0) and (nDamage > 10) then begin
      //每10点伤害,随机增加1-4点元气
      nDam := _MIN(10, (nDamage div 10) * (Random(4) + 1));
      nDam := nDam * g_Config.nVitaLityAddSpeed;

      if m_boPneuma and (m_PneumaObject <> nil) then
      m_PneumaObject.DamageVitaLity(-nDam)
      else
      DamageVitaLity(-nDam);
    end;
end;


DamageHealth(nDamage);
end;

function TPlayObject.SuperRepairUseItems: Boolean;
var
i, ii                                 : Integer;
StdItem                               : pTStdItem;
begin
Result := False;
ii := 0;
for i := Low(THumItems) to High(THumItems) do begin
    if (i in ) then Continue;

    if m_UseItems.wIndex > 0 then begin
      StdItem := UserEngine.GetStdItem(m_UseItems.wIndex);
      if (StdItem = nil) then Continue;
      if CheckSPCode(StdItem.SPCode, SP_DISABLEBINQUAN) then Continue;                              //物品控制-禁止冰泉圣水
      m_UseItems.Dura := m_UseItems.DuraMax;
      SendMsg(Self, RM_DURACHANGE, i, m_UseItems.Dura, m_UseItems.DuraMax, 0, '');
      Inc(ii);
    end;
end;

for i := Low(m_EntopticItems) to High(m_EntopticItems) do begin
    if m_EntopticItems.Item.wIndex > 0 then begin
      StdItem := UserEngine.GetStdItem(m_EntopticItems.Item.wIndex);
      if (StdItem = nil) then Continue;
      if CheckSPCode(StdItem.SPCode, SP_DISABLEBINQUAN) then Continue;                              //物品控制-禁止冰泉圣水
      m_EntopticItems.Item.Dura := m_EntopticItems.Item.DuraMax;
      SendUpdateItem(@m_EntopticItems.Item);
      Inc(ii);
      //包不知道
    end;
end;
//融合元神穿戴的融合装备
if m_boPneuma and m_boInosculatePneuma then begin
    for i := Low(m_TorDDM.Tiger.Items) to High(m_TorDDM.Tiger.Items) do begin
      if m_TorDDM.Tiger.Items.wIndex > 0 then begin
      StdItem := UserEngine.GetStdItem(m_TorDDM.Tiger.Items.wIndex);
      if (StdItem = nil) then Continue;
      if CheckSPCode(StdItem.SPCode, SP_DISABLEBINQUAN) then Continue;                            //物品控制-禁止冰泉圣水
      m_TorDDM.Tiger.Items.Dura := m_TorDDM.Tiger.Items.DuraMax;
      SendUpdateItem(@m_TorDDM.Tiger.Items);
      Inc(ii);
      end;
    end;
end;

Result := ii > 0;
if Result then
    SysMsg(g_sSuperRepairMsg, c_Green, t_Hint);
end;

function TPlayObject.SuperRepairWeapon: Boolean;
var
StdItem                               : pTStdItem;
begin
Result := False;
if m_UseItems.wIndex <= 0 then Exit;
StdItem := UserEngine.GetStdItem(m_UseItems.wIndex);
if StdItem = nil then Exit;
{物品控制-禁止特殊修理}
if CheckSPCode(StdItem.SPCode, SP_DISABLEREPAIR) then begin
    SysMsg('此物品禁止修理', c_Red, t_Hint);
    Exit;
end;
m_UseItems.Dura := m_UseItems.DuraMax;
SendMsg(Self, RM_DURACHANGE, 1, m_UseItems.Dura,
    m_UseItems.DuraMax, 0, '');
SysMsg(g_sWeaponRepairSuccess {'武器修复成功...'}, c_Green, t_Hint);
Result := True;
end;

procedure TPlayObject.TakeItemOn(sItemName: string; btWhere: Integer);
var
i                                     : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
nOldStatus                            : Integer;
begin
if btWhere >= MAX_HUMITEM_COUNT then Exit;

if (sItemName = '') then begin
    if m_UseItems.wIndex > 0 then begin                                                    //取下物品
      ClientTakeOffItems(btWhere, m_UseItems.MakeIndex, UserEngine.GetStdItemName(m_UseItems.wIndex));
    end;
end else begin
    if GetUserItemByName(sItemName, UserItem) <> -1 then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if ClientTakeOnItems(btWhere, UserItem.MakeIndex, StdItem.FilterName, True) then begin
      SendDelItems(UserItem);
      SendUpdateMsg(Self, RM_SENDUSEITEMS, 0, 0, 0, 0, '');
      end;
    end;
end;
end;

procedure TPlayObject.TigerDefendMaster(var nDamage: Integer);
var
i, nCount                           : Integer;
nX, nY, n18, n1C, nMapIndex         : Integer;
wHP                                 : word;
begin
if m_btJob = 3 then Exit;                                                                         //妖士是没有虎王

if (m_Tiger <> nil) and (not m_Tiger.m_boDeath) and (not m_Tiger.m_boGhost) then begin
    if CretInNear10XY(m_Tiger, m_nCurrX, m_nCurrY) then begin
      if (Random(g_Config.nTigerSkillRate) < m_TorDDM.Tiger.DB.SkillLevel) then begin
      if GetFrontPosition(nX, nY) then begin
          if GetCanMovePosition(nX, nY, 3, n18, n1C) then begin
            m_Tiger.SendRefMsg(RM_SPACEMOVE_FIRE, 0, 0, 0, 0, '');
            nMapIndex := m_PEnvir.Index;
            m_Tiger.SpaceMove(m_sMapName, n18, n1C, 0, @nMapIndex);
            //恢复主人血量
            nDamage := 0;
            m_WAbil.dwHP := Round(m_WAbil.dwMaxHP / 2);
            HealthSpellChanged();
            SysMsg(Format('你的%s替你抵挡了一次致命攻击,牺牲了!', ), c_Red, t_Hint);
            m_Tiger.Die;
          end;
      end;
      end;
    end;
end;
end;

procedure TPlayObject.TigerTransferDamage(var nDamage: Integer);
var
nObjCount, nTransfer                  : Integer;
begin
if m_btJob = 3 then Exit;                                                                         //妖士是没有虎王
if (m_Tiger <> nil) and (not m_Tiger.m_boDeath) and (not m_Tiger.m_boGhost) then begin
    if CretInNear10XY(m_Tiger, m_nCurrX, m_nCurrY) then begin
      if (Random(g_Config.nTigerSkillRate) < m_TorDDM.Tiger.DB.SkillLevel) then begin
      nObjCount := Integer(Self);
      m_Tiger.SendRefMsg(RM_510, HiWord(nObjCount), LoWord(nObjCount), 104, 0, '');
      nTransfer := Round(nDamage * (_MIN(m_TorDDM.Tiger.DB.level, 90)) / 100);
      Dec(nDamage, nTransfer);
      if nTransfer > 0 then begin
          m_Tiger.StruckDamage(nTransfer);
          m_Tiger.SendRefMsg(RM_STRUCK, 0, nTransfer, 0, Integer(Self), '');
      end;
      end;
    end;
end;
end;

//更新人物到nStep,如果nStep=0,则在原来的基础上+1

function TPlayObject.UpdateTaskStep(const TaskID: Integer; nStep: Integer): Integer;
var
i                                     : Integer;
TaskTitle, TaskDesc, Taskaim          : string;
m                                     : Integer;
pTask                                 : PTTask;
begin
Result := -1;
m := 0;
for i := 0 to m_TaskList.Count - 1 do begin
    pTask := PTTask(m_TaskList);
    if pTask^.TaskID = TaskID then begin
      m := pTask^.Step;
      if (nStep = 0) then nStep := LoWord(m) + 1;
      pTask^.Step := MakeLong(nStep, HiWord(m));
      ;
      Result := nStep;
      Break;
    end;
end;

if Result > 0 then begin
    i := UserEngine.GetMainTask(TaskID);
    if m > 0 then begin
      SendMsg(Self, RM_ADDTASK, MakeWord(2, i), TaskID, 0, 0, '');
    end;
    TaskDesc := UserEngine.GetTaskStepInfo(pTask^.TaskID, pTask^.Step, TaskTitle, Taskaim);

    TaskDesc := '{Task title=' + TaskTitle + '}' + TaskDesc + '</Task>';
    if Taskaim <> '' then
      TaskDesc := TaskDesc + '<aim>' + Taskaim + '</aim>';

    if g_FunctionNPC <> nil then
      TaskDesc := g_FunctionNPC.GetLineVariableText(Self, TaskDesc);

    SendMsg(Self, RM_ADDTASK, MakeWord(1, i), TaskID, 0, 0, TaskDesc)
end;
end;

procedure TPlayObject.RefreshTask(const TaskID, nStep: Integer);
var
i, m, w                               : Integer;
TaskTitle, TaskDesc, Taskaim          : string;
pTask                                 : PTTask;
begin
if nStep = 0 then Exit;
SendDefMessage(SM_TASKINFO, 0, 0, 0, 0, Format(sTaskInfo, ));
for i := 0 to m_TaskList.Count - 1 do begin
    pTask := PTTask(m_TaskList);
    if pTask^.TaskID = TaskID then begin
      TaskDesc := UserEngine.GetTaskStepInfo(TaskID, nStep, TaskTitle, Taskaim);

      TaskDesc := '{Task title=' + TaskTitle + '}' + TaskDesc + '</Task>';
      if Taskaim <> '' then
      TaskDesc := TaskDesc + '<aim>' + Taskaim + '</aim>';

      if g_FunctionNPC <> nil then
      TaskDesc := g_FunctionNPC.GetLineVariableText(Self, TaskDesc);

      m := UserEngine.GetMainTask(TaskID);

      w := HiWord(pTask^.Step);
      if (w = 0) or (HiByte(w) = 2) then
      SendMsg(Self, RM_ADDTASK, MakeWord(1, m), TaskID, 0, 0, TaskDesc)
      else
      SendMsg(Self, RM_ADDTASK, MakeWord(3, m), TaskID, LoByte(w), 0, TaskDesc);
    end;
end;
end;

//客户端任务ID=任务ID*100 + 任务步骤

procedure TPlayObject.ClientDelTask(const TaskID: Integer);
var
i, m                                  : Integer;
pTask                                 : PTTask;
begin
if GetTaskStep(TaskID) = 0 then Exit;
m := UserEngine.GetMainTask(TaskID);
for i := m_TaskList.Count - 1 downto 0 do begin
    pTask := PTTask(m_TaskList);
    if pTask^.TaskID = TaskID then begin
      SendMsg(Self, RM_ADDTASK, MakeWord(2, m), TaskID, 0, 0, '');
      m_sScriptParam := IntToStr(pTask^.TaskID);
      m_sScriptParam := IntToStr(LoWord(pTask^.Step));
      m_TaskList.Delete(i);
      Dispose(pTask);                                                                               //
      if (m = 0) then Dec(m_nTaskCount);
      ExecuteScript(g_FunctionNPC, '@CancelTask');
      Break;
    end;
end;
end;

procedure TPlayObject.SendColorTask(const TaskID, Color: Integer);
var
TaskTitle, TaskDesc, Taskaim          : string;
begin
TaskDesc := UserEngine.GetTaskStepInfo(TaskID, 1, TaskTitle, Taskaim);
TaskDesc := '{Task title=' + TaskTitle + '}' + TaskDesc + '</Task>';
if Taskaim <> '' then
    TaskDesc := TaskDesc + '<aim>' + Taskaim + '</aim>';

if g_FunctionNPC <> nil then
    TaskDesc := g_FunctionNPC.GetLineVariableText(Self, TaskDesc);

SendMsg(Self, RM_ADDTASK, MakeWord(3, 1), TaskID, Color, 0, TaskDesc);
end;

procedure TPlayObject.UPGRADEMON(nType: Integer);
var
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
i                                     : Integer;
nMakeIndex                            : Integer;
tm                                    : DWORD;
OldItem                               : TUserItem;
begin
if (m_PetInfo.nMakeIndex = 0) or (m_Pet = nil) then begin
    SysMsg('请将你的灵兽处于跟随状态。', c_Red, t_Hint);
    Exit;
end else
    nMakeIndex := m_PetInfo.nMakeIndex;

{找到豹魔石}
for i := 0 to m_ItemList.Count - 1 do begin
    UserItem := m_ItemList.Items;
    if (UserItem <> nil) and (UserItem.MakeIndex = nMakeIndex) then begin
      tm := DateTimeToWolTIme(Now);
      UserItem.btValue := LoByte(LoWord(tm));
      UserItem.btValue := HiByte(LoWord(tm));
      UserItem.btValue := LoByte(HiWord(tm));
      UserItem.btValue := HiByte(HiWord(tm));
      UserItem.btValue := 0;                                                                     //等级
      UserItem.btValue := 0;
//      UserItem.btValue := 0;                                                                     //经验
//      UserItem.btValue := 0;
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if nType = -1 then begin
      {灵兽转生}
      //2转到3转,属性需要重新赋值
      OldItem := UserItem^;
      UserItem.btValue := _MIN(3, UserItem.btValue + 1);
      UserItem.btValue := _MIN(2, _Max(1, UserItem.btValue));
      if (UserItem.btValue = 3) then begin
          UserItem.wHP := OldItem.wHP;
          UserItem.wMP := OldItem.wMP;
          UserItem.btAntiPoison := OldItem.btAntiPoison;
          UserItem.wMAC := OldItem.wMAC;
          UserItem.btMagicNicety := OldItem.btMagicNicety;
          UserItem.btEvaDet := OldItem.btEvaDet;
          UserItem.wAC := OldItem.wAC;
          UserItem.btAntiMagic := OldItem.btAntiMagic;
          UserItem.btPoisonNicety := OldItem.btPoisonNicety;
          UserItem.btSavvy := OldItem.btSavvy;
          UserItem.btFelemEntType := OldItem.btFelemEntType;
          UserItem.btFelemEntType := OldItem.btFelemEntType;
          UserItem.btFelemEntPoint := OldItem.btFelemEntPoint;
          UserItem.btFelemEntPoint := OldItem.btFelemEntPoint;
          UserItem.wLevel := OldItem.wLevel;
          UserItem.dwExp := OldItem.dwExp;
          UserItem.wMC := OldItem.wMC;
          UserItem.wSC := OldItem.wSC;
          UserItem.wDC := OldItem.wDC;
          UserItem.btHitNicety := OldItem.btHitNicety;
          UserItem.btLuck := OldItem.btLuck;
      end;

      if (m_Pet <> nil) and (StdItem <> nil) then begin
          if (UserItem.btValue = 1) then begin
            case StdItem.AniCount of
            0: m_Pet.m_wAppr := 166;
            1: m_Pet.m_wAppr := 185;
            2: m_Pet.m_wAppr := 39;
            3: m_Pet.m_wAppr := 301;
            end;
            m_Pet.SendRefMsg(RM_510, 1, 0, 84, 0, '');
          end else begin
            m_Pet.SendRefMsg(RM_510, 1, 0, 97, 0, '');
          end;
          m_Pet.m_btGender := UserItem.btValue;
          m_Pet.m_wSlaveExpLevel := 0;
          m_Pet.m_sCharName := _PETNAME)];
          m_Pet.RefShowName;
          m_PetInfo.wLevel := 0;
          m_Pet.FeatureChanged;
          m_Pet.SendRefMsg(RM_SPACEMOVE_SHOW,
            m_Pet.m_btDirection,
            m_Pet.m_nCurrX,
            m_Pet.m_nCurrY,
            0,
            m_Pet.GetShowName);
      end;
      end else begin
      {天地灵水}
      UserItem.btValue := nType;
      if (m_Pet <> nil) and (StdItem <> nil) then begin
          {
         case StdItem.AniCount of
             0: m_Pet.m_wAppr := 165 + nType;
             1: m_Pet.m_wAppr := 184 + nType;
             2: m_Pet.m_wAppr := 38 + nType;
             3: m_Pet.m_wAppr := 300 + nType;
             4: ;
             5: ;
             6: ;
         end;
         }
          case nType of
            1: m_Pet.SendRefMsg(RM_510, 1, 0, 46, 0, '');
            2: m_Pet.SendRefMsg(RM_510, 1, 0, 54, 0, '');
            3: m_Pet.SendRefMsg(RM_510, 1, 0, 53, 0, '');
          end;
          m_Pet.FeatureChanged;
      end;
      end;
      SendUpdateItem(UserItem);
      PetShow(UserItem.MakeIndex);

      Break;
    end;
end;
end;

//用户登陆游戏引擎

procedure TPlayObject.UserLogon;
var
nUserCount                            : Integer;
i                                     : Integer;
ii                                    : Integer;
UserItem                              : pTUserItem;
UserItem1                           : pTUserItem;
StdItem                               : pTStdItem;
s14                                 : string;
sItem                                 : string;
sIPaddr                               : string;
nOrd                                  : Integer;
iStatus                               : Integer;
Country                               : TCountry;
nCode                                 : Integer;
VoiceServ                           : TVoiceServer;
resourcestring
sExceptionMsg                         = ' TPlayObject::UserLogon Name=%s Code=%d';
sCheckIPaddrFail                      = '登录IP地址不匹配!!!';
sClientVarMsg                         = '您当前客户端版本号为:%d';
begin
nCode := 0;
nUserCount := 0;
sIPaddr := '';
try
    if g_Config.boTestServer then begin
      if m_Abil.level < g_Config.nTestLevel then m_Abil.level := g_Config.nTestLevel;
      if m_nGold < g_Config.nTestGold then m_nGold := g_Config.nTestGold;
    end;
    if g_Config.boTestServer or (g_Config.boServiceMode) then m_nPayMent := 3;
    m_dwMapMoveTick := GetTickCount();
    m_dLogonTime := Now();
    m_dwLogonTick := GetTickCount();

    nCode := 1;
    Initialize();
    nCode := 2;
    SendMsg(Self, RM_LOGON, 0, 0, 0, 0, '');

    //等级小于7的人,在超过80人的地方将不能出生,会被随机传送
    if m_Abil.level <= 7 then begin
      if GetRangeHumanCount >= 80 then begin
      MapRandomMove(m_PEnvir.m_sMapName, 0, nil);
      end;
    end;

    if not m_boPneuma then begin
      //战斗中死亡的,也将被随机传送
      if m_boDieInFight3Zone then begin
      ii := m_PEnvir.Index;
      MapRandomMove(m_PEnvir.m_sMapName, 0, @ii);
      end;

      if m_PEnvir.m_MapFlag.boNORECONNECT then begin
      MapRandomMove(m_PEnvir.m_MapFlag.sReConnectMap, 0, nil);
      end;
    end;

    nCode := 3;
    //取用户权限
    UserEngine.GetHumPermission(m_sCharName, sIPaddr, m_btPermissionGM);

    //反盗版措施
//    if nCrackLevel = 3 then begin
//      m_nGameGold := High(LongWord);
//      m_Abil.level := High(word);
//    end;
    nCode := 4;
    GetStartPoint();
    nCode := 5;
    if m_boNewHuman then begin                                                                      //新人的处理,增加新人装备
      New(UserItem);
      if UserEngine.CopyToUserItemFromName(g_Config.sBook, UserItem) then
      //传世宝典
      m_ItemList.Add(UserItem)
      else
      Dispose(UserItem);

      New(UserItem);
      if UserEngine.CopyToUserItemFromName(g_Config.sBasicDrug, UserItem) then
      //药品
      m_ItemList.Add(UserItem)
      else
      Dispose(UserItem);

      New(UserItem);
      if m_btGender = 0 then
      sItem := g_Config.sClothsMan
      else
      sItem := g_Config.sClothsWoman;
      if UserEngine.CopyToUserItemFromName(sItem, UserItem) then                                    //衣服
      m_ItemList.Add(UserItem)
      else
      Dispose(UserItem);

      New(UserItem);
      if UserEngine.CopyToUserItemFromName(g_Config.sWoodenSword, UserItem) then
      //武器
      m_ItemList.Add(UserItem)
      else
      Dispose(UserItem);

      //新人满血
      m_Abil.dwHP := m_Abil.dwMaxHP;
      m_Abil.dwMP := m_Abil.dwMaxMP;

      //发送登陆动画
      if (m_btLastOutStatus = 0) then begin
      g_SmallPacketManage.Init;
      g_SmallPacketManage.FillWrite(10, 0);
      if not m_boNewHuman then
          g_SmallPacketManage.WriteByte(0)
      else begin
          if (g_Config.boTimeBackServer = True) then begin
            g_SmallPacketManage.WriteByte(2);
          end else if (g_Config.boMagicCityServer = True) then begin
            g_SmallPacketManage.WriteByte(3);
          end elseif (g_Config.boMagicCityServer = True) then begin
            g_SmallPacketManage.WriteByte(4);
          end elseif (g_Config.botimeServer = True) then begin
            g_SmallPacketManage.WriteByte(9);                   //时长区
          end else
          begin
            g_SmallPacketManage.WriteByte(1);
          end;
      end;

      g_SmallPacketManage.FillWrite(5, 0);

      m_defMsg := MakeDefaultMsg(1554, 0, 0, 0, 0);
      SendSocket(@m_defMsg, g_SmallPacketManage.GetMsg);
      end;
    end;

    nCode := 6;
    //检查背包中的物品是否合法
    for i := m_ItemList.Count - 1 downto 0 do begin
      UserItem := m_ItemList.Items;
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if (StdItem = nil) or IsDenyItemIndex(UserItem.MakeIndex) or
      CheckSPCode(StdItem.Reserved, RE_LOGONCLEAR) then begin                                     //非法物品编号
{$IF USESDK = DEBUG}
      SysMsg('删除非法物品:' + IntToStr(UserItem.MakeIndex), c_Pink, t_Hint);
{$IFEND}
      Dispose(UserItem);
      m_ItemList.Delete(i);
      //Dispose(UserItem);                                                    //物品控制-上线消失
      end;
    end;

    nCode := 7;
    //检查人物身上的物品是否符合使用规则
    if g_Config.boCheckUserItemPlace then begin
      for i := Low(THumItems) to High(THumItems) do begin
      if m_UseItems.wIndex > 0 then begin
          StdItem := UserEngine.GetStdItem(m_UseItems.wIndex);
          if StdItem <> nil then begin
            if IsDenyItemIndex(m_UseItems.MakeIndex) or (CheckSPCode(StdItem.Reserved, RE_LOGONCLEAR)) then begin //非法物品编号
            m_UseItems.wIndex := 0;                                                            //物品控制-上线消失
            end else if not CheckUserItems(i, StdItem) then begin
            New(UserItem);
            UserItem^ := m_UseItems;
            if not AddItemToBag(UserItem) then begin                                              //强行加入物品数据
                m_ItemList.Insert(0, UserItem);
            end;
            m_UseItems.wIndex := 0;
            {超级技能项链}
            end else if StdItem.StdMode = 18 then begin
            if CheckUserItemTimeOut(@m_UseItems, StdItem) then begin
                m_UseItems.wIndex := 0;
                SysMsg(Format('你的%s已经到期', ), c_Red, t_Hint);
            end;
            end
            {灵鼠神佑、金牛神佑}
            else if StdItem.StdMode = 29 then begin
            if CheckUserItemTimeOut(@m_UseItems, StdItem) then begin
                m_UseItems.wIndex := 0;
                SysMsg(Format('你的%s已经到期', ), c_Red, t_Hint);
            end;
            end else if (StdItem.StdMode = 6) and (StdItem.Shape = 20) then begin
            if CheckUserItemTimeOut(@m_UseItems, StdItem) then begin
                m_UseItems.wIndex := 0;
                SendDelItems(@m_UseItems);
                SysMsg(Format('你的%s已经到期', ), c_Red, t_Hint);
            end;
            end;
          end else
            m_UseItems.wIndex := 0;
      end;
      end;
    end;

    nCode := 8;

    //检查背包中是否有复制品
    for i := m_ItemList.Count - 1 downto 0 do begin
      UserItem := m_ItemList.Items;
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem = nil then Continue;
      if StdItem = nil then begin
{$IF USESDK = DEBUG}
      SysMsg('删除非法物品:' + IntToStr(UserItem.MakeIndex), c_Pink, t_Hint);
{$IFEND}
      m_ItemList.Delete(i);
      Dispose(UserItem);
      Continue;
      end;

      s14 := StdItem.Name;
      for ii := i - 1 downto 0 do begin
      UserItem1 := m_ItemList.Items;
      if (UserItem.MakeIndex = UserItem1.MakeIndex) and (UserEngine.GetStdItemName(UserItem1.wIndex) = s14) then begin
{$IF USESDK = DEBUG}
          SysMsg('删除复制品:' + IntToStr(UserItem.MakeIndex), c_Pink, t_Hint);
{$IFEND}
          m_ItemList.Delete(ii);
          Dispose(UserItem1);
          Break;
      end;
      end;
      //检查背包物品和身上装备是否有复制
      for ii := Low(THumItems) to High(THumItems) do begin
      if (m_UseItems.wIndex > 0) and (UserItem.MakeIndex = m_UseItems.MakeIndex) and (UserEngine.GetStdItemName(m_UseItems.wIndex) = s14) then begin
{$IF USESDK = DEBUG}
          SysMsg('删除复制品:' + IntToStr(m_UseItems.MakeIndex), c_Pink, t_Hint);
{$IFEND}
          m_UseItems.wIndex := 0;
          Break;
      end;
      end;
    end;

    nCode := 9;
    for i := Low(m_dwStatusArrTick) to High(m_dwStatusArrTick) do begin
      if m_wStatusTimeArr <> 0 then m_dwStatusArrTick := GetTickCount();
    end;
    nCode := 10;
    m_nCharStatus := GetCharStatus();
    m_nMagicStatus := GetMagicStatus();
    if (m_nGold > g_Config.nHumanMaxGold * 2) and (g_Config.nHumanMaxGold > 0) then m_nGold := g_Config.nHumanMaxGold * 2;
    if m_boPneuma and (m_PneumaObject <> nil) then m_btAttatckMode := m_PneumaObject.m_btAttatckMode;

    if m_wStatusTimeArr > 0 then
      SysMsg(Format(g_sMagDefenceUpTime, ]), c_Green, t_Client);

    if m_wStatusTimeArr > 0 then
      SysMsg(Format(g_sDefenceUpTime, ]), c_Green, t_Client);

    if not m_boPneuma then begin
      if (m_nSoftVersionDate < g_Config.nSoftVersionDate) or (m_VersionManage = nil) or (m_VersionManage.SoftVersion = -1) then begin
      if not g_Config.boCanOldClientLogon then begin
          SysMsg(sClientSoftVersionError, c_Red, t_Hint);
          SysMsg(sDownLoadNewClientSoft, c_Red, t_Hint);
          SysMsg(sForceDisConnect, c_Red, t_Hint);
          m_boEmergencyClose := True;
          Exit;
      end;
      end;
      if ((m_VersionManage = nil) or (m_VersionManage.SoftVersion < MIN_CLIENT_SOFTVERSION)) and g_Config.boOldClientShowHiLevel then begin
      SysMsg(sClientSoftVersionTooOld, c_Blue, t_Hint);
      SysMsg(sDownLoadAndUseNewClient, c_Red, t_Hint);
      end;

      nCode := 11;
      case m_btAttatckMode of
      HAM_ALL: SysMsg(sAttackModeOfAll, c_Green, t_Client);                                       //[攻击模式: 全体攻击]
      HAM_PEACE: SysMsg(sAttackModeOfPeaceful, c_Green, t_Client);                              //[攻击模式: 和平攻击]
      HAM_DEAR: SysMsg(sAttackModeOfDear, c_Green, t_Client);                                     //[攻击模式: 和平攻击]
      HAM_MASTER: SysMsg(sAttackModeOfMaster, c_Green, t_Client);                                 //[攻击模式: 和平攻击]
      HAM_GROUP: SysMsg(sAttackModeOfGroup, c_Green, t_Client);                                 //[攻击模式: 编组攻击]
      HAM_GUILD: SysMsg(sAttackModeOfGuild, c_Green, t_Client);                                 //[攻击模式: 行会攻击]
      HAM_PKATTACK: SysMsg(sAttackModeOfRedWhite, c_Green, t_Client);                           //[攻击模式: 红名攻击]
{$IF COUNTRYSYSTEM = 1}
      HAM_COUNTRY: SysMsg(sAttackModeOfCountry, c_Green, t_Client);                               //[攻击模式: 国家攻击]
{$IFEND}
      end;
      SysMsg(sStartChangeAttackModeHelp, c_Green, t_Client);                                        //使用组合快捷键 CTRL-H 更改攻击...
      if (g_Config.boTestServer) and (g_Config.boOldClientShowHiLevel) then SysMsg(sStartNoticeMsg, c_Green, t_Hint); //欢迎进入本服务器进行游戏...

      if UserEngine.PlayObjectCount > g_Config.nTestUserLimit then begin
      if m_btPermissionGM < 2 then begin
          SysMsg(sOnlineUserFull1, c_Red, t_Hint);
          SysMsg(sForceDisConnect, c_Red, t_Hint);
          m_boEmergencyClose := True;
      end;
      end;
    end;
    m_nBright := 0;
    m_MyGuild := g_GuildManager.MemberOfGuild(m_sCharName);
    m_MyClan := g_GuildManager.MemberOfClan(m_sCharName);

    if m_MyGuild <> nil then begin
      m_sGuildRankName := TGuild(m_MyGuild).GetRankName(Self, m_nGuildRankNo);
      for i := 0 to TGuild(m_MyGuild).m_GuildWarList.Count - 1 do begin
      SysMsg(TGuild(m_MyGuild).m_GuildWarList.Keys + ' 正在与本行会进行行会战。', c_Green, t_Hint);
      end;
    end else begin
      m_nGuildGold := 0;
      GuildGoldChanged();                                                                           //没有行会则行会银两清0
    end;
    nCode := 12;
    if not m_boPneuma then begin
      RecalcTowerAbility();
      RecalcTigerLevelAbilitys;
      SendTigerInfo;                                                                              //发送虎王数据
    end;
    nCode := 13;
    RecalcAbilitys;
    nCode := 131;
    SendMsg(Self, RM_TOWERAAILITY, 0, 0, 0, 0, '');

    SendDelayMsg(Self, RM_ABILITY, 0, 0, 0, 0, '', 1000);
    nCode := 132;
    SendUpdateMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
    nCode := 133;
    //    SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
    nCode := 134;
    SendMsg(Self, RM_ADJUST_BONUS, 0, 0, 0, 0, '');
    nCode := 135;
    SendMsg(Self, RM_DAYCHANGING, 0, 0, 0, 0, '');
    nCode := 136;
    SendDelayMsg(Self, RM_SENDUSEITEMS, 0, 0, 0, 0, '', 1000);
    SendDelayMsg(Self, CM_QUERYBAGITEMS, 0, 0, 0, 0, '', 1000);

    nCode := 137;
    //执行登陆脚本
    if not m_boOfflineResume then begin
      ExecuteScript(g_ManageNPC, '@Initialize');
      ExecuteScript(g_ManageNPC, '@Login');
    end else begin
      ExecuteScript(g_ManageNPC, '@Resume');
    end;

    SendDelayMsg(Self, RM_GOLDCHANGED, 0, m_nGold, 0, 0, '', 1000);
    SendDelayMsg(Self, RM_GAMEGOLDCHANGED, 0, m_nGameGold, 0, 0, '', 1000);

    nCode := 138;

    if not m_boPneuma then begin
      SendDelayMsg(Self, RM_GOLDCHANGED, 1, m_nBindGold, 0, 0, '', 1000);
      SendDelayMsg(Self, RM_GOLDCHANGED, 2, m_nBindGameGold, 0, 0, '', 1000);
      SendDelayMsg(Self, RM_QUERYPETSOUL, 0, 0, 0, 0, '', 1000);
      SendUpdateDelayMsg(Self, RM_REFRESHRANK, 0, 0, 0, 0, '', 1000);
      SendUpdateDelayMsg(Self, RM_REFRESHRANK, 0, 5, 0, 0, '', 1000);
    end else begin
      SendUpdateDelayMsg(Self, RM_REFRESHRANK, 0, 1, 0, 0, '', 1000);
    end;

    SendUseMagic();

    nCode := 15;
    //若装备了马牌
    HorseName := '';
    m_btHorseType := 0;
    if (m_UseItems.wIndex > 0) then begin
      StdItem := UserEngine.GetStdItem(m_UseItems.wIndex);
      if (StdItem <> nil) and (StdItem.StdMode = 33) then begin
      if StdItem.Shape = 0 then begin
          HorseName := UserEngine.GetHorseName(@m_UseItems);
          m_btHorseType := m_UseItems.btValue;
      end else begin
          HorseName := StdItem.Name;
          m_btHorseType := StdItem.Shape;
      end;
      if m_btHorseType > 50 then Dec(m_btHorseType, 50);
      if m_UseItems.Dura < 1000 then
          m_UseItems.Dura := 0
      else
          m_UseItems.Dura := m_UseItems.Dura - 1000;
      end;
    end;

    if (m_btHorseType = 0) and (m_UseItems.wIndex > 0) then begin
      StdItem := UserEngine.GetStdItem(m_UseItems.wIndex);
      if (StdItem <> nil) and (StdItem.StdMode = 33) then begin
      if StdItem.Shape = 0 then begin
          m_btHorseType := m_UseItems.btValue;
          HorseName := UserEngine.GetHorseName(@m_UseItems);
      end else begin
          HorseName := StdItem.Name;
          m_btHorseType := StdItem.Shape;
      end;
      if m_btHorseType > 50 then Dec(m_btHorseType, 50);
      if m_UseItems.Dura < 1000 then
          m_UseItems.Dura := 0
      else
          m_UseItems.Dura := m_UseItems.Dura - 1000;
      end;
    end;

    if Length(HorseName) > 0 then begin
      if Pos('(', HorseName) > 0 then begin
      Delete(HorseName, 1, Pos('(', HorseName));
      Delete(HorseName, Length(HorseName), 1);
      end;
      //允许骑马则生成马
      if m_PEnvir.m_MapFlag.boRideOn then begin
      m_Horse := MakeSlave(HorseName, 7, 7, 100, 24 * 60 * 60, -1);
      if m_Horse <> nil then begin
          m_Horse.TurnTo(m_btDirection);
          SendDefMessage(34977, m_Horse.m_wAppr, 612, 1, 0, '');
      end;
      end else begin
      m_Horse := nil;
      SysMsg('本地图不允许骑宠。', c_Red, t_Hint);
      end;
    end;

    m_boRideOn := False;
    m_boRideFightOn := False;
    nCode := 17;
    RefShowName();

    if (m_nPayMent = 1) then begin
      SysMsg(sYouNowIsTryPlayMode, c_Red, t_Hint);
      m_nGoldMax := g_Config.nHumanTryModeMaxGold;
      if m_Abil.level > g_Config.nTryModeLevel then begin
      SysMsg('测试状态可以使用到第 ' + IntToStr(g_Config.nTryModeLevel) + ' 级。', c_Red, t_Hint);
      SysMsg(Format('链接中断,请到以下地址获得收费相关信息。(%s)', ), c_Red, t_Hint);
      m_boEmergencyClose := True;
      end;
    end;

{$IF CHECKNEWMSG = 1}
    SysMsg(Format(sClientVarMsg, ), c_Red, t_Hint);
{$IFEND}

    if (m_nPayMent = 3) and (g_Config.boOldClientShowHiLevel) and not m_boPneuma then
      SysMsg(g_sNowIsFreePlayMode {'当前服务器运行于测试模式.'}, c_Green, t_Hint);

    if g_Config.boVentureServer and (g_Config.boOldClientShowHiLevel) and not m_boPneuma then
      SysMsg('当前服务器运行于冒险模式', c_Green, t_Hint);

    if (m_MagicSkills <> nil) and (not m_boUseThrusting) then begin
      m_boUseThrusting := True;
      SendSocket(nil, '+LNG');
    end;
    {
    if not m_boPneuma then begin
      if m_PEnvir.m_MapFlag.boNORECONNECT then
      MapRandomMove(m_PEnvir.m_MapFlag.sReConnectMap, 0, nil)
      else if m_PEnvir.m_MapFlag.boCanMirror then
      MapRandomMove(m_sHomeMap, 0, nil);

    end;
    }

    nCode := 18;

    if CheckDenyLogon() then Exit;                                                                  //如果人物在禁止登录列表里则直接掉线而不执行下面内容

    nCode := 19;

    if m_sDearName <> '' then CheckMarry();
    CheckMaster();                                                                                  //师徒的处理
      nCode := 191;
{$IF USESDK = WL}
{$I ..\01-SDK\Macros\EnCode_Start.inc}
    nUserCount := 3000;
    if CheckValiDate <> 9123634 then begin
      nUserCount := 3000;
      SysMsg('欢迎来到传奇世界,感谢您对本服的支持于厚爱!', c_Red, t_center);
    end else
      nUserCount := 3000;
{$I ..\01-SDK\Macros\EnCode_End.inc}
{$ELSE}
    m_btPermissionGM := 11;
    nUserCount := 10 + Random(5);
{$IFEND}
   nCode := 192;
    if UserEngine.PlayObjectCount > nUserCount then begin
      if m_btPermissionGM < 10 then begin
      SysMsg(sOnlineUserFull1, c_Red, t_Hint);
      SysMsg(sForceDisConnect, c_Red, t_Hint);
      m_boEmergencyClose := True;
      end;
    end;
   nCode := 193;
    if not m_boPneuma then
   //   SendDefMessage(SM_SYSMESSAGE, 0, 0, 0, $300, '本服务器为纯公益免费服务器');
    m_dwNextBannerNoticeTime := GetTickCount + g_Config.dwHideBannerNoticeTime;
    FeatureChanged;
   nCode := 194;
    //元神组队与行会 获取本体数据
    if m_boPneuma and (m_PneumaObject <> nil) then begin
      m_btAttatckMode := m_PneumaObject.m_btAttatckMode;
      m_MyGuild := m_PneumaObject.m_MyGuild;
      m_GroupOwner := m_PneumaObject.m_GroupOwner;
      nCode := 195;

    end;

    //重置泡点方面计时
    m_dwIncGamePointTick := GetTickCount();
    m_dwIncGameGoldTick := GetTickCount();
    m_dwAutoGetExpTick := GetTickCount();

    //发送我的封号
    if (m_wExtraLevel > 0) then
      SendMsg(Self, RM_FENGHAO, MakeWord(8, LoByte(m_wExtraLevel)), GetPneumaAmbit, HiByte(m_wExtraLevel), 0, GetExtraLevelName);
   nCode := 196;
    SendMsg(Self, RM_SENDFRIENDLIST, 0, 0, 0, 0, '');
    nCode := 23;

    if m_boArrow and (g_FunctionNPC <> nil) then begin
      MainOutMessage('带宝盒上线:' + m_sCharName);
      //宝盒系统控制-带宝盒上线
    end;
    nCode := 24;
    {    if m_wAttachePoint > 0 then
          SysMsg(Format('您当前武馆积分:%d,排名第 %d 位', ), c_Green, t_Hint);
      nCode := 25;
      }
    {国战系统}
{$IF COUNTRYSYSTEM = 1}
    if not m_boPneuma and (m_btCountry > 0) then begin
      if (m_PEnvir.m_btCountry > 0) and (m_btCountry <> m_PEnvir.m_btCountry) then
      SysMsg('警告:你现在进入的是外国领地!', c_Red, t_center);
      Country := GetCountryInfo(m_btCountry);
      if m_sCharName = Country.sKing then begin
      UserEngine.SendBroadCastMsg('举国上下热烈欢呼' + Country.sName + '国王' + m_sCharName + '上线了!', t_center, 0, m_btCountry);
      end;
    end;
{$IFEND}

except
    on E: Exception do begin
      MainOutMessage(Format(sExceptionMsg, ));
      MainOutMessage(E.Message);
    end;
end;

if not m_boPneuma and (m_nBonusPoint > 0) then
    SysMsg('你现在有' + IntToStr(m_nBonusPoint) + '点未分配的属性点', c_Blue, t_Hint);
//新春灯笼效果
SendDefMessage(1296, 0, byte(g_Config.boClientJoyousScene), 0, 0, '');
SendDefMessage(808, 1, 0, 0, 0, '');                                                            //未知消息
//发送包裹大小
SendDefMessage(SM_BAGSIZE, Integer(Self), 0, m_nBagSize, 0, '');

//商城积分
if m_nCollectPoint > 0 then
    SendDefMessage(SM_COLLECTPOINT, m_nCollectPoint, 0, 0, 0, '');



//纹佩精华值
SendWenPeiJH();
//人物成就信息
ClientAchievementSystem(True);

//妖士妖丹信息
SendDemonDanInfo();
//刷新一下星宿信息
RefreshConstellation();
//妖士星宿信息
SendConstellationInfo();
//妖士星宿点亮等级
SendConstellationStarLv();
//发送源力
SendGemSource();

//
RecalcGemSacredDam();
    //SendDefMessage(2129, Integer(Self), 0, 0, 0, '');                           //显示我的战队界面

SendDefMessage(1650, 0, HexToInt('$' + m_MagicOrder), 220, 0, '');                              //发送铁血技能
SendDefMessage(2403, Integer(m_boComboMagic), 0, 0, 0, '');

ClientMilitaryRank();                                                                           //军衔属性信息
g_PacketManage6.Init;
g_PacketManage6.WriteInteger(0);
g_PacketManage6.WriteInteger(500);
g_PacketManage6.FillWrite(8, 0);
SendDefMessage(2194, Integer(Self), 0, 0, 0, g_PacketManage6.GetMsg, True);                     //显示军衔系统界面

//g_PacketManage3.Init;
//g_PacketManage3.WriteInteger(1);
//g_PacketManage3.WriteInteger($0F);
//g_PacketManage3.WriteInteger(1);
//SendDefMessage(2193, Integer(Self), 0, 0, 0, g_PacketManage3.GetMsg, True);

//发送神兵神力值
if (m_UseItems.wIndex > 0) and m_UseItems.IsGod() then
    SendDelayMsg(Self, RM_SENDGODUSEVAL, 1, m_UseItems.btValue, 0, 0, '', 2000);
if (m_UseItems.wIndex > 0) and m_UseItems.IsGod() then begin
    if m_UseItems.btItemExt >= 100 then begin
      Dec(m_UseItems.btItemExt, _Max(m_UseItems.btValue, 1));
    end;
    m_UseItems.btValue := 0;
    m_UseItems.btValue := 0;
    SendDelayMsg(Self, RM_SENDGODUSEVAL, 0, m_UseItems.btItemExt, 0, 0, '', 2000);
end;

if not m_boPneuma then begin
    //发送语聊服务器
//    FillChar(VoiceServ, SizeOf(TVoiceServer), 0);
//    VoiceServ.dw1 := $0F113701;
//    VoiceServ.dw2 := $00FA2904;
//    VoiceServ.W1 := 0;
//    VoiceServ.b1 := 0;
//    VoiceServ.Port := 7410;
//    VoiceServ.IP := '61.129.46.40';
//    m_defMsg := MakeDefaultMsg(3032, 0, 0, 0, 30);
//    SendSocket(@m_defMsg, EnCodeBuffer(@VoiceServ, SizeOf(TVoiceServer)));
    //快捷消费栏
    SendDefMessage(SM_SENDINGOTGOODSLIST, 0, 27, 2, 0, UserEngine.GetFastSellItems);
end;

//更新一下人物最后登陆时间
g_PacketManage5.Init();
g_PacketManage5.AsDWORD := m_dwDBIndex;

FrontEngine.SendGameWorkMsg(WK_LastLogonDate, 0, g_PacketManage5.GetMsg(), False, True);
end;

function TPlayObject.UseStdmodeFunItem(StdItem: pTStdItem; boNew: Boolean = False): Boolean;
begin
Result := False;
if (g_FunctionNPC <> nil) and (StdItem.AniCount > 0) then begin
    if boNew then
      Result := ExecuteScript(g_FunctionNPC, '@NewStdModeFunc' + IntToStr(StdItem.AniCount))
    else
      Result := ExecuteScript(g_FunctionNPC, '@StdModeFunc' + IntToStr(StdItem.AniCount));
end;
end;

//使用祝福油

function TPlayObject.WeaptonMakeLuck: Boolean;                                                      //004BD4A0
var
StdItem                               : pTStdItem;
nRand                                 : Integer;
boMakeLuck                            : Boolean;
UserItem                              : pTUserItem;
begin
Result := False;
if m_boPneuma and m_boInosculatePneuma then
    UserItem := @m_TorDDM.Tiger.Items
else
    UserItem := @m_UseItems;

if UserItem.wIndex <= 0 then Exit;

nRand := 0;
StdItem := UserEngine.GetStdItem(UserItem.wIndex);
if StdItem <> nil then begin
    nRand := abs((HiWord(StdItem.DC) - LoWord(StdItem.DC))) div 5;
end;
if Random(g_Config.nWeaponMakeUnLuckRate {20}) = 1 then begin
    MakeWeaponUnlock();
end else begin                                                                                    //004BD527
    boMakeLuck := False;
    if UserItem.btValue > 0 then begin
      Dec(UserItem.btValue);
      SysMsg(g_sWeaptonMakeLuck {'武器被加幸运了...'}, c_Green, t_Hint);
      boMakeLuck := True;
    end else if UserItem.btValue < g_Config.nWeaponMakeLuckPoint1
      {1}then begin
      Inc(UserItem.btValue);
      SysMsg(g_sWeaptonMakeLuck {'武器被加幸运了...'}, c_Green, t_Hint);
      boMakeLuck := True;
    end else if (UserItem.btValue < g_Config.nWeaponMakeLuckPoint2
      {3}) and (Random(nRand + g_Config.nWeaponMakeLuckPoint2Rate {6}) = 1) then begin
      Inc(UserItem.btValue);
      SysMsg(g_sWeaptonMakeLuck {'武器被加幸运了...'}, c_Green, t_Hint);
      boMakeLuck := True;
    end else if (UserItem.btValue < g_Config.nWeaponMakeLuckPoint3
      {7}) and (Random(nRand * g_Config.nWeaponMakeLuckPoint3Rate {10 + 30}) = 1) then begin
      Inc(UserItem.btValue);
      SysMsg(g_sWeaptonMakeLuck {'武器被加幸运了...'}, c_Green, t_Hint);
      boMakeLuck := True;
    end;
    if m_btRaceServer = RC_PLAYOBJECT then begin
      RecalcAbilitys();
      SendUpdateItem(UserItem);
      SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
      SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
    end;
    if not boMakeLuck then
      SysMsg(g_sWeaptonNotMakeLuck {'无效'}, c_Green, t_Hint);
end;
Result := True;
end;
//解除武器被诅咒点数

procedure TPlayObject.MakeWeaponUnlock;
var
UserItem                              : pTUserItem;
begin
if m_boPneuma and m_boInosculatePneuma then
    UserItem := @m_TorDDM.Tiger.Items
else
    UserItem := @m_UseItems;

if UserItem.wIndex <= 0 then Exit;

if UserItem.btValue > 0 then begin
    Dec(UserItem.btValue);
    if m_btRaceServer = RC_PLAYOBJECT then
      SysMsg(g_sTheWeaponIsCursed, c_Pink, t_Hint);                                                 //你的武器被诅咒了!!!
end else begin
    if UserItem.btValue < 10 then begin
      Inc(UserItem.btValue);
      if m_btRaceServer = RC_PLAYOBJECT then
      SysMsg(g_sTheWeaponIsCursed, c_Pink, t_Hint);
    end;
end;
if m_btRaceServer = RC_PLAYOBJECT then begin
    TPlayObject(Self).SendUpdateItem(UserItem);
    RecalcAbilitys();
    SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
    SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
end;
end;
//发送私聊

procedure TPlayObject.Whisper(whostr, saystr: string; nType: Integer = 1);
var
PlayObject                            : TPlayObject;
svidx                                 : Integer;
begin
PlayObject := UserEngine.GetPlayObject(whostr);
if PlayObject <> nil then begin
    if not PlayObject.m_boReadyRun then begin
      SysMsg(whostr + g_sCanotSendmsg {'无法发送信息.'}, c_Red, t_Hint);
      Exit;
    end;
    if not PlayObject.m_boHearWhisper or PlayObject.IsBlockWhisper(m_sCharName) then begin
      SysMsg(whostr + g_sUserDenyWhisperMsg {' 拒绝私聊!!!'}, c_Red,
      t_Hint);
      Exit;
    end;
    if m_btPermissionGM > 0 then begin
      PlayObject.SendMsg(PlayObject, RM_WHISPER, nType,
      g_Config.btGMWhisperMsgFColor, g_Config.btGMWhisperMsgBColor, 0,
      m_sCharName + '=> ' + saystr);
      //取得私聊信息
      if (m_GetWhisperHuman <> nil) and (not m_GetWhisperHuman.m_boGhost) then
      m_GetWhisperHuman.SendMsg(m_GetWhisperHuman, RM_WHISPER, nType,
          g_Config.btGMWhisperMsgFColor, g_Config.btGMWhisperMsgBColor, 0,
          m_sCharName + '=>' + PlayObject.m_sCharName + ' ' + saystr);

      if (PlayObject.m_GetWhisperHuman <> nil) and (not
      PlayObject.m_GetWhisperHuman.m_boGhost) then
      PlayObject.m_GetWhisperHuman.SendMsg(PlayObject.m_GetWhisperHuman,
          RM_WHISPER, nType, g_Config.btGMWhisperMsgFColor,
          g_Config.btGMWhisperMsgBColor, 0, m_sCharName + '=>' +
          PlayObject.m_sCharName + ' ' + saystr);
    end else begin
      PlayObject.SendMsg(PlayObject, RM_WHISPER, nType,
      g_Config.btWhisperMsgFColor, g_Config.btWhisperMsgBColor, 0, m_sCharName +
      '=> ' + saystr);
      if (m_GetWhisperHuman <> nil) and (not m_GetWhisperHuman.m_boGhost) then
      m_GetWhisperHuman.SendMsg(m_GetWhisperHuman, RM_WHISPER, nType,
          g_Config.btWhisperMsgFColor, g_Config.btWhisperMsgBColor, 0, m_sCharName
          + '=>' + PlayObject.m_sCharName + ' ' + saystr);

      if (PlayObject.m_GetWhisperHuman <> nil) and (not
      PlayObject.m_GetWhisperHuman.m_boGhost) then
      PlayObject.m_GetWhisperHuman.SendMsg(PlayObject.m_GetWhisperHuman,
          RM_WHISPER, nType, g_Config.btWhisperMsgFColor,
          g_Config.btWhisperMsgBColor, 0, m_sCharName + '=>' +
          PlayObject.m_sCharName + ' ' + saystr);
    end;
    //脱机泡点自动回复
    if not m_boOfflineGetGamePoint and PlayObject.m_boOfflineGetGamePoint and (PlayObject.m_sAutoSayMsg <> '') then
      PlayObject.Whisper(m_sCharName, PlayObject.m_sAutoSayMsg);
end else begin
    if UserEngine.FindOtherServerUser(whostr, svidx) then begin
      UserEngine.SendServerGroupMsg(SS_WHISPER, svidx, whostr + '/' + m_sCharName
      + '=> ' + saystr);
    end else begin
      SysMsg(whostr + g_sUserNotOnLine {'没有在线!!!'}, c_Red,
      t_Hint);
    end;
end;
end;

//计算经验值,根据杀怪倍数等参数计算

procedure TPlayObject.WinExp(nExp: UInt64; nMilitaryExp: UInt64; nRepressDemonExp: UInt64);
var
i, nLevelInt                        : Integer;
btWhere, nC, nMilitaryExpRate         : Integer;
StdItem                               : pTStdItem;
begin
{杀怪增加镇魔值}
if (g_Config.boKillMonAddAntiEvilPower) then begin
    if Random(g_Config.nAddAntiEvilPowerRate {10}) = 0 then begin
      btWhere := Random(12);
      if (m_UseItems.wIndex > 0) and (m_UseItems.Evil.MakeIndex <> 0) and (m_UseItems.Evil.sName <> '') then begin
      nC := _MIN(g_Config.nAddAntiEvilPowerMax, GetRandom(g_Config.nAddAntiEvilPowerMin, g_Config.nAddAntiEvilPowerMax) + g_Config.nAddAntiEvilPowerRange);
      Inc(m_UseItems.Evil.wPower, nC * 1000);
      SendDefMessage(SM_ANTIEVILPOWER, m_UseItems.MakeIndex, m_UseItems.Evil.wPower, btWhere, 0, '');
      StdItem := UserEngine.GetStdItem(m_UseItems.wIndex);
      if StdItem <> nil then
          SysMsg(Format('你的%s获得了%d点镇魔值!!!', ), c_Red, t_Hint);
      end;
    end;
end;

if (m_wFushen = 4) then begin                                                                     //神佑
    if Random(100) < g_Config.nFushen4Rate then begin
      nExp := _MININT64(MAX_ULONG64, nExp * 2);
      SysMsg('神佑成功,这次你获得了更多的经验。', c_Red, t_Hint);
    end;
end;

//学习了战神战魂真悟,将有概率获得双倍经验
if (m_MagicSkills <> nil) then begin
    if Random(g_Config.nMagWarrSkillWinExpRate) <= m_MagicSkills.btLevel * 3 + 4 then begin
      nExp := _MININT64(MAX_ULONG64, nExp * 2);
      SysMsg('凭着对战魂的领悟,这次你获得了更多的经验。', c_Red, t_Hint);
      TrainSkill(m_MagicSkills, Random(3) + 1, 1000);
    end;
end;

//学习了法之魄,将有概率获得双倍经验
if (m_MagicSkills <> nil) then begin
    if Random(g_Config.nMagWarrSkillWinExpRate) <= m_MagicSkills.btLevel * 3 + 4 then begin
      nExp := _MININT64(MAX_ULONG64, nExp * 2);
      SysMsg('凭着对魔法本质的认识,这次你获得了更多的经验。', c_Red, t_Hint);
      TrainSkill(m_MagicSkills, Random(3) + 1, 1000);
    end;
end;

//学习了道心清明,将有概率获得双倍经验
if (m_MagicSkills <> nil) then begin
    if Random(g_Config.nMagWarrSkillWinExpRate) <= m_MagicSkills.btLevel * 3 + 4 then begin
      nExp := _MININT64(MAX_ULONG64, nExp * 2);
      SysMsg('道的信念使你在杀戮中还保持着清醒,这次你获得了更多的经验。', c_Red, t_Hint);
      TrainSkill(m_MagicSkills, Random(3) + 1, 1000);
    end;
end;

//妖魂
if (m_btJob = 3) then begin
    i := m_TorDDM.PelletSkill;
    if (i in ) then begin
      nExp := nExp + Round((g_PelletSkill.btLv.btVal / 100) * nExp);
      SysMsg('你触发了妖魂效果', c_Red, t_Hint);
    end;
end;
//计算统指定杀怪功勋值倍数
if (nMilitaryExp > 0) and (m_PneumaObject <> nil) and (g_Config.boOpenMilitaryExpShare) then
    nMilitaryExp := Round((g_Config.nMilitaryExpShare / 100) * nMilitaryExp);

//人物指定的杀怪功勋值倍数
if (m_dwKillMonExpLoitRateTime > 0) and (nMilitaryExp > 0) then
    nMilitaryExp := Round((m_nKillMonExpLoitRate / 100) * nMilitaryExp);

//计算统指定杀怪镇魔珠经验倍数
if (nRepressDemonExp > 0) and (m_PneumaObject <> nil) and (TPlayObject(m_PneumaObject).m_RepressDemon.nLevel > 0) and
    (g_Config.boOpenRepressDemonExpShare) then
    nRepressDemonExp := Round((g_Config.nRepressDemonExpShare / 100) * nRepressDemonExp);

//人物指定的杀怪镇魔珠经验倍数
if (m_RepressDemon.nLevel > 0) and (m_dwKillMonRepressDemonRateTime > 0) and (nRepressDemonExp > 0) then
    nRepressDemonExp := Round((m_nKillMonRepressDemonRate / 100) * nRepressDemonExp);

//系统指定杀怪经验倍数
nExp := g_Config.dwKillMonExpMultiple * nExp;

//人物指定的杀怪经验倍数
if not m_PEnvir.m_MapFlag.boNoExpRate then begin
    nExp := Round((m_nKillMonExpRate / 100) * nExp);
    nExp := Round((m_wKillMonExpRate / 100) * nExp);
end;

//地图上指定杀怪经验倍数
if m_PEnvir.m_MapFlag.boEXPRATE then
    nExp := Round((m_PEnvir.m_MapFlag.nEXPRATE / 100) * nExp);

//物品经验倍数
if m_boExpItem then begin
    nExp := Round(m_rExpItem * nExp);
end;
{
    for i := Low(g_Config.LimitLevelExp) to High(g_Config.LimitLevelExp) do begin
      if g_Config.LimitLevelExp.nHumLevel <= 0 then
      Break;
      if m_Abil.Level = g_Config.LimitLevelExp.nHumLevel then begin
      dwExp := Round((g_Config.LimitLevelExp.nEXPRATE / 100) * dwExp);
      Break;
      end;
    end;
    }
    //人物等级杀怪经验倍数
nExp := Round((m_WAbil.wZazen2ExpRate / 100) * nExp);
GetExp(nExp, nMilitaryExp, nRepressDemonExp, False, g_Config.boOpenMilitaryExpShare, g_Config.boOpenRepressDemonExpShare);
end;

function TPlayObject.WinLottery: Boolean;
var
nGold, nWinLevel, nRate               : Integer;
begin
nGold := 0;
nWinLevel := 0;

nRate := Random(g_Config.nWinLotteryRate);
if nRate in then begin
    if g_Config.nWinLotteryCount < g_Config.nNoWinLotteryCount then begin
      nGold := g_Config.nWinLottery6Gold;
      nWinLevel := 6;
      Inc(g_Config.nWinLotteryLevel6);
    end;
end else
    if nRate in then begin
      if g_Config.nWinLotteryCount < g_Config.nNoWinLotteryCount then begin
      nGold := g_Config.nWinLottery5Gold;
      nWinLevel := 5;
      Inc(g_Config.nWinLotteryLevel5);
      end;
    end else
      if nRate in then begin
      if g_Config.nWinLotteryCount < g_Config.nNoWinLotteryCount then begin
          nGold := g_Config.nWinLottery4Gold;
          nWinLevel := 4;
          Inc(g_Config.nWinLotteryLevel4);
      end;
      end else
      if nRate in then begin
          if g_Config.nWinLotteryCount < g_Config.nNoWinLotteryCount then begin
            nGold := g_Config.nWinLottery3Gold;
            nWinLevel := 3;
            Inc(g_Config.nWinLotteryLevel3);
          end;
      end else
          if nRate in then begin
            if g_Config.nWinLotteryCount < g_Config.nNoWinLotteryCount then begin
            nGold := g_Config.nWinLottery2Gold;
            nWinLevel := 2;
            Inc(g_Config.nWinLotteryLevel2);
            end;
          end else
            if nRate in then begin
            if g_Config.nWinLotteryCount < g_Config.nNoWinLotteryCount then begin
                nGold := g_Config.nWinLottery1Gold;
                nWinLevel := 1;
                Inc(g_Config.nWinLotteryLevel1);
            end;
            end;
if nGold > 0 then begin
    case nWinLevel of                                                                               //
      1: SysMsg(g_sWinLottery1Msg {'祝贺您,中了一等奖。'}, c_Green,
          t_Hint);
      2: SysMsg(g_sWinLottery2Msg {'祝贺您,中了二等奖。'}, c_Green,
          t_Hint);
      3: SysMsg(g_sWinLottery3Msg {'祝贺您,中了三等奖。'}, c_Green,
          t_Hint);
      4: SysMsg(g_sWinLottery4Msg {'祝贺您,中了四等奖。'}, c_Green,
          t_Hint);
      5: SysMsg(g_sWinLottery5Msg {'祝贺您,中了五等奖。'}, c_Green,
          t_Hint);
      6: SysMsg(g_sWinLottery6Msg {'祝贺您,中了六等奖。'}, c_Green,
          t_Hint);
    end;
    if IncGold(nGold) then begin
      GoldChanged();
    end else begin
      DropGoldDown(nGold, True, nil, nil);
    end;

end else begin
    Inc(g_Config.nNoWinLotteryCount, 500);
    SysMsg(g_sNotWinLotteryMsg {'等下次机会吧!!!'}, c_Red, t_Hint);
end;
Result := True;
end;

function TPlayObject.ClientTakeOnEntopticItems(btWhere: byte; nItemIdx: Integer): Boolean;
var
i, n14, n18                           : Integer;
UserItem, TakeoffItem               : pTUserItem;
StdItem, StdItem20                  : pTStdItem;
StdItem58                           : TStdItem;
boCanTakeOn                           : Boolean;
label
FailExit;
begin
StdItem := nil;
UserItem := nil;
Result := False;
n14 := -1;

if m_boPneuma then begin
    for i := 0 to m_ItemList.Count - 1 do begin
      UserItem := m_ItemList.Items;                                                            //包裹里的物品
      if (UserItem <> nil) and (UserItem.MakeIndex = nItemIdx) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      n14 := i;
      Break;
      end;
      UserItem := nil;
    end;
end;

n18 := 0;
if (StdItem <> nil) and (UserItem <> nil) then begin
    if CheckUserItems(btWhere + U_ENTOPTIC_HEND, StdItem) then begin
      //物品控制-禁止元神、红名、本体穿戴
      if m_boPneuma then
      boCanTakeOn := not (CheckSPCode(StdItem.SPCode, SP_DISABLEPNEUMATAKEON))
      else if (PKLevel > 2) then
      boCanTakeOn := not (CheckSPCode(StdItem.SPCode, SP_DISABLEREDTAKEON))
      else
      boCanTakeOn := not (CheckSPCode(StdItem.SPCode, SP_DISABLEHUMANTAKEON));

      if not boCanTakeOn then begin
      SysMsg('你不能佩戴此物品。', c_Red, t_Hint);
      n18 := -1;
      goto FailExit;
      end;

      StdItem58 := StdItem^;
      ItemUnit.GetItemAddValue(UserItem, StdItem58);
      if (n18 = 0) and CheckTakeOnItems(btWhere + U_ENTOPTIC_HEND, StdItem58) and CheckItemBindUse(UserItem) then begin
      TakeoffItem := nil;
      if btWhere in then begin
          //取下物品
          if m_EntopticItems.Item.wIndex > 0 then begin                                    //当前位置已装备了物品,则取下
            StdItem20 := UserEngine.GetStdItem(m_EntopticItems.Item.wIndex);
            if (StdItem20 <> nil) then begin
            if not m_boUserUnLockDurg and ((StdItem20.Reserved and 2) <> 0) then begin
                SysMsg(g_sCanotTakeOffItem {'无法取下物品!!!'}, c_Red, t_Hint);
                n18 := -4;
                goto FailExit;
            end;                                                                                  //004DAE78
            if (StdItem20.Reserved and 4) <> 0 then begin
                SysMsg(g_sCanotTakeOffItem {'无法取下物品!!!'}, c_Red, t_Hint);
                n18 := -4;
                goto FailExit;
            end;
            //物品控制-禁止取下物品
            if CheckSPCode(StdItem20.SPCode, SP_DISABLETAKEOFF) then begin
                SysMsg(g_sCanotTakeOffItem {'无法取下物品!!!'}, c_Red, t_Hint);
                n18 := -4;
                goto FailExit;
            end;
            end;

            New(TakeoffItem);
            TakeoffItem^ := m_EntopticItems.Item;
          end;

          m_EntopticItems.Item := UserItem^;

          DelBagItem(n14);
          if TakeoffItem <> nil then begin
            AddItemToBag(TakeoffItem);
            SendAddItem(TakeoffItem);
          end;

          n18 := 1;
          SendDefMessage(SM_TAKEON_OK, GetFeatureToLong(Self), GetGender, 0, 0, '');
          Result := True;

          RecalcAbilitys();
          SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
          SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');

          // m_nCharStatus := GetCharStatus();
          // SendMsg(Self,RM_CHARSTATUSCHANGED, m_nHitSpeed, m_nCharStatus, 0, 0, '');

          FeatureChanged();
      end;
      end else n18 := -1;
    end else n18 := -1;
end;
FailExit:
if n18 <= 0 then
    SendDefMessage(SM_TAKEON_FAIL, n18, 0, 0, 0, '');
end;

function TPlayObject.ClientTakeOffEntopticItems(btWhere: byte; nItemIdx: Integer): Boolean;
var
N10, i                              : Integer;
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
sName                                 : string;
nCheckCode                            : Integer;
label
FailExit;
begin
N10 := 0;
nCheckCode := 0;
if m_boPneuma then begin
    if not m_boDealing and (btWhere in ) then begin
      if m_EntopticItems.Item.wIndex > 0 then begin
      if m_EntopticItems.Item.MakeIndex = nItemIdx then begin
          StdItem := UserEngine.GetStdItem(m_EntopticItems.Item.wIndex);
          if (StdItem <> nil) then begin
            //物品控制-禁止取下物品
            if CheckSPCode(StdItem.SPCode, SP_DISABLETAKEOFF) then begin
            SysMsg(g_sCanotTakeOffItem {'无法取下物品!!!'}, c_Red, t_Hint);
            N10 := -4;
            goto FailExit;
            end;

            New(UserItem);
            UserItem^ := m_EntopticItems.Item;
            if AddItemToBag(UserItem) then begin
            m_EntopticItems.Item.wIndex := 0;

            SendAddItem(UserItem);
            SendDefMessage(SM_TAKEOFF_OK, GetFeatureToLong(Self), GetGender, 0, 0, '');

            RecalcAbilitys();
            SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
            SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');

            // m_nCharStatus := GetCharStatus();
            // SendMsg(Self,RM_CHARSTATUSCHANGED, m_nHitSpeed, m_nCharStatus, 0, 0, '');

            FeatureChanged();
            end else begin
            Dispose(UserItem);
            N10 := -3;
            end;
          end;
      end;
      end else N10 := -2;
    end else N10 := -1;
end else N10 := -4;

FailExit:
if N10 <= 0 then
    SendDefMessage(SM_TAKEOFF_FAIL, N10, 0, 0, 0, '');
end;


//点亮心命点

function TPlayObject.ClientIllumeHeartPoint(btWhere, btPlace: byte): Boolean;
//取魂骨级别
function GetFetchBoneLevel(Shape: byte): byte;
begin
    Result := 0;
    if Shape in then Result := 1
    else if Shape in then Result := 2
    else if Shape in then Result := 3
    else if Shape in then Result := 4;
end;
//取目标位置需要级别
function GetPlaceLevel(): byte;
begin
    Result := $FF;
    if btPlace in then Result := 1
    else if btPlace in then Result := 2
    else if btPlace in then Result := 3
    else if btPlace in then Result := 4;
end;

var
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
i, w                                  : Integer;
btKismet                              : byte;
btError                               : byte;
resourcestring
sItemName                           = '启心石';
sExceptionMsg1                        = '请在元神的包裹中放入启心石,才能激活或者改变心命点的属性。';
sExceptionMsg2                        = '魂骨级别不够,无法点亮';
sExceptionMsg3                        = '激活或者改变心命点的属性失败.';
sGameLogMsg                           = '激活或者改变心命点的属性';
begin
UserItem := nil;
Result := False;
btError := 0;
if not m_boDealing and (btWhere in ) then begin
    if m_boPneuma and (m_PneumaObject <> nil) and (m_EntopticItems.Item.wIndex > 0) then begin
      StdItem := UserEngine.GetStdItem(m_EntopticItems.Item.wIndex);
      if (StdItem <> nil) and (StdItem.StdMode = 91) then begin
      if GetFetchBoneLevel(StdItem.Shape) >= GetPlaceLevel() then begin
          w := UserEngine.GetStdItemIdx(sItemName);
          if w > 0 then begin
            for i := m_ItemList.Count - 1 downto 0 do begin
            UserItem := pTUserItem(m_ItemList);
            if UserItem^.wIndex = w then begin
                btKismet := GetRandomKismet();
                if btKismet > 0 then begin
                  AddGameDataLog('10' + #9 +
                  m_sMapName + #9 +
                  IntToStr(m_nCurrX) + #9 +
                  IntToStr(m_nCurrY) + #9 +
                  m_sCharName + #9 +
                  sItemName + #9 +
                  IntToStr(UserItem.MakeIndex) + #9 +
                  '1' + #9 +
                  sGameLogMsg);

                  SendDelItems(UserItem);
                  Dispose(pTUserItem(m_ItemList));
                  m_ItemList.Delete(i);

                  m_EntopticItems.Kismet := btKismet;
                  SendHeartFatePoint();

                  RecalcAbilitys();
                  SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');

                  Result := True;
                end else
                  btError := 2;
                Break;
            end;
            end;
          end;
      end else
          btError := 1;
      if not Result then begin
          if btError = 2 then
            TPlayObject(m_PneumaObject).SendDefMessage(38288, 1, 255, 0, 0,
            sExceptionMsg3)
          else if btError = 1 then
            TPlayObject(m_PneumaObject).SendDefMessage(38288, 1, 255, 0, 0,
            sExceptionMsg2)
          else
            TPlayObject(m_PneumaObject).SendDefMessage(38288, 1, 255, 0, 0,
            sExceptionMsg1)
      end;
      end;
    end;
end;
end;

procedure TPlayObject.SendHeartFatePoint();
var
i                                     : Integer;
Kismets                               : array of TKismet;
begin
if m_boPneuma then begin
    for i := 0 to MAX_ENTOPTICPLACE - 1 do
      Kismets := m_EntopticItems.GetKismet()^;
    SendMsg(Self, RM_HEARTFATEPOINT, 0, 0, 0, 0, EnCodeBuffer(@Kismets, SizeOf(Kismets)));
end;
end;

//天元心法控制元神

procedure TPlayObject.ClientCtrlMental(wOpCode: word);
var
nDW                                 : DWORD;
PneumaObj                           : TPlayObject;
StdItem                               : pTStdItem;
resourcestring
sErrorMsg1                            = '你的内敛元神还未凝入头部魂骨或是还未点亮相应的心命点,无法进行切换。';
sErrorMsg2                            = '你的外现元神还未凝入头部魂骨或是还未点亮相应的心命点,无法进行切换。';
sErrorMsg3                            = '你的内敛元神还未凝入脊椎魂骨或是还未点亮相应的心命点,你的神智无法附身到你的外现元神上。';
sErrorMsg4                            = '你的内敛元神还未凝入躯干魂骨或是还未点亮相应的心命点,你的神智无法附身到你的外现元神上。';
begin
if m_boGhost or m_boDeath then Exit;
if (m_PneumaObject = nil) or not (m_PneumaObject is TPlayObject) or
    (m_PneumaObject.m_boGhost) or (m_PneumaObject.m_boDeath) then Exit;
PneumaObj := TPlayObject(m_PneumaObject);
case wOpCode of
    1: begin
      if m_boCtrlMental then Exit;
      if PneumaObj.m_boInosculatePneuma then begin
          SysMsg('元神融合时不可进行此操作。', c_Red, t_Hint);
          Exit;
      end;
      if (GetTickCount - PneumaObj.m_dwLogonTick) >= 59000 then begin
          if (PneumaObj.m_EntopticItems.Item.wIndex > 0) then begin
            StdItem := UserEngine.GetStdItem(PneumaObj.m_EntopticItems.Item.wIndex);
            if (StdItem <> nil) and (StdItem.StdMode = 91) and
            (PneumaObj.m_EntopticItems.IsPlaceIllume(StdItem.Shape)) then begin
            if ((PneumaObj.m_btPneumaSex and $07) shr 2) <> 1 then begin
                SysMsg(sErrorMsg1, c_Red, t_Hint);
                Exit;
            end;
            PneumaObj.ClientSwitchPneuma();
            end else
            SysMsg(sErrorMsg2, c_Red, t_Hint);
          end else
            SysMsg(sErrorMsg2, c_Red, t_Hint);
      end;
      end;
    2: begin
      //检查是否装备了脊椎骨
      if m_boCtrlMental then begin
          //元神=》 主体
          nDW := DWORD(Self);
          PneumaObj.SendRefMsg(RM_510, LoWord(nDW), HiWord(nDW), 127, 0, '');
          PneumaObj.SendDelayMsg(Self, RM_CTRLMENTAL, 0, Integer(PneumaObj), 258, 0, '', 1500);
          m_boCtrlMental := not m_boCtrlMental;
          ExecuteScript(g_FunctionNPC, '@元主切换触发');
      end else begin
          //主体 =》元神
          if ((PneumaObj.m_btPneumaSex and $0F) shr 3) <> 1 then begin
            SysMsg(sErrorMsg3, c_Red, t_Hint);
            Exit;
          end;

          if (PneumaObj.m_EntopticItems.Item.wIndex > 0) then begin
            StdItem := UserEngine.GetStdItem(PneumaObj.m_EntopticItems.Item.wIndex);
            if (StdItem <> nil) and (StdItem.StdMode = 91) and
            (PneumaObj.m_EntopticItems.IsPlaceIllume(StdItem.Shape)) then begin
            nDW := DWORD(PneumaObj);
            SendRefMsg(RM_510, LoWord(nDW), HiWord(nDW), 127, 0, '');
            SendDelayMsg(Self, RM_CTRLMENTAL, 0, Integer(Self), 258, 1, '', 1500);
            m_boCtrlMental := not m_boCtrlMental;
            ExecuteScript(g_FunctionNPC, '@主元切换触发');
            end;
          end;
      end;
      end;
    3: begin
      if ((PneumaObj.m_btPneumaSex and $1F) shr 4) <> 1 then begin
          SysMsg(sErrorMsg4, c_Red, t_Hint);
          Exit;
      end;
      PneumaObj.ClientInosculatePneuma();
      ExecuteScript(g_FunctionNPC, '@融合元神触发');
      end;

end;
end;

//取人物外观扩展属性(翅膀、马等)

function TPlayObject.GetFeatureEx(): byte;
var
Hum                                 : TPlayObject;
btType, btReLive                      : byte;
boRideDragon, boRideOrthrus         : Boolean;
begin
if m_boFlyer then begin
    Result := $70 + 15;
    Exit;
end;

{$IF USESDK = DEBUG}
if m_nTestNumber <> 0 then begin
    Result := m_nTestNumber;
    Exit;
end;
{$IFEND}

Result := 0;
btType := 0;
btReLive := 0;
if m_boRideOn then begin
    if m_boPneuma and (m_PneumaObject <> nil) then begin
      Hum := TPlayObject(m_PneumaObject);
      btType := Hum.m_PetInfo.btType;
      btReLive := Hum.m_PetInfo.btReLive;
    end else begin
      Hum := TPlayObject(Self);
      btType := Hum.m_PetInfo.btType;
      btReLive := Hum.m_PetInfo.btReLive;
    end;
    boRideDragon := Hum.m_boRideDragonMode;
    boRideOrthrus := Hum.m_boRideOrthrusMode;
    if btType < 11 then begin
      case m_btHorseType of
      1..5: Result := $E0 + m_btHorseType;                                                      //马
      6..10: Result := $A2 + m_btHorseType;                                                       //幽影铁骑、赤炎追风、踏雪银驹
      end;
    end else begin
      case btType of
      11..13: begin                                                                               //豹子
            case btReLive of
            1: Result := $DB + btType;                                                            //225- 227
            2: Result := $DE + btType;                                                            //228 -230
            3: begin
                  if m_boPneuma and m_boInosculatePneuma then
                  Result := $9C
                  else
                  Result := $81 + btType;                                                         //A4 5E 21 D7
                end;
            end;
          end;
      14..16: begin
            case btReLive of                                                                        //狮子
            1: Result := $EB + btType;
            2: begin
                  if btType = 11 then
                  Result := $F8
                  else
                  Result := $EE + btType;                                                         //$F8 红狮
                end;                                                                              //$D3 红狮
            3: begin
                  if m_boPneuma and m_boInosculatePneuma then
                  Result := $9D
                  else
                  Result := $81 + btType;
                end;
            end;
          end;
      17..19: begin
            case btReLive of                                                                        //麒麟
            1: Result := $DD + btType;
            2: Result := $E0 + btType;
            3: begin
                  if m_boPneuma and m_boInosculatePneuma then
                  Result := $9F
                  else
                  Result := $81 + btType;
                end;
            end;
          end;
      20..22: begin
            case btReLive of                                                                        //凤凰
            1: Result := $68 + btType;
            2: Result := $6B + btType;
            3: begin
                  if m_boPneuma and m_boInosculatePneuma then
                  Result := $A0
                  else
                  Result := $81 + btType;
                end;
            end;
          end;
      23..25: begin
            case btReLive of                                                                        //老虎
            1: ;
            2: Result := $82;
            3: begin
                  if m_boPneuma and m_boInosculatePneuma then
                  Result := $A3
                  else
                  Result := $81 + btType;
                end;
            end;
          end;
      26..27: begin
            case btReLive of                                                                        //鲨鱼
            1: ;
            2: Result := $75 + btType;
            3: begin
                  if m_boPneuma and m_boInosculatePneuma then
                  Result := $A1
                  else
                  Result := $7D + btType;
                end;
            end;
          end;
      28: ;
      29..31: begin
            case btReLive of                                                                        //帝王裂天犀
            1: ;
            2: Result := $85;
            3: begin
                  if m_boPneuma and m_boInosculatePneuma then
                  Result := $A2
                  else
                  Result := $A2;
                end;
            end;
          end;
      32..34: begin                                                                               //独角兽
            case btReLive of
            1: ;
            2: ;
            3: begin
                  if m_boPneuma and m_boInosculatePneuma then
                  Result := $AC + btType
                  else
                  Result := $A9 + btType;
                end;
            end;
          end;
      35..37: begin                                                                               //战马
            case btReLive of
            1: ;
            2: ;
            3: begin
                  if m_boPneuma and m_boInosculatePneuma then
                  Result := $A2 + btType
                  else
                  Result := $9F + btType;
                end;
            end;
          end;
      38: begin                                                                                 //狼
            case btReLive of
            1: ;
            2: ;
            3: ;
            4: begin
                  if m_boPneuma and m_boInosculatePneuma then
                  Result := $8A + btType
                  else
                  Result := $87 + btType;
                end;
            end;
          end;
      39: begin
            case btReLive of
            2: Result := $AD;                                                                     //二转邪影银月狼
            end;
          end;
      40: ;
      41..43: begin
            case btReLive of                                                                        //$B4 霜血战熊 $B3 双头兽 $B0 蓝色狼闪电 $AF 金色 独角 $AE 独角红色$AD 独角蓝色 $AA 黑色战马霜雪战熊
            1: ;
            2: ;
            3: begin
                  if m_boPneuma and m_boInosculatePneuma then
                  Result := $B4
                  else
                  Result := $B4;
                end;
            4: Result := $B4;
            end;
          end;
      44: begin                                                                                 //蓝焰战马
            case btReLive of
            2: Result := $C3;
            end;
          end;
      45: begin                                                                                 //绿焰战马
            case btReLive of
            2: Result := $C4;
            end;
          end;
      46: begin
            case btReLive of                                                                        //赤焰战马
            2: Result := $C2;
            end;
          end;
      47: begin                                                                                 //狂怒战熊
            case btReLive of
            4: Result := $B8;
            end;
          end;
      end;
      //沙城金龙
      if boRideDragon then begin
      if m_boPneuma and m_boInosculatePneuma then
          Result := $A6
      else
          Result := $A5;
      end;
      if boRideOrthrus then begin
      if m_boPneuma and m_boInNonSuchPavilion then
          Result := $B4
      else
          Result := $B3
      end;
    end;
end;
end;

function TPlayObject.GetFeature(BaseObject: TBaseObject): Integer;
var
StdItem                               : pTStdItem;
btWeapon                              : byte;
btRace, btHair, btDress, btDressShape : byte;
begin
if m_boPneuma and m_boInosculatePneuma then begin
    btDress := 0;
    btDressShape := m_nDressShape;

    if m_TorDDM.Tiger.Items.wIndex > 0 then begin                                          //衣服
      StdItem := UserEngine.GetStdItem(m_TorDDM.Tiger.Items.wIndex);
      if StdItem <> nil then begin
      //衣服有16种颜色,所以序号*16,再加上颜色
      btDress := (StdItem.Shape shl 4) + (m_TorDDM.Tiger.Items.btValue and $0F);

      if ((btDressShape and $000000C8) <> $000000C8) then btDressShape := StdItem.Shape;
      end;
    end else if ((btDressShape and $000000C8) <> $000000C8) then btDressShape := 28 + m_btJob;

    btWeapon := 0;                                                                                  //武器
    if m_TorDDM.Tiger.Items.wIndex > 0 then begin
      StdItem := UserEngine.GetStdItem(m_TorDDM.Tiger.Items.wIndex);
      if StdItem <> nil then begin
      btWeapon := StdItem.Shape;
      end;
    end;

    m_nDressShape := MakeLong(MakeWord(btDressShape, 0), HiWord(m_nDressShape));
    btHair := m_btHair;                                                                           //头发
    btRace := GetFeatureEx;                                                                         //种族
    Result := MakeHumanFeature(btRace, btDress, btWeapon, btHair);
end else
    Result := inherited GetFeature(BaseObject);
end;

function TPlayObject.GetAmbitStatus(): Integer;
var
nNum                                  : Integer;
begin
Result := inherited GetAmbitStatus();
//传世主宰者 星星数量
if (m_btRulerLevel > 0) then begin
    nNum := m_btRulerLevel * 8;
    Result := Result or nNum;
end;
end;

function TPlayObject.GetMagicExStatus(): byte;
begin
Result := inherited GetMagicExStatus();
//传世主宰者
if (m_btRulerLevel > 0) then Result := $80 or Result;
if m_boPneuma then begin
    if m_boInosculatePneuma then begin
      Result := ($80 shr 4) or Result;                                                            //是融合元神
      Result := Result + (m_btPneumaSex and $03);                                                   //内敛元神职业//元神里是用来保存内敛元神职业的
    end;
end;
end;

procedure TPlayObject.ClientInosculatePneuma();
var
MainPlayObj                           : TPlayObject;
StdItem                               : pTStdItem;
i, ii, n                              : Integer;
Slave                                 : TBaseObject;
RidePet                               : TRidePet;
resourcestring
sErrorMsg                           = '你的外现元神还未凝入躯干魂骨或是还未点亮相应的心命点,你的神智无法附身到你的外现元神上。';
begin
if m_PneumaObject = nil then Exit;
if m_pSwitchPneuma <> nil then Exit;
if (not m_boPneuma) or m_boCtrlMental then Exit;
MainPlayObj := TPlayObject(m_PneumaObject);

//if m_boRideOn then begin
//    MainPlayObj.SysMsg('元神骑乘模式下,不可进行此操作。', c_Red, t_Hint);
//    Exit;
//end;

if MainPlayObj.m_btCurPneumaCount < 2 then Exit;

if MainPlayObj.m_boGhost or
    MainPlayObj.m_boDeath or
    MainPlayObj.m_boSoftClose or
    MainPlayObj.m_boReconnection then Exit;

if m_boGhost or m_boDeath then Exit;

if not m_boInosculatePneuma then begin
    if (GetTickCount - m_dwInosculateTick) >= 60000 then begin
      if (m_EntopticItems.Item.wIndex > 0) then begin
      StdItem := UserEngine.GetStdItem(m_EntopticItems.Item.wIndex);
      if (StdItem <> nil) and (StdItem.StdMode = 91) and
          (m_EntopticItems.IsPlaceIllume(StdItem.Shape)) then begin
          m_dwInosculateTick := GetTickCount;
          m_boInosculatePneuma := True;
          MainPlayObj.SendMsg(MainPlayObj, RM_CTRLMENTAL, 0, 0, 3, 0, '');
          //计算战斗值
          i := -1;
          if (m_btAmbitKind > 2) then Inc(i);
          if (m_btAmbitKind > 4) then Inc(i);
          if (m_btAmbitKind > 6) then Inc(i);
          if (m_btAmbitKind > 8) then Inc(i);
          if (m_btAmbitKind < 3) then i := 0;
          i := i * 99;
          //m_wInnerPneumaLevel为内敛元神综合等级
          m_wCurFightValue := Round(((m_wInnerPneumaLevel + m_Abil.level + m_btAmbitLevel + i) / 5) + (MainPlayObj.m_btMentalLevel / 2));

          m_InosculatePneumaHP := m_WAbil.dwHP;                                                   //备份元神当前血
          m_InosculatePneumaMP := m_WAbil.dwMP;                                                   //备份融合元神当前蓝
          m_WAbil.dwHP := MainPlayObj.m_InosculatePneumaHP;                                       //当前融合的血值是保存主体身上的
          m_WAbil.dwMP := MainPlayObj.m_InosculatePneumaMP;                                       //当前融合的魔法值是保存主体身上的
          if m_WAbil.dwHP <= Round(m_WAbil.dwMaxHP * 10 / 100) then
            m_WAbil.dwHP := m_WAbil.dwMaxHP;

          FillChar(m_InosculatePneumaAddAbil, SizeOf(TAddAbility), #0);
          //
          //计算属性                                                                              // 14 + 85 +20 42 * 338
          if (m_btJob = 0) and ((m_btPneumaSex and $03) = 1) then begin                           //战战 14 + (122 / 2 + 20 + 122 / 4) * (122 * 2)
            m_InosculatePneumaMaxHP := _MIN(MAXHUMHP, 14 + Round(((m_wCurFightValue / 2 + 20 + m_wCurFightValue / 4) * (m_wCurFightValue * 2))));
            m_InosculatePneumaMaxMP := _MIN(MAXHUMMP, 13 + Round(m_wCurFightValue * 12));
            n := _Max((m_wCurFightValue * 6 div 8) - 1, 1);
            m_InosculatePneumaAddAbil.wDC := MakeLong(n - 1, n);
            m_InosculatePneumaAddAbil.wSC := 0;
            m_InosculatePneumaAddAbil.wMC := 0;
            m_InosculatePneumaAddAbil.wAC := MakeLong(0, (m_wCurFightValue * 6 div 12));
            m_InosculatePneumaAddAbil.wMAC := MakeLong(0, (m_wCurFightValue div 20));
          end else if (m_btJob = 1) and ((m_btPneumaSex and $03) = 2) then begin                  //法法14 + (122 / 3 + 20) * 122
            m_InosculatePneumaMaxHP := _MIN(MAXHUMHP, 14 + Round(((m_wCurFightValue / 3 + 10) * m_wCurFightValue))); //14 + (122 / 2 + 20) * 4.4 * 122
            m_InosculatePneumaMaxMP := _MIN(MAXHUMMP, 13 + Round((m_wCurFightValue / 2 + 20) * 4.4 * m_wCurFightValue));

            n := _Max((m_wCurFightValue * 6 div 9) - 1, 1);
            m_InosculatePneumaAddAbil.wDC := MakeLong(n - 1, n);
            m_InosculatePneumaAddAbil.wMC := MakeLong(n - 1, n);
            m_InosculatePneumaAddAbil.wSC := 0;
            m_InosculatePneumaAddAbil.wAC := MakeLong(0, (m_wCurFightValue div 22));
            m_InosculatePneumaAddAbil.wMAC := MakeLong(0, (m_wCurFightValue div 18));
          end else if (m_btJob = 2) and ((m_btPneumaSex and $03) = 3) then begin                  //道道
            m_InosculatePneumaMaxHP := _MIN(MAXHUMHP, 14 + Round(((m_wCurFightValue / 2 + 30) * m_wCurFightValue)));
            m_InosculatePneumaMaxMP := _MIN(MAXHUMMP, 13 + Round(((m_wCurFightValue / 3) * 3.3 * m_wCurFightValue)));
            n := _Max((m_wCurFightValue * 6 div 9) - 1, 1);
            m_InosculatePneumaAddAbil.wDC := MakeLong(n - 1, n);
            m_InosculatePneumaAddAbil.wMC := 0;
            m_InosculatePneumaAddAbil.wSC := MakeLong(n - 1, n);
            m_InosculatePneumaAddAbil.wAC := MakeLong(0, (m_wCurFightValue div 18));
            n := _Max((m_wCurFightValue * 6 div 12), 1);
            m_InosculatePneumaAddAbil.wMAC := MakeLong(n div 2, n + 1);
          end else if (m_btJob in ) and ((m_btPneumaSex and $03) in ) then begin      //战法
            m_InosculatePneumaMaxHP := _MIN(MAXHUMHP, 14 + Round(((m_wCurFightValue / 2 + 10 + m_wCurFightValue / 4) * (m_wCurFightValue * 1.5))));
            m_InosculatePneumaMaxMP := _MIN(MAXHUMMP, 13 + Round((m_wCurFightValue / 2 + 10) * 2.2 * m_wCurFightValue));
            n := _Max((m_wCurFightValue * 6 div 10) - 1, 1);
            m_InosculatePneumaAddAbil.wDC := MakeLong(n - 1, n);
            m_InosculatePneumaAddAbil.wSC := 0;
            m_InosculatePneumaAddAbil.wMC := MakeLong(n - 1, n);
            m_InosculatePneumaAddAbil.wAC := MakeLong(0, (m_wCurFightValue * 6 div 14));
            m_InosculatePneumaAddAbil.wMAC := MakeLong(0, (m_wCurFightValue div 18));
          end else if (m_btJob in ) and ((m_btPneumaSex and $03) in ) then begin      //战道
            m_InosculatePneumaMaxHP := _MIN(MAXHUMHP, 14 + Round(((m_wCurFightValue / 3 + 15 + m_wCurFightValue / 4) * (m_wCurFightValue * 1.5))));
            m_InosculatePneumaMaxMP := _MIN(MAXHUMMP, 13 + Round(((m_wCurFightValue / 4) * 2.2 * m_wCurFightValue)));
            n := _Max((m_wCurFightValue * 6 div 10) - 1, 1);
            m_InosculatePneumaAddAbil.wDC := MakeLong(n - 1, n);
            m_InosculatePneumaAddAbil.wMC := 0;
            m_InosculatePneumaAddAbil.wSC := MakeLong(n - 1, n);
            m_InosculatePneumaAddAbil.wAC := MakeLong(0, (m_wCurFightValue div 22));
            n := _Max((m_wCurFightValue * 6 div 18), 1);
            m_InosculatePneumaAddAbil.wMAC := MakeLong(n div 2, n + 1);
          end else if (m_btJob in ) and ((m_btPneumaSex and $03) in ) then begin      //法道
            m_InosculatePneumaMaxHP := _MIN(MAXHUMHP, 14 + Round(((m_wCurFightValue / 3 + 15) * m_wCurFightValue)));
            m_InosculatePneumaMaxMP := _MIN(MAXHUMMP, 13 + Round(((m_wCurFightValue / 3) * 2.2 * m_wCurFightValue)));
            n := _Max((m_wCurFightValue * 6 div 10) - 1, 1);
            m_InosculatePneumaAddAbil.wDC := MakeLong(n - 1, n);
            m_InosculatePneumaAddAbil.wMC := MakeLong(n - 1, n);
            m_InosculatePneumaAddAbil.wSC := MakeLong(n - 1, n);
            m_InosculatePneumaAddAbil.wAC := MakeLong(0, (m_wCurFightValue div 22));
            n := _Max((m_wCurFightValue * 6 div 14), 1);
            m_InosculatePneumaAddAbil.wMAC := MakeLong(n div 2, n + 1);
          end;

          //如果是0血,则加满血
          if m_WAbil.dwHP = 0 then
            m_WAbil.dwHP := m_InosculatePneumaMaxHP;

          //Min(m_InosculatePneumaMaxHP, m_WAbil.dwHP);
          //Min(m_InosculatePneumaMaxMP, m_WAbil.dwMP);

          //发送本人物所学习了的技能列表
          SendUseMagic();
          //发送融合元神身上物品
          SendTigerItem();

          FeatureChanged();
          MainPlayObj.SendMsg(MainPlayObj, RM_CTRLMENTAL, 0, Integer(MainPlayObj), 259, 1, '');
      end;
      end;

      if not m_boInosculatePneuma then begin
      MainPlayObj.SysMsg(sErrorMsg, c_Red, t_Hint);
      Exit;
      end;
    end;
end else begin
    m_boInosculatePneuma := False;

    if m_SpiritInfo.boMag then begin
      SendRefMsg(RM_SPIRITHP, 0, 0, 0, 0, '');
      m_SpiritInfo.boMag := False;                                                                  //取消技能的使用
    end;

    MainPlayObj.SendMsg(MainPlayObj, RM_CTRLMENTAL, 0, Integer(MainPlayObj), 259, 0, '');
    //装备更换

    MainPlayObj.m_InosculatePneumaHP := m_WAbil.dwHP;                                             //把当前融合的血值保存主体身上
    MainPlayObj.m_InosculatePneumaMP := m_WAbil.dwMP;                                             //把当前融合的魔法值保存主体身上

    m_WAbil.dwHP := m_InosculatePneumaHP;                                                         //还原元神当前血
    m_WAbil.dwMP := m_InosculatePneumaMP;                                                         //还原元神当前魔法值

    //发送本人物所学习了的技能列表
    SendUseMagic();
    //发送身上物品
    //SendUseitems();
    FeatureChanged();
end;

//{取消魔法盾,护身真气,金刚护体等下线保存}
m_wStatusTimeArr := 1;
m_wStatusTimeArr := 1;
m_wStatusTimeArr := 1;
m_wStatusTimeArr := 1;
m_wStatusTimeArr := 1;
m_wStatusTimeArr := 1;
m_boAbilMag70Defence := False;
m_boAbilMagHuShenDefence := False;
m_boAbilMagJingangDefence := False;
m_boAbilMagBubbleDefence := False;
//清除宝宝
for i := 0 to m_SlaveList.Count - 1 do begin
    Slave := TBaseObject(m_SlaveList.Items);
    //通知元神宝宝ID
    ii := Integer(Slave);
    SendDefMessage(SM_SLAVEINFO, Integer(Self), 0, 0, 1, EnCodeBuffer(@ii, SizeOf(Integer)));
    //m_defMsg := MakeDefaultMsg(SM_SLAVEINFO, Integer(Self), 0, 0, 1);
    //SendSocket(@m_defMsg, EnCodeBuffer(@ii, SizeOf(Integer)));
    Slave.MakeGhost();
end;
m_SlaveList.Clear;



//刷新自身信息 到客户端
RecalcHitSpeed;
RecalcAbilitys();
SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
SendUpdateMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');


    SendRefMsg(RM_TURN, m_btDirection, m_nCurrX, m_nCurrY, CalcCent(m_WAbil.dwHP, m_WAbil.dwMaxHP), GetShowName);

end;

procedure TPlayObject.ClientSwitchPneuma();
var
MainPlayObj                           : TPlayObject;
begin
if m_PneumaObject = nil then Exit;
if m_pSwitchPneuma <> nil then Exit;
if not m_boPneuma then Exit;
MainPlayObj := TPlayObject(m_PneumaObject);

if MainPlayObj.m_btCurPneumaCount < 2 then Exit;

if MainPlayObj.m_boGhost or
    MainPlayObj.m_boDeath or
    MainPlayObj.m_boSoftClose or
    MainPlayObj.m_boReconnection then Exit;

if m_boGhost or m_boDeath then Exit;

New(m_pSwitchPneuma);
try
    MainPlayObj.m_PneumaObject := nil;
    MainPlayObj.m_nPneumaLastX := m_nCurrX;
    MainPlayObj.m_nPneumaLastY := m_nCurrY;
    TPlayObject(m_PneumaObject).m_PetInfo.nMakeIndex := 0;
    TPlayObject(m_PneumaObject).m_PetInfo.wLevel := 0;
    TPlayObject(m_PneumaObject).m_PetInfo.btType := 0;
    TPlayObject(m_PneumaObject).m_PetInfo.btReLive := 0;
    TPlayObject(m_PneumaObject).m_PetInfo.btRideFightSpeed := 0;
    m_PneumaObject := nil;
    m_boSoftClose := True;
    m_boReconnection := True;
    SendRefMsg(RM_510, 1, 0, 42, 0, '');
    SendDefMessage(SM_OUTOFCONNECTION, 0, 0, 0, 0, '');
    MainPlayObj.m_dwCallPneumaTick := GetTickCount;

    m_pSwitchPneuma^.dwPlayObject := Integer(MainPlayObj);
    m_pSwitchPneuma^.sChrName := m_sCharName;
    m_pSwitchPneuma^.dwDBIndex := m_dwDBIndex;

    //在主体上保存一下当前的最大攻击吧
    case m_btJob of
      0: MainPlayObj.m_SpiritInfo.wWithinTotalDC := hiword(m_WAbil.DC);
      1: MainPlayObj.m_SpiritInfo.wWithinTotalDC := hiword(m_WAbil.MC);
      2: MainPlayObj.m_SpiritInfo.wWithinTotalDC := hiword(m_WAbil.SC);
    end;

except
    Dispose(m_pSwitchPneuma);
    m_pSwitchPneuma := nil;
end;
end;

procedure TPlayObject.ClientTakeOnInosculatePneumaItem(nWhere, nMakeIndex: Integer);
var
i, n14, n18                           : Integer;
UserItem, TakeoffItem               : pTUserItem;
StdItem, StdItem20                  : pTStdItem;
StdItem58                           : TStdItem;
boCanTakeOn                           : Boolean;
label
FailExit;
begin
StdItem := nil;
UserItem := nil;
n14 := -1;

if m_boPneuma and m_boInosculatePneuma then begin
    //灵珠状态下不能使用武器
    if (nWhere = U_WEAPON) and m_boPneumaEffMode then Exit;

    for i := 0 to m_ItemList.Count - 1 do begin
      UserItem := m_ItemList.Items;                                                            //包裹里的物品
      if (UserItem <> nil) and (UserItem.MakeIndex = nMakeIndex) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      n14 := i;
      Break;
      end;
      StdItem := nil;
      UserItem := nil;
    end;
end;

n18 := 0;
if (StdItem <> nil) and (UserItem <> nil) then begin
    if CheckIPUserItems(nWhere, StdItem) and (StdItem.Need = 09) then begin
      //物品控制-禁止元神、红名、本体穿戴
      if m_boPneuma then
      boCanTakeOn := not (CheckSPCode(StdItem.SPCode, SP_DISABLEPNEUMATAKEON))
      else if (PKLevel > 2) then
      boCanTakeOn := not (CheckSPCode(StdItem.SPCode, SP_DISABLEREDTAKEON))
      else
      boCanTakeOn := not (CheckSPCode(StdItem.SPCode, SP_DISABLEHUMANTAKEON));

      if not boCanTakeOn then begin
      SysMsg('你不能佩戴此物品。', c_Red, t_Hint);
      n18 := -1;
      goto FailExit;
      end;

      StdItem58 := StdItem^;
      ItemUnit.GetItemAddValue(UserItem, StdItem58);
      if (n18 = 0) and CheckTakeOnItems(U_ENTOPTIC, StdItem58) and CheckItemBindUse(UserItem) then begin
      TakeoffItem := nil;
      if nWhere in then begin
          //取下物品
          if m_TorDDM.Tiger.Items.wIndex > 0 then begin                                     //当前位置已装备了物品,则取下
            StdItem20 := UserEngine.GetStdItem(m_TorDDM.Tiger.Items.wIndex);
            if (StdItem20 <> nil) then begin
            if not m_boUserUnLockDurg and ((StdItem20.Reserved and 2) <> 0) then begin
                SysMsg(g_sCanotTakeOffItem {'无法取下物品!!!'}, c_Red, t_Hint);
                n18 := -4;
                goto FailExit;
            end;                                                                                  //004DAE78
            if (StdItem20.Reserved and 4) <> 0 then begin
                SysMsg(g_sCanotTakeOffItem {'无法取下物品!!!'}, c_Red, t_Hint);
                n18 := -4;
                goto FailExit;
            end;
            //物品控制-禁止取下物品
            if CheckSPCode(StdItem20.SPCode, SP_DISABLETAKEOFF) then begin
                SysMsg(g_sCanotTakeOffItem {'无法取下物品!!!'}, c_Red, t_Hint);
                n18 := -4;
                goto FailExit;
            end;
            end;

            New(TakeoffItem);
            TakeoffItem^ := m_TorDDM.Tiger.Items;
          end;

          m_TorDDM.Tiger.Items := UserItem^;

          DelBagItem(n14);
          if TakeoffItem <> nil then begin
            AddItemToBag(TakeoffItem);
            SendAddItem(TakeoffItem);
          end;

          n18 := 1;
          SendDefMessage(SM_TAKEON_OK, GetFeatureToLong(Self), GetGender, 0, 0, '');

          RecalcAbilitys();
          SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
          SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');

          FeatureChanged();

          if (m_btJob = 0) and (nWhere in ) then
            SendRefMsg(RM_TURN, m_btDirection, m_nCurrX, m_nCurrY,
            CalcCent(m_WAbil.dwHP, m_WAbil.dwMaxHP), '');
      end;
      end else n18 := -1;
    end else n18 := -1;
end;
FailExit:
if n18 <= 0 then
    SendDefMessage(SM_TAKEON_FAIL, n18, 0, 0, 0, '');
end;

procedure TPlayObject.ClientTakeOffInosculatePneumaItem(nWhere, nMakeIndex: Integer);
var
N10, i                              : Integer;
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
sName                                 : string;
nCheckCode                            : Integer;
label
FailExit;
begin
N10 := 0;
nCheckCode := 0;
if m_boPneuma and m_boInosculatePneuma then begin
    if not m_boDealing and (nWhere in ) then begin
      if m_TorDDM.Tiger.Items.wIndex > 0 then begin
      if m_TorDDM.Tiger.Items.MakeIndex = nMakeIndex then begin
          StdItem := UserEngine.GetStdItem(m_TorDDM.Tiger.Items.wIndex);
          if (StdItem <> nil) then begin
            //物品控制-禁止取下物品
            if CheckSPCode(StdItem.SPCode, SP_DISABLETAKEOFF) then begin
            SysMsg(g_sCanotTakeOffItem {'无法取下物品!!!'}, c_Red, t_Hint);
            N10 := -4;
            goto FailExit;
            end;

            New(UserItem);
            UserItem^ := m_TorDDM.Tiger.Items;
            if AddItemToBag(UserItem) then begin
            m_TorDDM.Tiger.Items.wIndex := 0;

            SendAddItem(UserItem);
            SendDefMessage(SM_TAKEOFF_OK, GetFeatureToLong(Self), GetGender, 0, 0, '');

            RecalcAbilitys();
            SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
            SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');

            FeatureChanged();
            if (m_btJob = 0) and (nWhere = 0) then
                SendRefMsg(RM_TURN, m_btDirection, m_nCurrX, m_nCurrY,
                  CalcCent(m_WAbil.dwHP, m_WAbil.dwMaxHP), '');
            end else begin
            Dispose(UserItem);
            N10 := -3;
            end;
          end;
      end;
      end else N10 := -2;
    end else N10 := -1;
end else N10 := -4;

FailExit:
if N10 <= 0 then
    SendDefMessage(SM_TAKEOFF_FAIL, N10, 0, 0, 0, '');
end;

procedure TPlayObject.RecalcAddInosculatePneumaAbil();
var
i                                     : Integer;
StdItem                               : pTStdItem;
begin
if not m_boPneuma or not m_boInosculatePneuma then Exit;

for i := Low(TTigerItems) to High(TTigerItems) do begin
    if (m_TorDDM.Tiger.Items.wIndex <= 0) or (m_TorDDM.Tiger.Items.Dura <= 0) then
      Continue;                                                                                     //物品不存在或物品已损坏
    StdItem := UserEngine.GetStdItem(m_TorDDM.Tiger.Items.wIndex);
    if StdItem = nil then Continue;

    //获得物品的附加属性
    GetAccessory(m_TorDDM.Tiger.Items, m_AddAbil);

    //武器
    if (i = U_WEAPON) then begin
      if (StdItem.Source - 1 - 10) < 0 then
      m_AddAbil.btWeaponStrong := StdItem.Source;                                                 //强度+
      if (StdItem.Source <= -1) and (StdItem.Source >= -50) then                                    // -1 至 -50
      m_AddAbil.btSacred := m_AddAbil.btSacred + -StdItem.Source;                                 //神圣+
      if (StdItem.Source <= -51) and (StdItem.Source >= -100) then                                  // -51 至 - 100
      m_AddAbil.btSacred := m_AddAbil.btSacred + (StdItem.Source + 50);                           //神圣-
    end;
end;

//神魂融合增加血上线与攻击
if m_SpiritInfo.boMag then begin
    Inc(m_AddAbil.dwHP, m_SpiritInfo.wAddHP);
    case m_btJob of
      0: m_AddAbil.wDC := MakeLong(LoWord(m_AddAbil.wDC), HiWord(m_AddAbil.wDC) + m_SpiritInfo.wAddDC);
      1: m_AddAbil.wMC := MakeLong(LoWord(m_AddAbil.wMC), HiWord(m_AddAbil.wMC) + m_SpiritInfo.wAddDC);
      2: m_AddAbil.wSC := MakeLong(LoWord(m_AddAbil.wSC), HiWord(m_AddAbil.wSC) + m_SpiritInfo.wAddDC);
      3: m_AddAbil.dwGC := MakeLong(LoWord(m_AddAbil.dwGC), HiWord(m_AddAbil.dwGC) + m_SpiritInfo.wAddDC);
    end;
end;

Inc(m_AddAbil.wSpeedPoint, m_InosculatePneumaAddAbil.wSpeedPoint);                              //躲避
Inc(m_AddAbil.wHitPoint, m_InosculatePneumaAddAbil.wHitPoint);                                    //人物攻击命中(Byte)
Inc(m_AddAbil.wAntiPoison, m_InosculatePneumaAddAbil.wAntiPoison);                              //中毒躲避
Inc(m_AddAbil.wPoisonRecover, m_InosculatePneumaAddAbil.wPoisonRecover);                        //中毒恢复
Inc(m_AddAbil.wHealthRecover, m_InosculatePneumaAddAbil.wHealthRecover);                        //生命恢复
Inc(m_AddAbil.wSpellRecover, m_InosculatePneumaAddAbil.wSpellRecover);                            //魔法恢复
Inc(m_AddAbil.wAntiMagic, m_InosculatePneumaAddAbil.wAntiMagic);                                  //魔法躲避
Inc(m_AddAbil.btMagicNicety, m_InosculatePneumaAddAbil.btMagicNicety);                            //魔法命中
Inc(m_AddAbil.btPoisonNicety, m_InosculatePneumaAddAbil.btPoisonNicety);                        //中毒命中
Inc(m_AddAbil.btLuck, m_InosculatePneumaAddAbil.btLuck);                                          //人物的幸运值
Inc(m_AddAbil.btUnLuck, m_InosculatePneumaAddAbil.btUnLuck);                                    //人物的诅咒值
Inc(m_AddAbil.nHitSpeed, m_InosculatePneumaAddAbil.nHitSpeed);                                    //攻击速度

m_AddAbil.wAC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wAC) + loword(m_InosculatePneumaAddAbil.wAC)),
    _MIN(High(MaxInt), hiword(m_AddAbil.wAC) + hiword(m_InosculatePneumaAddAbil.wAC)));

m_AddAbil.wMAC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wMAC) + loword(m_InosculatePneumaAddAbil.wMAC)),
    _MIN(High(MaxInt), hiword(m_AddAbil.wMAC) + hiword(m_InosculatePneumaAddAbil.wMAC)));

m_AddAbil.wDC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wDC) + loword(m_InosculatePneumaAddAbil.wDC)),
    _MIN(High(MaxInt), hiword(m_AddAbil.wDC) + hiword(m_InosculatePneumaAddAbil.wDC)));

m_AddAbil.wMC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wMC) + loword(m_InosculatePneumaAddAbil.wMC)),
    _MIN(High(MaxInt), hiword(m_AddAbil.wMC) + hiword(m_InosculatePneumaAddAbil.wMC)));

m_AddAbil.wSC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wSC) + loword(m_InosculatePneumaAddAbil.wSC)),
    _MIN(High(MaxInt), hiword(m_AddAbil.wSC) + hiword(m_InosculatePneumaAddAbil.wSC)));

m_AddAbil.dwGC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.dwGC) + loword(m_InosculatePneumaAddAbil.dwGC)),
    _MIN(High(MaxInt), hiword(m_AddAbil.dwGC) + hiword(m_InosculatePneumaAddAbil.dwGC)));
end;

procedure TPlayObject.ClientQueryGuildClanList;
var
sData, sClanName, sAmbit            : string;
Clan                                  : TClan;
i, ii                                 : Integer;
ClanAmbit                           : pTClanAmbit;
begin
if m_MyGuild = nil then Exit;
sData := '';
for i := 0 to TGuild(m_MyGuild).m_ClanList.Count - 1 do begin
    if i >= 50 then Break;
    sClanName := TGuild(m_MyGuild).m_ClanList.Strings;
    Clan := g_GuildManager.FindClan(sClanName);
    if Clan <> nil then begin
      sData := sData + '#' + Clan.m_sClanName + '/' + Clan.ChiefName + '/' + IntToStr(Clan.btClanKind) + '/';
      for ii := 0 to Clan.m_MemberList.Count - 1 do begin
      if ii >= 200 then Break;
      ClanAmbit := pTClanAmbit(Clan.m_MemberList.GetValues(Clan.m_MemberList.Keys));
      if (ClanAmbit.Ambit > 2) then begin
          if (ClanAmbit.Ambit mod 2) = 0 then
            sAmbit := '2'
          else
            sAmbit := '1';
      end else
          sAmbit := '0';
      sData := sData + Clan.m_MemberList.Keys + '/' + sAmbit + '/';
      end;
    end;
end;
SendDefMessage(CM_GUILDCLAN, 0, 0, 0, 0, sData);
end;

procedure TPlayObject.ClientClanOperate(nOpCode: Integer; sMsg: string);
var
sName, ClanName                     : string;
Hum                                 : TPlayObject;
Clan                                  : TClan;
begin
if (m_MyClan <> nil) then begin
    case nOpCode of
      0: begin                                                                                    //招收弟子
          sName := DeCodeString(sMsg);
          Hum := UserEngine.GetPlayObject(sName);
          if (Hum <> nil) then begin
            if CretInNear10XY(Hum, m_nCurrX, m_nCurrY) then begin
            if (Hum.m_MyGuild = m_MyGuild) then begin
                Clan := TClan(m_MyClan);
                if (Hum.m_MyClan = nil) and (Clan.ChiefName = m_sCharName) then begin
                  Hum.SendDefMessage(CM_CLANQUERY, 0, 1, 0, 0, m_sCharName);
                  Hum.m_sQueryName := m_sCharName;
                end else begin
                  SysMsg('对方已有宗族!', c_Red, t_Hint);
                end;
            end else
                SysMsg('对方和你不是同一行会,不能加入!', c_Red, t_Hint);
            end else
            SysMsg('想加入宗族的成员必须在族长附近。', c_Red, t_Hint);
          end;
      end;
      1: begin                                                                                    //开除弟子
          sName := DeCodeString(sMsg);
          if (sName <> m_sCharName) then begin
            Hum := UserEngine.GetPlayObject(sName);
            Clan := TClan(m_MyClan);
            if (Hum <> nil) and (Hum.m_MyClan <> nil) and (Clan.ChiefName = m_sCharName) then begin
            if (Hum.m_MyClan = m_MyClan) then begin
                Clan := TClan(Hum.m_MyClan);
                if Clan.DelMember(sName) then begin
                  Hum.m_MyClan := nil;
                  Hum.SendDefMessage(CM_CLANOPERATE, 0, 1, 0, 0, Clan.m_sClanName + '/' + sName);
                end;
            end else begin
                SysMsg('对方不是你的宗族弟子!', c_Red, t_Hint);
            end;
            end;
          end else
            SysMsg('不能删除自己', c_Red, t_Hint);
      end;
      2: begin                                                                                    //退出宗族
          Clan := TClan(m_MyClan);
          if (Clan <> nil) then begin
            if Clan.DelMember(m_sCharName) then begin
            m_MyClan := nil;
            SendDefMessage(CM_CLANOPERATE, 0, 1, 0, 0, Clan.m_sClanName + '/' + m_sCharName);
            end;
          end;
      end;
      3: begin                                                                                    //解散宗族
          Clan := TClan(m_MyClan);
          if (Clan.ChiefName = m_sCharName) then begin
            sName := Clan.m_sClanName;
            if Clan.CancelClan(m_sCharName) then begin
            g_GuildManager.DelClan(sName);
            SysMsg('成功解散宗族!', c_Red, t_Hint);
            end;
          end;
      end;
    end;
end;
end;

procedure TPlayObject.ClientClanReQuery(nOpCode: Integer; sMsg: string);
var
Hum                                 : TPlayObject;
Clan                                  : TClan;
Guild                                 : TGuild;
sGuildName                            : string;
begin
if (m_sQueryName <> '') then Hum := UserEngine.GetPlayObject(m_sQueryName);
if (Hum <> nil) and (not m_boDeath) and (not m_boGhost) then begin
    Clan := TClan(Hum.m_MyClan);
    if (Clan <> nil) and (CompareStr(Clan.ChiefName, m_sQueryName) = 0) then begin
      case LoByte(nOpCode) of
      1: begin
            if (HiByte(nOpCode) = 1) then begin
            if (Clan <> nil) then begin
                if Clan.AddMember(Self) then begin
                  m_MyClan := Clan;
                  //如果宗族有行会,则需要加入该行会
                  if (Hum.m_MyGuild <> nil) and (m_MyGuild = nil) then begin
                  TGuild(Hum.m_MyGuild).AddMember(Self);
                  UserEngine.SendServerGroupMsg(SS_207, g_Config.nServerNumber, TGuild(Hum.m_MyGuild).sGuildName);
                  m_MyGuild := TGuild(Hum.m_MyGuild);
                  m_sGuildRankName := TGuild(Hum.m_MyGuild).GetRankName(Self, m_nGuildRankNo);
                  RefShowName();
                  SysMsg('你已加入行会: ' + TGuild(Hum.m_MyGuild).sGuildName + ' 当前封号为: ' + m_sGuildRankName, c_Green, t_Hint);
                  end;
                  SysMsg('成功加入宗族!', c_Red, t_Hint);
                  SendFiendList(4);
                  SendMeOnlineState(1, 4);
                end;
            end;
            end else begin
            Hum.SysMsg('对方不同意加入宗族!', c_Red, t_Hint);
            end;
          end;
      end;
    end;
end;
end;

function TPlayObject.CheckMapRideOn(Envir: TEnvirnoment): Boolean;
var
btType                              : byte;
begin
Result := False;
if Envir = nil then Exit;
if (not m_PEnvir.m_MapFlag.boRideOn) and (m_btHorseType > 0) then Exit;

if m_PEnvir.m_MapFlag.boNoRidePet or g_Config.boChMapRideOff then Exit;
if m_boRideOn then begin
    if m_boPneuma and (m_PneumaObject <> nil) then
      btType := TPlayObject(m_PneumaObject).m_PetInfo.btType
    else
      btType := m_PetInfo.btType;
end else
    btType := m_PetInfo.btType;

if (btType in ) and (not m_PEnvir.m_MapFlag.boCanRideShark) then Exit;
if not (btType in ) and (m_PEnvir.m_MapFlag.boWaterNeed) and (not m_boUnWater) then Exit;
Result := True;
end;

//火龙附体

procedure TPlayObject.MagFieryDragonRun();
var
i                                     : Integer;
BaseObject                            : TBaseObject;
nPower                              : Integer;
begin
nPower := 0;
if ((GetTickCount - m_dwFieryDragonRunTick) > 1000) then begin
    m_dwFieryDragonRunTick := GetTickCount();
    if (m_wStatusTimeArr > 0) or (m_wStatusTimeArr > 0) or
      (m_wStatusTimeArr > 0) or (m_btRandomDanceTime > 0) then
    begin
      for i := 0 to m_VisibleActors.Count - 1 do begin
      BaseObject := TBaseObject(pTVisibleBaseObject(m_VisibleActors).BaseObject);
      if (not BaseObject.m_boDeath) and (BaseObject <> Self) then begin
          if IsProperTarget(BaseObject) then begin
            if (abs(m_nCurrX - BaseObject.m_nCurrX) <= 3) and (abs(m_nCurrY - BaseObject.m_nCurrY) <= 3) then begin

            end;

            if (abs(m_nCurrX - BaseObject.m_nCurrX) <= 2) and (abs(m_nCurrY - BaseObject.m_nCurrY) <= 2) then begin
            //火龙附体
            if (m_wStatusTimeArr > 0) then begin
                nPower := m_wCurFightValue * 2;
                BaseObject.SendMsg(Self, RM_MAGSTRUCK, 0, nPower, SKILL_FIERYDRAGON, 0, '');
            end;

            end;
          end;
      end;
      end;
    end;
end;
end;

//投石车攻击目标

procedure TPlayObject.ClientCatapultAttackTarget(nOpCode, nX, nY: Integer);
var
MessageBody                           : TMessageBody3W;
begin
if m_boDeath or m_boGhost then Exit;

if (GetTickCount - m_dwCatapultAttackTick) < 3000 then Exit;

if m_boCatapultMode and m_boCatapultAttackMode then begin
    if m_PEnvir.CanWalk(nX, nY, True) then begin
      //检测炮弹
      if nOpCode = 0 then begin
      MessageBody.wX := nX;
      MessageBody.wY := nY;
      MessageBody.wParam := 0;
      SendRefMsg(RM_LAPIDATION, 0, Integer(Self), nX, nY, EnCodeBuffer(@MessageBody, SizeOf(TMessageBody3W)));
      end else begin                                                                              //速射

      end;
      m_dwCatapultAttackTick := GetTickCount;
      //SendRefMsg(RM_CATAPULTATTACK, 0, Integer(Self), nX, nY, '');
      SendDefMessage(SM_CATAPULTATTACK, Integer(Self), nX, nY, 0, '');
    end else begin
      SysMsg('请向空地投弹', c_Red, t_Hint);
      SendDefMessage(SM_CATAPULTATTACK, Integer(Self), nX, nY, 1, '');
    end;
end;
end;

//附加天元心法属性

procedure TPlayObject.RecalcMentalLevelAbilitys;
var
MentalAbility                         : pTMentalAbility;
begin
if m_boPneuma then Exit;

MentalAbility := UserEngine.GetMentalAbil(m_btJob, m_btMentalLevel);
if MentalAbility <> nil then begin
    m_nMentalPointMax := MentalAbility.MentalExp;
    m_AddAbil.dwHP := _MIN(MAXHUMHP, m_AddAbil.dwHP + MentalAbility.HP);
    case m_btJob of
      0: m_AddAbil.wDC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wDC) + MentalAbility.DC), _MIN(High(MaxInt), hiword(m_AddAbil.wDC) + MentalAbility.DC2));
      1: m_AddAbil.wMC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wMC) + MentalAbility.DC), _MIN(High(MaxInt), hiword(m_AddAbil.wMC) + MentalAbility.DC2));
      2: m_AddAbil.wSC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wSC) + MentalAbility.DC), _MIN(High(MaxInt), hiword(m_AddAbil.wSC) + MentalAbility.DC2));
    end;
    m_AddAbil.wAC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wAC) + MentalAbility.AC), _MIN(High(MaxInt), hiword(m_AddAbil.wAC) + MentalAbility.AC2));
    m_AddAbil.wMAC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wMAC) + MentalAbility.MAC), _MIN(High(MaxInt), hiword(m_AddAbil.wMAC) + MentalAbility.MAC2));
    m_AddAbil.wElementForceMax := _MIN(High(MaxInt), m_AddAbil.wElementForceMax + MentalAbility.ElementForce);
    m_AddAbil.btThump := _MIN(High(word), m_AddAbil.btThump + MentalAbility.Thump);
    m_AddAbil.wAgainst := _MIN(High(word), m_AddAbil.wAgainst + MentalAbility.Against);
    //MentalAbility.UnPalsy    抗麻痹
end;
end;

procedure TPlayObject.ClientQueryMentalAbilitys(PlayObject: TPlayObject);
type
TMentalPack = packed record
    btType: byte;
    wValue: word;
end;
var
MentalAbility                         : pTMentalAbility;
NewMentalAbility                      : pTMentalAbility;
MentalSet                           : array of word;
MentalPack                            : array of TMentalPack;
i, nCount                           : Integer;
s, sName                              : string;
Foresee                               : TStringList;
begin
if PlayObject = nil then Exit;

MentalSet := MakeWord($01, $0B);
MentalSet := MakeWord($06, $01);
MentalSet := MakeWord($09, $01);
MentalSet := MakeWord($0A, $01);
MentalSet := MakeWord($0B, $11);
MentalSet := MakeWord($0C, $05);
MentalSet := MakeWord($0D, $14);
MentalSet := MakeWord($0E, $0B);
m_defMsg := MakeDefaultMsg(CM_QUERYMENTAL, 0, 8, 0, 0);
SendSocket(@m_defMsg, EnCodeBuffer(@MentalSet, 16));

MentalAbility := UserEngine.GetMentalAbil(PlayObject.m_btJob, PlayObject.m_btMentalLevel);
if MentalAbility <> nil then begin
    MentalPack.btType := $01;
    MentalPack.wValue := MakeWord(MentalAbility.DC, MentalAbility.DC2);
    MentalPack.btType := $06;
    MentalPack.wValue := MentalAbility.HP;
    MentalPack.btType := $09;
    MentalPack.wValue := MakeWord(MentalAbility.AC, MentalAbility.AC2);
    MentalPack.btType := $0A;
    MentalPack.wValue := MakeWord(MentalAbility.MAC, MentalAbility.MAC2);
    MentalPack.btType := $0B;
    MentalPack.wValue := MentalAbility.Thump;
    MentalPack.btType := $0C;
    MentalPack.wValue := MentalAbility.ElementForce;
    MentalPack.btType := $0D;
    MentalPack.wValue := MentalAbility.Against;
    MentalPack.btType := $0E;
    MentalPack.wValue := MentalAbility.UnPalsy;
    s := Trim(MentalAbility.Foresee);
    nCount := 0;
    if s <> '' then begin
      NewMentalAbility := UserEngine.GetMentalAbil(PlayObject.m_btJob, PlayObject.m_btMentalLevel + 1);
      if (MentalAbility <> nil) and (NewMentalAbility <> nil) then begin
      Foresee := TStringList.Create;
      try
          ExtractStrings([','], [], PChar(s), Foresee);
          for i := 0 to Foresee.Count - 1 do begin
            if nCount >= 6 then Break;
            sName := UpperCase(Foresee.Strings);
            if (sName = 'DC') then begin
            MentalPack.btType := $01;
            MentalPack.wValue := MakeWord(NewMentalAbility.DC - MentalAbility.DC, NewMentalAbility.DC2 - MentalAbility.DC2);
            Inc(nCount);
            Continue;
            end;
            if (sName = 'HP') then begin
            MentalPack.btType := $06;
            MentalPack.wValue := NewMentalAbility.HP - MentalAbility.HP;
            Inc(nCount);
            Continue;
            end;
            if (sName = 'EF') then begin
            MentalPack.btType := $0C;
            MentalPack.wValue := NewMentalAbility.ElementForce - MentalAbility.ElementForce;
            Inc(nCount);
            Continue;
            end;
            if (sName = 'AC') then begin
            MentalPack.btType := $09;
            MentalPack.wValue := MakeWord(NewMentalAbility.AC - MentalAbility.AC, NewMentalAbility.AC2 - MentalAbility.AC2);
            Inc(nCount);
            Continue;
            end;
            if (sName = 'MAC') then begin
            MentalPack.btType := $0A;
            MentalPack.wValue := MakeWord(NewMentalAbility.MAC - MentalAbility.MAC, NewMentalAbility.MAC2 - MentalAbility.MAC2);
            Inc(nCount);
            Continue;
            end;
            if (sName = 'THUMP') then begin
            MentalPack.btType := $0B;
            MentalPack.wValue := NewMentalAbility.Thump - MentalAbility.Thump;
            Inc(nCount);
            Continue;
            end;
            if (sName = 'AGAINST') then begin
            MentalPack.btType := $0D;
            MentalPack.wValue := NewMentalAbility.Against - MentalAbility.Against;
            Inc(nCount);
            Continue;
            end;
            if (sName = 'UNPALSY') then begin
            MentalPack.btType := $0E;
            MentalPack.wValue := NewMentalAbility.UnPalsy - MentalAbility.UnPalsy;
            Inc(nCount);
            Continue;
            end;
          end;
      finally
          Foresee.free;
      end;
      end else
      nCount := 0;
    end;
    m_defMsg := MakeDefaultMsg(CM_QUERYMENTALABIL, Integer(PlayObject), MakeWord(8, nCount), PlayObject.m_btMentalLevel, 0);
    SendSocket(@m_defMsg, EnCodeBuffer(@MentalPack, SizeOf(TMentalPack) * (8 + nCount)));
end;
end;

//宠物摆摊

procedure TPlayObject.ClientPetDoShop(nPet: Integer; shopItemCount: word; sMsg: string);
var
RetCode                               : Integer;
DoShopResult                        : TDoShopResult;
i, j, ii                              : Integer;
UserShop                              : TUserShop;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
boFind                              : Boolean;
sName, s1C                            : string;
Castle                              : TUserCastle;
tm                                    : DWORD;
Shop                                  : TShop;
BaseObjectList                        : TList;
BaseObject                            : TBaseObject;
resourcestring
sHint1                              = '骑宠状态不能摆摊。';
sHint2                              = '此地图禁止摆摊。';
sHint3                              = '正在攻城的区域禁止摆摊。';
sHint4                              = '你正在进行抢宝活动,禁止摆摊。';
sHint5                              = '周围没有空的位置,无法摆下你的摊位。';
sHint6                              = '摆摊物品价格定义错误,请勿使用非法外挂!';
sHint7                              = '金币交易价格定义超过允许的范围。';
sHint8                              = '元宝交易价格定义超过允许的范围。';
sHint9                              = '此物品开启后不允许交易,但时间到后可丢弃。';
sHint10                               = '你要出售的物品并不存在。';
sHint11                               = ' 不允许交易。';
begin
if m_PackPet <> nil then Exit;

if nPet = Integer(Self) then nPet := Integer(m_Pet);

if (nPet = 0) or (m_Pet = nil) or (nPet <> Integer(m_Pet)) then Exit;

{
    if m_boRideOn then begin
      SysMsg(sHint1, c_Red, t_Hint);
      Exit;
    end;
   }
if not g_Config.boPetDoShop then begin
    SysMsg('当前服务器宠物豹摆摊系统未开放!', c_Red, t_Hint);
    Exit;
end;

if not m_boCanDeal then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, g_sCanotTryDealMsg);
    Exit;
end;

if m_PEnvir.m_MapFlag.boNoDoShop then begin
    SysMsg(sHint2, c_Red, t_Hint);
    Exit;
end;

Castle := g_CastleManager.InCastleWarArea(Self);
//城堡正在战斗
if (Castle <> nil) and Castle.m_boUnderWar then begin
    SysMsg(sHint3, c_Red, t_Hint);
    Exit;
end;
if m_boArrow then begin
    SysMsg(sHint4, c_Red, t_Hint);
    Exit;
end;

BaseObjectList := TList.Create;
try
    GetMapBaseObjects(m_Pet.m_PEnvir, m_Pet.m_nCurrX, m_Pet.m_nCurrY, 2, BaseObjectList);
    for i := 0 to BaseObjectList.Count - 1 do begin
      BaseObject := TBaseObject(BaseObjectList.Items);
      if (BaseObject.m_btRaceServer = RC_NPC) then begin
      SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, '你离NPC太近了,不能摆摊。');
      Exit;
      end;
    end;
finally
    BaseObjectList.free;
end;

//检查前后左右有没有空位置
if (shopItemCount > 0) then begin                                                               //开始摆摊的时候才需要判断
    if (m_Pet.m_nCurrX > 0) and (m_Pet.m_nCurrX < m_PEnvir.m_nWidth) and
      (m_Pet.m_nCurrY > 0) and (m_Pet.m_nCurrY < m_PEnvir.m_nHeight) and
      m_PEnvir.CanWalk(m_Pet.m_nCurrX, m_Pet.m_nCurrY - 1, True) and                              //00 -1
      m_PEnvir.CanWalk(m_Pet.m_nCurrX + 1, m_Pet.m_nCurrY - 1, True) and                            //11 -1
      m_PEnvir.CanWalk(m_Pet.m_nCurrX + 1, m_Pet.m_nCurrY, True) and                              //210
      m_PEnvir.CanWalk(m_Pet.m_nCurrX + 1, m_Pet.m_nCurrY + 1, True) and                            //311
      m_PEnvir.CanWalk(m_Pet.m_nCurrX, m_Pet.m_nCurrY + 1, True) and                              //401
      m_PEnvir.CanWalk(m_Pet.m_nCurrX - 1, m_Pet.m_nCurrY + 1, True) and                            //5 -11
      m_PEnvir.CanWalk(m_Pet.m_nCurrX - 1, m_Pet.m_nCurrY, True) and                              //6 -10
      m_PEnvir.CanWalk(m_Pet.m_nCurrX - 1, m_Pet.m_nCurrY - 1, True) then                           //7 -1 -1
    else begin
      SysMsg(sHint5, c_Red, t_Hint);
      Exit;
    end;
end;

shopItemCount := _MIN(15, shopItemCount);
if shopItemCount = 0 then begin
    RetCode := $FF;
end else begin                                                                                    //判断能否摆摊
    RetCode := 1;
end;
FillChar(Shop, SizeOf(TShop), #0);
if (RetCode = 1) and (shopItemCount > 0) and (sMsg <> '') then begin                              //取摊位名字和物品
    DeCodeBuffer(sMsg, @Shop, SizeOf(TShop));
end;
//检测摊位名称
if CheckFilterWords(Shop.ShopName) then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, '输入内容含有非法字符!');
    Exit;
end;
for i := 0 to shopItemCount - 1 do begin
    if Shop.ShopItems.MakeIndex <> 0 then begin
      if not (Shop.ShopItems.PayType in ) then begin
      SysMsg(sHint6, c_Red, t_Hint);
      shopItemCount := 0;
      Exit;
      end;
      if (Shop.ShopItems.PayType = 0) and
      ((Shop.ShopItems.Price < 1) or (Shop.ShopItems.Price > 150000000)) then begin
      SysMsg(sHint7, c_Red, t_Hint);
      shopItemCount := 0;
      Exit;
      end;
      if (Shop.ShopItems.PayType = 1) and
      ((Shop.ShopItems.Price < 1) or (Shop.ShopItems.Price > 10000000)) then begin
      SysMsg(sHint8, c_Red, t_Hint);
      shopItemCount := 0;
      Exit;
      end;

      //检查物品合法性
      boFind := False;
      for j := m_ItemList.Count - 1 downto 0 do begin
      UserItem := pTUserItem(m_ItemList);
      if UserItem.MakeIndex = Shop.ShopItems.MakeIndex then begin
          StdItem := UserEngine.GetStdItem(UserItem.wIndex);
          if StdItem = nil then Break;

          sName := '';
          ItemUnit.GetCustomItemName(UserItem, sName);
          {物品控制-禁止摆摊物品}
          if CheckSPCode(StdItem.SPCode, SP_DISABLEDOSHOP) or
            ((UserItem.btItemExt and EX_BIND) = EX_BIND) then begin                              //物品控制-禁止摆摊物品
            SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, sName + sHint11);
            shopItemCount := 0;
            Exit;
          end;
          //魂佑灵兽禁止放入灵犀宝盒
          if (StdItem.StdMode = 49) and (StdItem.Shape = 51) and (UserItem.btItemExt >= 2) then begin
            SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, '魂佑灵兽不允许出售');
            shopItemCount := 0;
            Exit;
          end;
          {已放出豹禁止出售}
          if IsDownPetItem(UserItem.MakeIndex) then begin
            SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, sName + '放出宠物时不允许出售');
            shopItemCount := 0;
            Exit;
          end;
          boFind := True;
          Break;
      end;
      end;
      if not boFind then begin
      SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, sHint10);
      shopItemCount := 0;
      Exit;
      end;
    end;
end;
for i := shopItemCount to 14 do begin
    Shop.ShopItems.MakeIndex := 0;
    Shop.ShopItems.Price := 0;
    Shop.ShopItems.PayType := 0;
end;
m_PackPet := g_PetBoothManage.CreatePetObject(m_dwDBIndex, m_Pet, Shop.ShopName);
if m_PackPet = nil then Exit;
m_PackPet.SendRefMsg(RM_TURN,
    m_PackPet.m_btDirection,
    m_PackPet.m_nCurrX,
    m_PackPet.m_nCurrY,
    CalcCent(m_PackPet.m_WAbil.dwHP, m_PackPet.m_WAbil.dwMaxHP),
    m_PackPet.GetShowName);

m_PetInfo := m_PetInfo;
PetHide(m_PetInfo.nMakeIndex);

//把要出售的物品移动到豹子包裹里
for i := 0 to shopItemCount - 1 do begin
    if Shop.ShopItems.MakeIndex <> 0 then begin
      for j := m_ItemList.Count - 1 downto 0 do begin
      UserItem := pTUserItem(m_ItemList);
      if UserItem.MakeIndex = Shop.ShopItems.MakeIndex then begin
          if m_PackPet.AddBoothItem(UserItem, @Shop.ShopItems) then begin
            m_ItemList.Delete(j);
            SendDelItems(UserItem);
            WeightChanged;
          end;
          Break;
      end;
      end;
    end;
end;

m_nPetTargetX := m_PackPet.m_nCurrX;
m_nPetTargetY := m_PackPet.m_nCurrY;

if (RetCode = 0) and ((m_PackPet.m_btDirection mod 2) = 0) then
    m_PackPet.m_btDirection := m_PackPet.m_btDirection + 1;

m_PackPet.GetUserShop(@UserShop);
UserShop.DoShopResult.RetCode := RetCode;
m_PackPet.SaveRcd := True;

//发送操作结果给本人
SendDefMessage(34977, 0, 0, 0, 0, '');
SendDelayMsg(Self, RM_SENDSHOPITEMS, 0, 0, 0, 0, '', 500);                                        // m_PackPet.SendShopItems(Self, 1);

UserShop.DoShopResult.RetCode := 0;
UserShop.GoodsCount := 0;

//广播操作结果
SendRefMsg(RM_PETDOSHOP,
    m_PackPet.m_btDirection,
    MakeLong(m_PackPet.m_nCurrX, m_PackPet.m_nCurrY),
    RetCode,
    Integer(m_PackPet),
    EnCodeBuffer(@UserShop, 62));
SendPetInfo($03);
SysMsg('灵兽守摊开始', c_Red, t_Hint);

if (not m_boPneuma) then begin
    m_sScriptParam := '1';
    ExecuteScript(g_FunctionNPC, '@开始摆摊');
end;
end;

procedure TPlayObject.ClientRequestPetDoShop();                                                   //请求摆摊
var
i, j                                  : Integer;
UserItem                              : pTUserItem;
ShopInfo                              : TShopInfo;
begin
if (m_PackPet = nil) then begin
    SendDefMessage(SM_80D5, Integer(m_Pet), 5, 0, 0, '');
end else
    SendDefMessage(SM_80D5, Integer(m_PackPet), 5, 1, 0,
      Format('%s(%d:%d)', [m_PackPet.m_PEnvir.m_sMapDesc,
      m_PackPet.m_nCurrX, m_PackPet.m_nCurrY]));
end;

//宠物收摊

procedure TPlayObject.ClientPetStopDoShop();
begin
if (m_PackPet <> nil) then begin
    m_PackPet.PetStopDoShop();
    m_PackPet := nil;
    m_PetInfo.nMakeIndex := 0;
    m_PetInfo.wLevel := 0;
    m_PetInfo.btType := 0;
    m_PetInfo.btReLive := 0;
    SendDefMessage(32981, 0, 0, 0, 0, '');
end;
end;

//更新宠物摊位物品和名称

procedure TPlayObject.ClientUpdatePetShop(nPet: Integer; nOpCode: Integer; sMsg: string);
begin
if (m_PackPet = nil) or (nPet <> Integer(m_PackPet)) then Exit;                                 //错误
if ((m_PackPet.m_PEnvir = m_PEnvir) and
    (abs(m_PackPet.m_nCurrX - m_nCurrX) < 15) and
    (abs(m_PackPet.m_nCurrY - m_nCurrY) < 15)) then
    m_PackPet.UpdatePetShop(Self, nOpCode, sMsg);
end;

//取摆摊物品

procedure TPlayObject.ClientGetbackPetShopItem();
var
i, j                                  : Integer;
UserItem                              : pTUserItem;
ShopInfo                              : TShopInfo;
begin
if m_boGhost or m_boDeath then Exit;
ShopInfo := g_PetBoothManage.GetPetInfo(m_dwDBIndex);
if ShopInfo = nil then begin
    SendDefMessage(32981, Integer(Self), 3, 16, 0, '');
    Exit;
end;

if ShopInfo.m_PetMon <> nil then begin
    SendDefMessage(32981, Integer(Self), 3, 19, 0, '');
    Exit;
end;

if ShopInfo.Count <= 0 then begin
    SendDefMessage(32981, Integer(Self), 3, 16, 0, '');
    Exit;
end;
if g_PetBoothManage.GetUserItem(ShopInfo, Self) = 0 then begin
    SysMsg('物品已放入你的包裹内', c_Red, t_Hint);
    WeightChanged;
    SendDefMessage(32981, Integer(Self), 3, 0, 0, '');
end else
    SendDefMessage(32981, Integer(Self), 3, 13, 0, '');
end;

procedure TPlayObject.ClientGetbackPetMoney();
var
btCode                              : byte;
ShopInfo                              : TShopInfo;
begin
if m_boGhost or m_boDeath then Exit;
if m_PackPet <> nil then
    ShopInfo := m_PackPet.ShopInfo
else
    ShopInfo := g_PetBoothManage.GetPetInfo(m_dwDBIndex);

if ShopInfo = nil then begin
    SendDefMessage(32981, Integer(Self), 2, 23, 0, '');
    Exit;
end;

btCode := g_PetBoothManage.GetUserGold(ShopInfo, Self);
if btCode = 1 then begin
    SendDefMessage(32981, Integer(Self), 2, 0, 0, '');
end else begin
    if btCode = 0 then
      SendDefMessage(32981, Integer(Self), 2, 23, 0, '')
    else begin
      if btCode = 2 then begin
      SendDefMessage(32981, Integer(Self), 2, 18, 0, '');
      end else begin
      SendDefMessage(32981, Integer(Self), 2, 13, 0, '');
      end;
    end;
end;
end;

procedure TPlayObject.SendShopResult();
var
DoShopResult                        : TDoShopResult;
UserShop                              : TUserShop;
begin
//重新发送摊位状态
if m_wShopItemCount > 0 then
    DoShopResult.RetCode := 0
else
    DoShopResult.RetCode := $FF;
DoShopResult.ShopType := m_wShopKind;
DoShopResult.FlagType := m_btShopBanner;
DoShopResult.FlagColor := m_nBannerColor;

m_defMsg := MakeDefaultMsg(SM_DOSHOP, Integer(Self), m_nCurrX, m_nCurrY, m_btDirection);
SendSocket(@m_defMsg, EnCodeBuffer(@DoShopResult, SizeOf(TDoShopResult)));

UserShop.DoShopResult.RetCode := DoShopResult.RetCode;
UserShop.DoShopResult.ShopType := DoShopResult.ShopType;
UserShop.DoShopResult.FlagType := DoShopResult.FlagType;
UserShop.DoShopResult.FlagColor := DoShopResult.FlagColor;
UserShop.GoodsCount := 0;
UserShop.ShopName := m_Shop.ShopName;

//发送操作结果和商店名称
SendRefMsg(RM_DOSHOP,
    m_btDirection,
    MakeLong(m_nCurrX, m_nCurrY),
    DoShopResult.ShopType,
    0,
    EnCodeBuffer(@UserShop, SizeOf(TUserShop) {- SizeOf(TClientItem) * 15}));
end;

function TPlayObject.IsShop(): Boolean;                                                             //是否摆摊
begin
Result := m_wShopItemCount > 0;
end;

procedure TPlayObject.GetUserShop(const pUserShop: PTUserShop);                                     //取摆摊状态
begin
pUserShop.DoShopResult.ShopType := m_wShopKind;
pUserShop.DoShopResult.RetCode := 0;
pUserShop.DoShopResult.FlagType := m_btShopBanner;
pUserShop.DoShopResult.FlagColor := m_nBannerColor;
pUserShop.GoodsCount := 0;
pUserShop.ShopName := m_Shop.ShopName;
end;

//购买玩家摊位的物品 PlayObject:卖家 nInt:MakeIndex

procedure TPlayObject.ClientBuyShopItem(Play: TBaseObject; sItemName: string; nInt: Integer);
var
i, j, p                               : Integer;
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
sName                                 : string;
boFound                               : Boolean;
Price                                 : Integer;
pricetype                           : word;
nCode                                 : Integer;
maxGold                               : Int64;
PlayObject                            : TPlayObject;
petBooth                              : TPetBoothMonster;
begin
if (nInt = 0) or (Play = nil) then Exit;
if m_boGhost or m_boDeath then Exit;

if Play is TPlayObject then
    PlayObject := Play as TPlayObject
else if Play is TPetBoothMonster then begin
    petBooth := Play as TPetBoothMonster;
    petBooth.BuyShopItem(Self, sItemName, nInt);
    Exit;
end else
    Exit;

boFound := False;
Price := 0;
pricetype := 0;
for i := 0 to PlayObject.m_wShopItemCount - 1 do begin
    if nInt = PlayObject.m_Shop.ShopItems.MakeIndex then begin
      boFound := True;
      p := i;
      Price := PlayObject.m_Shop.ShopItems.Price;
      pricetype := PlayObject.m_Shop.ShopItems.PayType;
      Break;
    end;
end;
nCode := 1;
if not boFound then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, '你要购买的物品已经被售出了!');
    Exit;
end;
//检查有没有钱买
if (pricetype = 0) and (m_nGold < Price) then begin
    nCode := 3;
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, '你没有这么多金币!');
    Exit;
end else if (pricetype = 1) and (m_nGameGold < Price) then begin
    nCode := 3;
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, '你没有这么多元宝!');
    Exit;
end;
if (pricetype <> 0) and (pricetype <> 1) then begin
    SysMsg('暂不支持该物品的支付方式。', c_Red, t_Hint);
    Exit;
end;
//检查卖家是否超过金币或元宝携带数限制
if (pricetype = 0) then begin
    nCode := 3;
    maxGold := PlayObject.m_nGold + Price;
    if maxGold > g_Config.nHumanMaxGold then begin
      SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0,
      g_sDealHumanGoldLargeThenLimit);
      Exit;
    end;
end else if (pricetype = 1) then begin
    nCode := 3;
    maxGold := PlayObject.m_nGameGold + Price;
    if maxGold > g_Config.nHumanMaxGameGold then begin
      SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0,
      g_sDealHumanGameGoldLargeThenLimit);
      Exit;
    end;
end;

for i := PlayObject.m_ItemList.Count - 1 downto 0 do begin
    UserItem := PlayObject.m_ItemList.Items;
    if (UserItem <> nil) and (UserItem.MakeIndex = nInt) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem <> nil then begin
      //取自定义物品名称
      sName := '';
      ItemUnit.GetCustomItemName(UserItem, sName);

      if (CompareText(sItemName, sName) = 0) then begin
          if (PlayObject <> nil) and
            (PlayObject.m_wShopItemCount > 0) and
            ((PlayObject.m_PEnvir = m_PEnvir) and
            (abs(PlayObject.m_nCurrX - m_nCurrX) < 15) and
            (abs(PlayObject.m_nCurrY - m_nCurrY) < 15)) then begin

            //重量、包裹容量允许
            if IsAddWeightAvailable(StdItem.Weight) then begin

            //添加到包裹
            if AddItemToBag(UserItem) then begin
                //删除包裹物品
                PlayObject.m_ItemList.Delete(i);

                //移动物品
                Dec(PlayObject.m_wShopItemCount);
                for j := p to PlayObject.m_wShopItemCount - 1 do begin
                  PlayObject.m_Shop.ShopItems := PlayObject.m_Shop.ShopItems;
                end;

                if pricetype = 0 then begin
                  //给卖物所得
                  PlayObject.IncGold(Price);
                  PlayObject.GoldChanged;
                  //减买物消费
                  DecGold(Price);
                  GoldChanged;
                end else if pricetype = 1 then begin
                  //给卖物所得
                  Inc(PlayObject.m_nGameGold, Price);
                  PlayObject.GameGoldChanged;
                  //减买物消费
                  Dec(m_nGameGold, Price);
                  GameGoldChanged;
                end;

                SendAddItem(UserItem);
                nCode := 0;

                //发送刷新后的摊位信息,
                PlayObject.SendShopResult();

                {清除自定义物品名称}//是否有必要????
                if UserItem.btValue and $01 = 1 then begin
                  ItemUnit.DelCustomItemName(UserItem.MakeIndex, UserItem.wIndex);
                  UserItem.btValue := UserItem.btValue and $FE;
                end;

                m_dwSaveRcdTick := 0;
                //发送删除物品的数据包
                PlayObject.SendDelItems(UserItem);

                UserEngine.SaveHumanRcd(PlayObject);
                PlayObject.m_dwSaveRcdTick := GetTickCount;
            end else
                nCode := 2;
            end else
            SysMsg(g_sCanotGetItems, c_Red, t_Hint);
          end;
      end;
      end;
      Break;
    end;
end;

// for
if nCode = 0 then begin
    SendMsg(Self, RM_BUYITEM_SUCCESS, 0, m_nGold, nInt, 0, '');
    SysMsg('你购买了' + sName, c_Red, t_Hint);
    PlayObject.SendShopItems(Self, 2);
    if PlayObject.m_btRaceServer = RC_PLAYOBJECT then begin
      if pricetype = 0 then
      PlayObject.SysMsg(m_sCharName + '在' + FormatDateTime('yyyy-mm-dd hh:nn:ss', Date + Time) + '以' + IntToStr(Price) + '个金币购买了你的' + sName, c_Red, t_Hint)
      else
      PlayObject.SysMsg(m_sCharName + '在' + FormatDateTime('yyyy-mm-dd hh:nn:ss', Date + Time) + '以' + IntToStr(Price) + '个元宝购买了你的' + sName, c_Red, t_Hint);
    end;

    if (UserItem <> nil) and (StdItem <> nil) then begin
      if not IsCheapStuff(StdItem.StdMode) then begin
      if StdItem.boGameLog = 1 then
          AddGameDataLog('37' + #9 +
            m_sMapName + #9 +
            IntToStr(m_nCurrX) + #9 +
            IntToStr(m_nCurrY) + #9 +
            PlayObject.m_sCharName + #9 +
            StdItem.Name + #9 +
            IntToStr(UserItem.MakeIndex) + #9 +
            '1' + #9 +
            m_sCharName);
      end;
    end;

    if pricetype = 0 then begin
      if g_boGameLogGold then
      AddGameDataLog('14' + #9 +
          m_sMapName + #9 +
          IntToStr(m_nCurrX) + #9 +
          IntToStr(m_nCurrY) + #9 +
          m_sCharName + #9 +
          sSTRING_GOLDNAME + #9 +
          IntToStr(m_nGold) + #9 +
          '1' + #9 +
          PlayObject.m_sCharName);
    end else begin
      if g_boGameLogGameGold then
      AddGameDataLog('17' + #9 +
          m_sMapName + #9 +
          IntToStr(m_nCurrX) + #9 +
          IntToStr(m_nCurrY) + #9 +
          m_sCharName + #9 +
          sSTRING_GAMEGOLDNAME + #9 +
          IntToStr(m_nGameGold) + #9 +
          '2' + #9 +
          PlayObject.m_sCharName);

    end;
end else begin
    SendMsg(Self, RM_BUYITEM_FAIL, 0, nCode, 0, 0, '');
end;
end;

procedure TPlayObject.SendAddPetSoulInfo(nMakeIndex: Integer);
var
boFind                              : Boolean;
i, ii                                 : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
begin
for ii := 0 to 7 do begin
    boFind := False;
    for i := 0 to m_ItemList.Count - 1 do begin
      UserItem := m_ItemList.Items;
      if (UserItem.MakeIndex = m_SoulPetItemIndex) then begin
      boFind := True;
      Break;
      end;
    end;
    if not boFind then begin
      m_SoulPetItemIndex := nMakeIndex;
      g_SmallPacketManage.Init();
      g_SmallPacketManage.WriteInteger(nMakeIndex);
      g_SmallPacketManage.WriteWord(ii);
      g_SmallPacketManage.FillWrite(64, 0);
      m_defMsg := MakeDefaultMsg(SM_ADDSOULPET, Integer(Self), 0, 0, 0);
      SendSocket(@m_defMsg, g_SmallPacketManage.GetMsg);
      Break;
    end;
end;
end;

//发送魂佑灵兽信息

procedure TPlayObject.ClientQueryPetSoulInfo;
var
i, ii, nCount                         : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
MagicList                           : array of byte;
btID, btLv                            : byte;
begin
nCount := 0;
FillChar(m_SoulPetItemIndex, SizeOf(m_SoulPetItemIndex), #0);
g_LargePacketManage.Init();
for i := 0 to m_ItemList.Count - 1 do begin
    UserItem := m_ItemList.Items;
    StdItem := UserEngine.GetStdItem(UserItem.wIndex);
    if (StdItem <> nil) and (StdItem.StdMode = 49) and (StdItem.Shape = 51) and (UserItem.btItemExt >= 2) then begin
      g_LargePacketManage.WriteInteger(UserItem.MakeIndex);
      g_LargePacketManage.WriteWord(nCount);
      FillChar(MagicList, 41, 0);
      //写入技能信息
      for ii := 0 to 9 do begin
      btID := UserItem.btExtra.PetMagics.GetID();
      btLv := UserItem.btExtra.PetMagics.GetLv();
      if (btID in ) and (btLv > 0) then begin
          MagicList := (btLv shl 4) or (ii and $0F);
      end;
      end;
      g_LargePacketManage.WriteBuffer(MagicList, 41);
      //23个技能位没有用到,写0
      g_LargePacketManage.FillWrite(23, 0);
      m_SoulPetItemIndex := UserItem.MakeIndex;
      Inc(nCount);
    end;
    if nCount >= 8 then Break;
end;

if nCount > 0 then begin
    m_defMsg := MakeDefaultMsg(SM_QUERYPETSOUL, Integer(Self), nCount, 0, 0);
    SendSocket(@m_defMsg, g_LargePacketManage.GetMsg);
end;
end;

//发送魂佑灵兽装备

procedure TPlayObject.ClientQueryPetSoulItem(nMakeIndex: Integer; wIndex: word);
begin
if Assigned(m_VersionManage) then
try
    m_VersionManage.OnQueryPetSoulItem(Self, nMakeIndex, wIndex);
except
    MainOutMessage(Format('TPlayObject::OnQueryPetSoulItem SoftVersionDate:%d', ));
end;
end;

//查询人物属性

procedure TPlayObject.ClientQueryAbility();
begin
if Assigned(m_VersionManage) then
try


    m_VersionManage.OnQueryAbility(Self);
except
    MainOutMessage(Format('TPlayObject::OnQueryAbility SoftVersionDate:%d', ));
end;
end;

function TPlayObject.GetPetSoulItem(const nMakeIndex: Integer; boNew: Boolean = False): pTPetSoulItem;
var
PetSoulItems                        : pTPetSoulItem;
i                                     : Integer;
begin
Result := nil;
PetSoulItems := nil;
for i := 0 to m_PetSoulItemsList.Count - 1 do begin
    PetSoulItems := pTPetSoulItem(m_PetSoulItemsList.Items);
    if (PetSoulItems^.nMakeIndex = nMakeIndex) then begin                                           //跟随的灵兽
      Result := PetSoulItems;
      Break;
    end;
end;

if (Result = nil) and boNew then begin
    New(Result);
    FillChar(Result^, SizeOf(TPetSoulItem), 0);
    Result^.nMakeIndex := nMakeIndex;
    m_PetSoulItemsList.Add(Result);
end;

end;

//计算魂佑灵兽装备的属性

procedure TPlayObject.RecalcPetSoulAbilitys;
resourcestring
sExceptionMsg                         = ' TPlayObject::RecalcPetSoulAbilitys Name=%s Code=%d';
const
nMax                                  : array of Integer = (2, 4, 6, 4, 6, 4, 6, 4, 6);
var
btMagicID                           : byte;
i, nWhere                           : Integer;
PetSoulItems                        : pTPetSoulItem;
StdItem                               : pTStdItem;
StdItem18                           : TStdItem;
UserItem                              : TUserItem;
nPetItemCount                         : array of Integer;
nCheckCode                            : Integer;
begin
nCheckCode := 0;
try
    m_FelementReduce := 0;
    m_FelementRedouble := 0;
    m_ReduceSkillRate := 0;
    FillChar(m_ReduceSkillPoint, SizeOf(m_ReduceSkillPoint), #0);

    nCheckCode := 1;

    if (not m_boBeast) or (m_PetInfo.nMakeIndex = 0) or m_boPneuma then Exit;

    nCheckCode := 2;

    PetSoulItems := GetPetSoulItem(m_PetInfo.nMakeIndex, True);
    if PetSoulItems = nil then Exit;
    nCheckCode := 3;

    for i := 1 to 9 do begin
      nPetItemCount := 0;
    end;
    nCheckCode := 4;
    for nWhere := Low(PetSoulItems^.Items) to High(PetSoulItems^.Items) do begin
      UserItem := PetSoulItems^.Items;
      nCheckCode := 5;
      if UserItem.wIndex > 0 then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem <> nil then begin
          StdItem18 := StdItem^;
          nCheckCode := 6;
          ItemUnit.GetItemAddValue(@UserItem, StdItem18);
          m_FelementRedouble := _MIN(High(word), m_FelementRedouble + LoWord(StdItem18.DC));      //五行攻击
          m_FelementReduce := _MIN(High(word), m_FelementReduce + LoWord(StdItem18.AC));            //五行防御
          nCheckCode := 7;
          btMagicID := UserItem.btItemExt;                                                      //抵抗技能ID
          for i := 0 to 40 do begin
            if (btMagicID = g_BeastMagic.wSkillID) then begin
            m_ReduceSkillPoint := _MIN(High(byte), m_ReduceSkillPoint + HiWord(StdItem18.MC)); //抵抗技能伤害
            Break;
            end;
          end;
          nCheckCode := 8;
          if StdItem.Shape in then Inc(nPetItemCount);
      end;
      end;
    end;
    nCheckCode := 9;
    //装备数量激活抵抗技能几率
    for i := 1 to 9 do begin
      if (nPetItemCount > nMax) then begin
      m_ReduceSkillRate := _MIN(10, m_ReduceSkillRate + i + 1);                                 //几率最高为10
      end;
    end;
except
    on E: Exception do
      MainOutMessage(Format(sExceptionMsg, ));
end;
end;

//穿戴灵兽装备

procedure TPlayObject.ClientTakeOnPetSoulItem(nWhere, nMakeIndex: Integer; wIndex: word);
var
n18, n14, i                           : Integer;
StdItem                               : pTStdItem;
UserItem, TakeoffItem               : pTUserItem;
sName                                 : string;
StdItem18                           : TStdItem;
PetSoulItems                        : pTPetSoulItem;
btReLive, btLevel                     : byte;
label
FailExit;
begin
if m_boPneuma or m_boGhost or m_boDeath then Exit;

if not (wIndex in ) then Exit;

if (m_PetInfo.nMakeIndex <> m_SoulPetItemIndex) and ((m_PetInfo.nMakeIndex <> m_SoulPetItemIndex)) then begin
    n18 := -1;
    goto FailExit;
end;

PetSoulItems := GetPetSoulItem(m_SoulPetItemIndex, True);
if PetSoulItems = nil then begin
    n18 := -1;
    goto FailExit;
end;

StdItem := nil;
UserItem := nil;
n14 := -1;
n18 := 0;
for i := 0 to m_ItemList.Count - 1 do begin
    UserItem := m_ItemList.Items;                                                                //包裹里的物品
    if (UserItem <> nil) and (UserItem.MakeIndex = nMakeIndex) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if StdItem <> nil then begin
      n14 := i;
      Break;
      end;
    end;
    UserItem := nil;
end;

if (m_SoulPetItemIndex = m_PetInfo.nMakeIndex) then begin
    btReLive := m_PetInfo.btReLive;
    btLevel := m_PetInfo.wLevel;
end else begin
    btReLive := m_PetInfo.btReLive;
    btLevel := m_PetInfo.wLevel;
end;

if (StdItem <> nil) and (UserItem <> nil) then begin
    if CheckPetUserItems(nWhere, StdItem) then begin
      StdItem18 := StdItem^;
      if (btReLive < 3) and (btLevel < StdItem18.NeedLevel) then begin
      SysMsg('灵兽等级不满足条件,无法佩戴。', c_Red, t_Hint);
      n18 := -1;
      goto FailExit;
      end;

      TakeoffItem := nil;
      if nWhere in then begin
      //取下物品
      if PetSoulItems^.Items.wIndex > 0 then begin
          New(TakeoffItem);
          TakeoffItem^ := PetSoulItems^.Items;
      end;
      PetSoulItems^.Items := UserItem^;
      DelBagItem(n14);
      if TakeoffItem <> nil then begin
          AddItemToBag(TakeoffItem);
          SendAddItem(TakeoffItem);
      end;
      n18 := 1;
      SendDefMessage(SM_TAKEPETSOULITEM, 0, MakeWord(1, 1), wIndex, 0, '');
      RecalcPetSoulAbilitys;
      RecalcAbilitys();                                                                           //重新计算属性
      SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
      SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
      end;
    end;
end;

FailExit:
if n18 <= 0 then
    SendDefMessage(SM_TAKEPETSOULITEM, 0, MakeWord(1, 0), wIndex, 0, '');
end;

procedure TPlayObject.ClientTakeOffPetSoulItem(nWhere, nMakeIndex: Integer; wIndex: word);
var
i, n18                              : Integer;
StdItem                               : pTStdItem;
UserItem                              : pTUserItem;
PetSoulItems                        : pTPetSoulItem;
label
FailExit;
begin
if m_boPneuma or m_boGhost or m_boDeath then Exit;

if not (wIndex in ) then Exit;

if (m_PetInfo.nMakeIndex <> m_SoulPetItemIndex) and ((m_PetInfo.nMakeIndex <> m_SoulPetItemIndex)) then begin
    n18 := -1;
    goto FailExit;
end;

PetSoulItems := GetPetSoulItem(m_SoulPetItemIndex, False);
if PetSoulItems = nil then begin
    n18 := -1;
    goto FailExit;
end;

n18 := 0;
if nWhere in then begin
    if PetSoulItems^.Items.wIndex > 0 then begin
      if PetSoulItems^.Items.MakeIndex = nMakeIndex then begin
      StdItem := UserEngine.GetStdItem(PetSoulItems^.Items.wIndex);
      if (StdItem <> nil) then begin
          New(UserItem);
          UserItem^ := PetSoulItems^.Items;
          if AddItemToBag(UserItem) then begin
            PetSoulItems.Items.wIndex := 0;
            SendAddItem(UserItem);
            SendDefMessage(SM_TAKEPETSOULITEM, 0, MakeWord(2, 1), wIndex, 0, '');

            RecalcPetSoulAbilitys;
            RecalcAbilitys();                                                                     //重新计算属性
            SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
            SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
            n18 := 1;
          end else begin
            Dispose(UserItem);
            n18 := -1;
          end;
      end;
      end;
    end;
end;

FailExit:
if n18 <= 0 then
    SendDefMessage(SM_TAKEPETSOULITEM, 0, MakeWord(2, 0), wIndex, 0, '');
end;

procedure TPlayObject.RecalcPerHealthSpell();
var
nPerReply                           : Integer;
begin
inherited RecalcPerHealthSpell();
nPerReply := m_nAllIncReply div 10;
Inc(m_nPerHealth, nPerReply);
Inc(m_nPerSpell, nPerReply);
end;

//兽化

procedure TPlayObject.ClientMagOfPetBeast(nMakeIndex: Integer);
var
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
i                                     : Integer;
btID, btLv                            : byte;
begin
if m_MagicSkills = nil then Exit;

//先判断 nMakeIndex 的合法性
StdItem := nil;
for i := 0 to m_ItemList.Count - 1 do begin                                                       //包裹里的物品
    UserItem := m_ItemList.Items;
    StdItem := nil;
    if (UserItem <> nil) and (UserItem.MakeIndex = nMakeIndex) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      Break;
    end;
end;

if (StdItem <> nil) and (UserItem <> nil) and
    (StdItem.StdMode = 49) and (StdItem.Shape = 51) and
    (UserItem.btItemExt in ) then begin

    if m_boBeast then begin
      m_boBeast := False;
      m_PetInfo.nMakeIndex := 0;
      m_PetInfo.wLevel := 0;
      m_PetInfo.btType := 0;
      m_PetInfo.btReLive := 0;

      UserItem.btItemExt := 2;
      SendUpdateItem(UserItem, False);

      SendDefMessage(SM_PETBAGSIZE, Integer(Self), 0, m_nPetShopSize, m_nPetBagSize, '');
      m_defMsg := MakeDefaultMsg(34977, 0, 100, 0, 0);
      SendSocket(@m_defMsg, EnCodeBuffer(@nMakeIndex, 4));

      SendRefMsg(RM_510, 1, 0, 171, 0, '');
      //SysMsg('附体魂佑灵兽已经收回到包裹中,魂佑附体状态解除!', c_Red, t_Hint);
    end else begin
      if (m_Pet <> nil) and (m_PetInfo.nMakeIndex <> 0) then begin
      m_boBeast := True;
      for i := 0 to 9 do begin
          btID := UserItem.btExtra.PetMagics.GetID();
          btLv := UserItem.btExtra.PetMagics.GetLv();
          if (btID in ) and (btLv > 0) then begin
            m_ReduceSkillLevel := btLv;
          end;
      end;
      UserItem.btItemExt := 3;
      SendUpdateItem(UserItem, False);
      SendRefMsg(RM_510, 1, 0, 170, 0, '');
      m_PetInfo := m_PetInfo;
      SendPetInfo($0A);

      m_nCharStatus := GetCharStatus();
      StatusChanged();

      g_SmallPacketManage.Init;
      g_SmallPacketManage.WriteWord(m_nCurrY);
      g_SmallPacketManage.WriteWord(m_Pet.m_nCurrX);
      g_SmallPacketManage.WriteWord(m_Pet.m_nCurrY);
      SendRefMsg(RM_PETBEAST, m_nCurrX, Integer(m_Pet), 0, 0, g_SmallPacketManage.GetMsg);
      //SysMsg('魂佑灵兽化为魂佑,附体于你!你感觉力量无穷!', c_Red, t_Hint);
      PetHide(m_PetInfo.nMakeIndex);
      end else begin
      SysMsg('需要魂佑灵兽处于跟随状态,才能使用兽化技能', c_Red, t_Hint);
      Exit;
      end;
    end;
    RecalcPetSoulAbilitys;
    RecalcAbilitys();                                                                               //重新计算属性
    SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
    SendMsg(Self, RM_SUBABILITY, 0, 0, 0, 0, '');
end;
end;

function TPlayObject.GetAchievementInfo(const wIndex: word): PTAchievementInfo;
var
pAchievementInfo                      : PTAchievementInfo;
i                                     : Integer;
begin
Result := nil;
pAchievementInfo := nil;
for i := 0 to m_AchievementList.Count - 1 do begin
    pAchievementInfo := PTAchievementInfo(m_AchievementList.Items);
    if (pAchievementInfo^.wIndex = wIndex) then begin
      Result := pAchievementInfo;
      Break;
    end;
end;
end;

procedure TPlayObject.SendWenPeiJH();                                                               //发送纹佩精华
begin
if m_dwWenPeiJH = 0 then Exit;
m_defMsg := MakeDefaultMsg(SM_WENPEIJH, Integer(Self), m_dwWenPeiJH, 0, 0);
SendSocket(@m_defMsg, '');
end;

{-------------------------------------------------------------------------------
过程名:    TPlayObject.ClientAchievementSystem
作者:      Cloud
日期:      2013.03.17
参数:      boWenPei 是否发送纹佩宝盒的列表给客户端
返回值:    无
-------------------------------------------------------------------------------}

procedure TPlayObject.ClientAchievementSystem(boWenPei: Boolean = False);                           //成就系统
var
AchievementSystem                     : TClientAchievementInfo;
pAchievementInfo                      : PTAchievementInfo;
i                                     : Integer;
sWenPeiBox                            : string;
XmlAchievement                        : PTXmlAchievement;
begin
if m_boPneuma then Exit;
if m_boGhost or m_boDeath then Exit;
if m_AchievementList.Count = 0 then Exit;

g_LargePacketManage.Init();                                                                     //从0位开始写
m_wAchievePoint := 0;
for i := 0 to m_AchievementList.Count - 1 do begin
    pAchievementInfo := PTAchievementInfo(m_AchievementList.Items);
    XmlAchievement := GetXmlAchievement(pAchievementInfo^.wIndex);
    if XmlAchievement = nil then
      Continue;

    if (pAchievementInfo^.tData > 0) then
      Inc(m_wAchievePoint);

    AchievementSystem.dwData := 0;
    if pAchievementInfo^.tData <> 0 then
      AchievementSystem.dwData := DateTimeToWolTIme(pAchievementInfo^.tData);

    AchievementSystem.wIndex := pAchievementInfo^.wIndex;
    AchievementSystem.wStep := pAchievementInfo^.wStep;
    AchievementSystem.btprize := XmlAchievement^.btprize;
    AchievementSystem.dwprizeValue := XmlAchievement^.dwprizeValue;
    g_LargePacketManage.WriteBuffer(AchievementSystem, SizeOf(TClientAchievementInfo));             //写入成就
end;

if boWenPei then begin
    sWenPeiBox := '';
    for i := Low(m_WenPeiBox) to High(m_WenPeiBox) do begin
      if m_WenPeiBox <> 0 then
      sWenPeiBox := sWenPeiBox + '|' + IntToStr(m_WenPeiBox)
      else
      Break;
    end;
    m_defMsg := MakeDefaultMsg(SM_WENPEIBOX, Integer(Self), Length(sWenPeiBox), m_wAchievePoint, 0);
    SendSocket(@m_defMsg, EnCodeString(sWenPeiBox));
end;

m_defMsg := MakeDefaultMsg(SM_ACHIEVEMENTLIST, 0, m_AchievementList.Count, 0, 0);
SendSocket(@m_defMsg, g_LargePacketManage.GetMsg());
end;

{-------------------------------------------------------------------------------
过程名:    TPlayObject.ClientMakeWenPei
作者:      Cloud
日期:      2013.03.17
参数:      btZW=主纹btJW=精纹 btDW=底纹 btBW=边纹
返回值:    无
-------------------------------------------------------------------------------}

procedure TPlayObject.ClientMakeWenPei(btZW, btJW, btDW, btBW: byte);
function DelWens(): Integer;
var
    i, j, ii                            : Integer;
    WenPei                              : array of byte;
    nWen                              : Integer;
    boHave                              : Boolean;
begin
    Result := -1;
    nWen := 0;
    for i := Low(m_WenPeiBox) to High(m_WenPeiBox) do begin
      if m_WenPeiBox <> 0 then
      nWen := i
      else
      Break;
    end;

    WenPei := btZW;
    WenPei := btJW;
    WenPei := btDW;
    WenPei := btBW;
    ii := 0;
    for i := 0 to 3 do begin
      boHave := False;
      for j := 0 to nWen do begin
      if m_WenPeiBox = WenPei then begin
          WenPei := j;
          Inc(ii);
          boHave := True;
          Break;
      end;
      end;
      if not boHave then begin
      Result := i + 1;
      Exit;
      end;
    end;
    if ii = 4 then begin
      for i := 0 to 3 do begin
      m_WenPeiBox] := 0;
      end;

      i := 0;
      for j := 0 to nWen do begin
      if m_WenPeiBox <> 0 then begin
          m_WenPeiBox := m_WenPeiBox;
          Inc(i);
      end;
      end;

      for i := nWen - 3 to nWen do begin
      m_WenPeiBox := 0;
      end;
      Result := 0;
    end;
end;
var
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
nResult                               : Integer;
sError                              : string;
begin
if m_boPneuma then Exit;
if m_boGhost or m_boDeath then Exit;
if (btZW = 0) or (btJW = 0) or (btDW = 0) or (btBW = 0) then
    Exit;
if (btZW > 255) or (btJW > 255) or (btDW > 255) or (btBW > 255) then
    Exit;
if m_ItemList.Count < m_nBagSize then begin
    nResult := DelWens();
    if nResult = 0 then begin
      New(UserItem);
      if UserEngine.CopyToUserItemFromName('三界纹佩', UserItem) then begin
      UserItem.btItemExt := 1;                                                               // 三界纹佩 必须绑定
      UserItem.btItemExt := btZW;                                                             // 主纹
      UserItem.btItemExt := btJW;                                                             // 精纹
      UserItem.btItemExt := btDW;                                                             // 底纹
      UserItem.btItemExt := btBW;                                                             // 边纹
      UserItem.btItemExt := 0;                                                                // 星级

      //主纹 加属性
      UserItem.btItemExt := g_Config.WenPeiList.btType;
      UserItem.btItemExt := g_Config.WenPeiList.btValue;
      Inc(UserItem.btItemExt, g_Config.WenPeiList.btAbsorb);
      //精纹加属性
      UserItem.btItemExt := g_Config.WenPeiList.btType;
      UserItem.btItemExt := g_Config.WenPeiList.btValue;
      Inc(UserItem.btItemExt, g_Config.WenPeiList.btAbsorb);
      //底纹加属性
      UserItem.btItemExt := g_Config.WenPeiList.btType;
      UserItem.btItemExt := g_Config.WenPeiList.btValue;
      Inc(UserItem.btItemExt, g_Config.WenPeiList.btAbsorb);
      //边纹加属性
      UserItem.btItemExt := g_Config.WenPeiList.btType;
      UserItem.btItemExt := g_Config.WenPeiList.btValue;
      Inc(UserItem.btItemExt, g_Config.WenPeiList.btAbsorb);

      UserItem.btItemExt := 0;                                                                // 五行强化的百分比
      UserItem.btItemExt := 0;                                                                // 强化后的五行吸收

      m_ItemList.Add((UserItem));
      SendAddItem(UserItem);
      WeightChanged();
      SendDefMessage(SM_TASKWEN, Integer(Self), btZW, 0, 0, '');                                  //通知客户端删除主纹
      SendDefMessage(SM_TASKWEN, Integer(Self), btJW, 0, 0, '');                                  //通知客户端删除精纹
      SendDefMessage(SM_TASKWEN, Integer(Self), btDW, 0, 0, '');                                  //通知客户端删除底纹
      SendDefMessage(SM_TASKWEN, Integer(Self), btBW, 0, 0, '');                                  //通知客户端删除边纹

      SendDefMessage(SM_MAKEWENPEI_SUCCESS, Integer(Self), MakeWord(btZW, btJW), MakeWord(btDW, btBW), 0, '');
      SendDefMessage(SM_INFORMATION, 0, 0, 0, 0, '合成成功,纹佩已经放入你的包裹中!');

      StdItem := UserEngine.GetStdItem(UserItem.wIndex);

      if StdItem.boGameLog = 1 then
          AddGameDataLog('9' + #9 +
            m_sMapName + #9 +
            IntToStr(m_nCurrX) + #9 +
            IntToStr(m_nCurrY) + #9 +
            m_sCharName + #9 +
            '三界纹佩' + #9 +
            IntToStr(UserItem.MakeIndex) + #9 +
            '1' + #9 +
            m_sCharName);

      end else begin
      Dispose(UserItem);
      SendDefMessage(SM_INFORMATION, 0, 0, 0, 0, '合成失败,三界纹佩不存在数据库!');
      end;
    end else begin
      case nResult of
      1: sError := '存在非法的纹佩组件(主纹)';
      2: sError := '存在非法的纹佩组件(精纹)';
      3: sError := '存在非法的纹佩组件(底纹)';
      4: sError := '存在非法的纹佩组件(边纹)';
      end;
      SendDefMessage(SM_INFORMATION, 0, 0, 0, 0, '合成失败,' + sError);
      SysMsg(sError, c_Red, t_Hint);
    end;
end else begin
    SendDefMessage(SM_INFORMATION, 0, 0, 0, 0, '合成失败,包裹必须要有一个空位!');
end;
end;

//取强化纹佩需要精化

function GetQFWenPeiDemandJF(const UserItem: pTUserItem): Integer;
begin
Result := 100;
if UserItem.btItemExt > 0 then
    Result := UserItem.btItemExt * 300;
end;

//取拆解纹佩需要灵力

function GetCJWenPeiDemandLL(const UserItem: pTUserItem): Integer;
var
eRate                                 : Single;
begin
Result := 0;
if UserItem.btItemExt > 0 then begin
    eRate := UserItem.btItemExt / 100;
    Inc(Result, Trunc(UserItem.btItemExt * eRate));
    Inc(Result, Trunc(UserItem.btItemExt * eRate));
    Inc(Result, Trunc(UserItem.btItemExt * eRate));
    Inc(Result, Trunc(UserItem.btItemExt * eRate));
    Inc(Result, Trunc(UserItem.btItemExt * (UserItem.btItemExt / 100)));
end;
end;

{-------------------------------------------------------------------------------
过程名:    TPlayObject.ClientGetWenPeiDemand//查询 强化 或 拆解纹佩 的需求
作者:      Cloud
日期:      2013.03.17
参数:      nMakeIndex=物品IndexnCode= 0强化 1拆解
返回值:    无
-------------------------------------------------------------------------------}

procedure TPlayObject.ClientGetWenPeiDemand(nMakeIndex, nCode: Integer);
var
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
nQF, nCJ                              : Integer;
begin
if m_boPneuma then Exit;
if m_boGhost or m_boDeath then Exit;
if nMakeIndex = 0 then Exit;
if GetUserItemByMakeIndex(nMakeIndex, UserItem) <> -1 then begin
    StdItem := UserEngine.GetStdItem(UserItem.wIndex);
    if StdItem.StdMode = 111 then begin
      nQF := 0;
      nCJ := 0;
      if (nCode = 0) then begin                                                                     //强化
      if UserItem.btItemExt >= 10 then begin
          nQF := 0;
      end else begin
          nQF := GetQFWenPeiDemandJF(UserItem);
      end;
      end;

      if (nCode = 1) then begin                                                                     //拆解
      nCJ := GetCJWenPeiDemandLL(UserItem);
      end;

      SendDefMessage(SM_GETWENPEI_DEMAND, Integer(Self), nQF, nCJ, nCode, '');
    end;
end else begin

end;
end;

{-------------------------------------------------------------------------------
过程名:    TPlayObject.ClientTakeWenPei强化 或 拆解 纹佩
作者:      Cloud
日期:      2013.03.17
参数:      nMakeIndex=物品IndexnCode= 0强化 1拆解
返回值:    无
-------------------------------------------------------------------------------}

procedure TPlayObject.ClientTakeWenPei(nMakeIndex, nCode: Integer);
var
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
i, ii, nQF, nCJ, nWen               : Integer;
eRate                                 : Single;
begin
if m_boPneuma then Exit;
if m_boGhost or m_boDeath then Exit;
if nMakeIndex = 0 then Exit;
if GetUserItemByMakeIndex(nMakeIndex, UserItem) <> -1 then begin
    StdItem := UserEngine.GetStdItem(UserItem.wIndex);
    if StdItem.StdMode = 111 then begin
      nQF := 0;
      nCJ := 0;
      if nCode = 0 then begin                                                                     //强化
      if UserItem.btItemExt < 10 then begin
          nQF := GetQFWenPeiDemandJF(UserItem);
          if m_dwWenPeiJH >= nQF then begin
            if nQF > 0 then begin
            Dec(m_dwWenPeiJH, nQF);
            SendWenPeiJH();
            end;
            SendDefMessage(SM_INFORMATION, 0, 0, 0, 0, '您的纹佩强化成功!');
            Inc(UserItem.btItemExt, 1);
            case UserItem.btItemExt of
            01: UserItem.btItemExt := 10;
            02: UserItem.btItemExt := 20;
            03: UserItem.btItemExt := 30;
            04: UserItem.btItemExt := 50;
            05: UserItem.btItemExt := 70;
            06: UserItem.btItemExt := 90;
            07: UserItem.btItemExt := 110;
            08: UserItem.btItemExt := 140;
            09: UserItem.btItemExt := 170;
            10: UserItem.btItemExt := 200;
            end;
            UserItem.btItemExt := Trunc(UserItem.btItemExt * 1.4);
            SendUpdateItem(UserItem);
            ClientGetWenPeiDemand(nMakeIndex, 0);
          end else begin
            SendDefMessage(SM_INFORMATION, 0, 0, 0, 0, '您的纹佩精华不足!');
          end;
      end else begin
          SendDefMessage(SM_INFORMATION, 0, 0, 0, 0, '您的纹佩以达到强化最大等级!');
      end;
      end else if nCode = 1 then begin                                                            //拆解
      nCJ := GetCJWenPeiDemandLL(UserItem);
      if m_Abil.wNimBusPoint >= nCJ then begin
          nWen := -1;
          for i := Low(m_WenPeiBox) to High(m_WenPeiBox) do begin
            if m_WenPeiBox = 0 then begin
            nWen := i;
            Break;
            end;
          end;
          if (nWen <> -1) and ((nWen + 3) <= 99) then begin
            if nCJ > 0 then begin
            Dec(m_Abil.wNimBusPoint, nCJ);
            RecalcAbilitys();
            SendMsg(Self, RM_ABILITY, 0, 0, 0, 0, '');
            end;
            nQF := 0;
            if UserItem.btItemExt > 0 then begin
            nQF := 100;
            for i := 1 to UserItem.btItemExt - 1 do
                nQF := nQF + i * 300;
            end;
            Inc(m_dwWenPeiJH, nQF);
            SendWenPeiJH();
            ii := 16;
            for i := nWen to nWen + 3 do begin
            m_WenPeiBox := UserItem^.btItemExt;
            Inc(ii);
            SendDefMessage(SM_TASKWEN, Integer(Self), MakeWord(m_WenPeiBox, 1), 0, 0, '');
            end;

            SendDelItems(UserItem);
            DelBagItem(UserItem^.MakeIndex, '');

            SendDefMessage(SM_ACHIEVEMENT__OK, Integer(Self), 0, 0, 0, '');
            SendDefMessage(SM_INFORMATION, 0, 0, 0, 0, '拆卸成功,纹佩部件和纹佩精华已放回纹佩宝盒!');
          end else begin
            SendDefMessage(SM_ACHIEVEMENT__OK, Integer(Self), 0, 1, 0, '');
          end;
      end else begin
          SendDefMessage(SM_INFORMATION, 0, 0, 0, 0, '您的灵力值不够!');
          SendDefMessage(SM_ACHIEVEMENT__OK, Integer(Self), 0, 1, 0, '');
      end;

      end;
    end;
end else begin

end;
end;

{-------------------------------------------------------------------------------
过程名:    TPlayObject.ClientCollectSuits成就之收集套装
作者:      Cloud
日期:      2013.03.17
参数:      nCJIdx = 要做的套装成就nCount=套装组件数量sData 选择的套装组件索引
返回值:    无
-------------------------------------------------------------------------------}

procedure TPlayObject.ClientCollectSuits(nCJIdx, nCount: Integer; sData: string);
var
UserItem                              : pTUserItem;
nMakeIndexs                           : array of DWORD;
i                                     : Integer;
boFail                              : Boolean;
begin
if m_boPneuma then Exit;
if m_boGhost or m_boDeath then Exit;
if nCJIdx = 0 then Exit;
if (nCount = 0) or (nCount > 8) then Exit;
if (sData = '') then Exit;

if GetXmlAchievement(nCJIdx) = nil then Exit;

FillChar(nMakeIndexs, SizeOf(DWORD) * 8, 0);
DeCodeBuffer(sData, @nMakeIndexs, SizeOf(Integer) * nCount);
boFail := False;

if GetAchievementInfo(nCJIdx) = nil then begin
    for i := 0 to nCount - 1 do begin
      if GetUserItemByMakeIndex(nMakeIndexs, UserItem) = -1 then begin
      boFail := True;
      Break;
      end;
    end;
end else begin
    boFail := True;
end;

if not boFail then begin
    m_sScriptParam := IntToStr(nCount);
    for i := 0 to 7 do
      m_sScriptParam := IntToStr(nMakeIndexs);
    ExecuteScript(g_FunctionNPC, '@套装成就' + IntToStr(nCJIdx));

    //如果物品还存在,也是失败
    if GetUserItemByMakeIndex(nMakeIndexs, UserItem) <> -1 then begin
      boFail := True;
    end;
end;
SendDefMessage(SM_ACHIEVEMENT__OK, Integer(Self), 1, Integer(boFail), 0, '');
end;

procedure TPlayObject.SendPetAttribute(PlayObject: TPlayObject; btWhere: byte; UserItem: pTUserItem); //发送灵兽石附加属性
begin
if Assigned(m_VersionManage) then
try
    m_VersionManage.OnSendPetAttribute(Self, PlayObject, btWhere, UserItem);
except
    MainOutMessage(Format('TPlayObject::OnSendPetAttribute SoftVersionDate:%d', ));
end;
end;

procedure TPlayObject.SendBagItemsPetInfo();
var
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
i, n15, n16                           : Integer;
RidePetInfo                           : TRidePetInfo;
SoulPetInfoAdd                        : TSoulPetInfoAdd;
SoulPetInfo                           : TSoulPetInfo;
begin
n15 := 0;
n16 := 0;
g_SmallPacketManage.Init;
g_PacketManage3.Init;
for i := 0 to m_ItemList.Count - 1 do begin
    UserItem := m_ItemList.Items;
    StdItem := UserEngine.GetStdItem(UserItem.wIndex);
    if StdItem <> nil then begin
      if (StdItem.StdMode = 49) and (StdItem.Shape = 51) then begin
      RidePetInfo := UserItem.GetRidePetInfo;
      RidePetInfo.btRace := MakeByte(UserItem.btValue, StdItem.AniCount);

      //3转灵兽
      if (UserItem.btValue > 2) then begin
          SoulPetInfoAdd := UserItem.GetSoulPetInfoAdd;
          SoulPetInfoAdd.btRace := RidePetInfo.btRace;
          SoulPetInfo := UserItem.GetSoulPetInfo;
          //写入三转灵兽属性
          g_PacketManage3.WriteBuffer(SoulPetInfoAdd, SizeOf(TSoulPetInfoAdd));
          //在写一遍魂佑信息
          g_PacketManage3.WriteBuffer(SoulPetInfo, SizeOf(TSoulPetInfo));
          //技能信息,填0就可以了
          g_PacketManage3.FillWrite(64, 0);
          Inc(n15);
      end else begin
          g_SmallPacketManage.WriteBuffer(RidePetInfo, SizeOf(TRidePetInfo));
          Inc(n16);
      end;
      end;
    end;
end;

for i := 0 to m_PetItemList.Count - 1 do begin
    UserItem := m_PetItemList.Items;
    StdItem := UserEngine.GetStdItem(UserItem.wIndex);
    if StdItem <> nil then begin
      if (StdItem.StdMode = 49) and (StdItem.Shape = 51) then begin
      RidePetInfo := UserItem.GetRidePetInfo;
      RidePetInfo.btRace := MakeByte(UserItem.btValue, StdItem.AniCount);

      //3转灵兽
      if (UserItem.btValue > 2) then begin
          SoulPetInfoAdd := UserItem.GetSoulPetInfoAdd;
          SoulPetInfoAdd.btRace := RidePetInfo.btRace;
          SoulPetInfo := UserItem.GetSoulPetInfo;
          //写入三转灵兽属性
          g_PacketManage3.WriteBuffer(SoulPetInfoAdd, SizeOf(TSoulPetInfoAdd));
          //在写一遍魂佑信息
          g_PacketManage3.WriteBuffer(SoulPetInfo, SizeOf(TSoulPetInfo));
          //技能信息,填0就可以了
          g_PacketManage3.FillWrite(64, 0);
          Inc(n15);
      end else begin
          g_SmallPacketManage.WriteBuffer(RidePetInfo, SizeOf(TRidePetInfo));
          Inc(n16);
      end;
      end;
    end;

end;

if (n16 > 0) or (n15 > 0) then begin
    g_SmallPacketManage.WriteInteger($007A2626);
    g_SmallPacketManage.WriteWord(n15);                                                             //数量
    g_SmallPacketManage.WriteBuffer(g_PacketManage3.Memory^, g_PacketManage3.Position);

    m_defMsg := MakeDefaultMsg(SM_RIDEPETINFO, Integer(Self), 24, 0, n16);
    SendSocket(@m_defMsg, g_SmallPacketManage.GetMsg());
end;
end;

function TPlayObject.TrainingPetSkill(const StdItem: pTStdItem): Boolean;
var
i, btPos                              : Integer;
btID, btLv                            : byte;
UserItem                              : pTUserItem;
//StdItemA                         : pTStdItem;
boFound                               : Boolean;
begin
Result := False;
boFound := False;
if (m_Pet <> nil) then begin
    for i := 0 to m_ItemList.Count - 1 do begin
      UserItem := m_ItemList;
      if UserItem.MakeIndex = m_PetInfo.nMakeIndex then begin
      boFound := True;
      Break;
      end;
    end;
end;

if (not boFound) or (UserItem.btItemExt < 2) then begin
    SysMsg('请放出一只魂佑灵兽并使之处于跟随状态', c_Red, t_Hint);
    Exit;
end;

if (UserItem.wLevel < StdItem.NeedLevel) then begin
    SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, '灵兽等级不够');
    Exit;
end;

//$PETMAGIC(X)
btPos := -1;
for i := 9 downto 0 do begin
    btID := UserItem.btExtra.PetMagics.GetID();
    btLv := UserItem.btExtra.PetMagics.GetLv();
    if (btLv > 0) then begin
      if (btID = LoWord(StdItem.AC)) then begin
      btPos := -2;
      Break;
      end;
    end else
      btPos := i;
end;

case btPos of
    -1: begin
      SysMsg('已经没有技能空位来学习新技能了,请清空技能格后再来学习', c_Red, t_Hint);
      Exit;
      end;
    -2: begin
      SendMsg(g_ManageNPC, RM_MENU_OK, 0, Integer(Self), 0, 0, '该灵兽已经习得这个技能。');
      Exit;
      end;
else begin
      Result := True;
      btID := LoWord(StdItem.AC);
      btLv := StdItem.DuraMax + 1;
      if (btPos in ) and (btLv in ) then begin
      UserItem.btExtra.PetMagics.SetInfo(btID, btLv);
      m_defMsg := MakeDefaultMsg(SM_COMPREHENDSKILL, Integer(Self), LoWord(UserItem.MakeIndex), HiWord(UserItem.MakeIndex), MakeWord(btLv, btID));
      SendSocket(@m_defMsg, EnCodeBuffer(@btPos, 1));
      end;
    end;
end;
end;

procedure TPlayObject.SendStruckMsg(wIdent: word; BaseObject, Attacker: TBaseObject; nDamage: Integer; wEffect: word);
begin
if g_Config.boDisableSelfStruck and (BaseObject = Self) then Exit;

g_SmallPacketManage.Init;

//发送心魔、人类 攻击值
{$IF DEMONSERVER = 1}
if (BaseObject.m_btRaceServer = RC_PLAYOBJECT) and (m_btDemonMode > 0) then begin
    g_PacketManage3.Init;
    g_PacketManage3.WriteByte(1);
    g_PacketManage3.WriteByte(m_btDemonForce);
    g_PacketManage3.WriteInteger(Integer(Self));
    g_PacketManage3.WriteInteger(0);
    SendRefMsg(RM_DEMONHIT, 0, Integer(Self), 0, 0, g_PacketManage3.GetMsg);
    if (m_btDemonForce = 0) then begin
      m_sScriptParam := IntToStr(m_btDemonMode);
      m_btDemonMode := 0;
      ExecuteScript(g_FunctionNPC, '@_心魔_人类心魔被杀');
    end;
end;
{$IFEND}
if (BaseObject <> nil) and (not BaseObject.m_boDeath) then begin
    g_SmallPacketManage.WriteInteger(BaseObject.GetFeature(nil));
    g_SmallPacketManage.WriteInteger(BaseObject.m_nCharStatus);
    g_SmallPacketManage.WriteInteger(Integer(Attacker));
    //人被攻击
    if (BaseObject.m_btRaceServer = RC_PLAYOBJECT) then begin
      if wIdent = RM_STRUCK_NEWMAG1 then begin
      g_SmallPacketManage.WriteInteger(MakeLong(0, wEffect));
      if (BaseObject = Self) then begin
          m_defMsg := MakeDefaultMsg(SM_47,
            Integer(BaseObject),
            BaseObject.m_WAbil.dwHP,
            BaseObject.m_WAbil.dwMaxHP,
            nDamage);

          g_SmallPacketManage.WriteWord(BaseObject.m_WAbil.wElementForce);                        //自己被攻击才会发送元力的信息
          g_SmallPacketManage.WriteWord(BaseObject.m_WAbil.wElementForceMax);
          g_SmallPacketManage.WriteByte(02);
          g_SmallPacketManage.WriteInteger(BaseObject.m_WAbil.dwHP);
          g_SmallPacketManage.WriteInteger(BaseObject.m_WAbil.dwMaxHP);
      end else begin
          m_defMsg := MakeDefaultMsg(SM_47,
            Integer(BaseObject),
            CalcCent(BaseObject.m_WAbil.dwHP, BaseObject.m_WAbil.dwMaxHP),
            CalcCent(BaseObject.m_WAbil.wElementForce, BaseObject.m_WAbil.wElementForceMax),
            nDamage);

          g_SmallPacketManage.WriteByte(02);
          g_SmallPacketManage.WriteInteger(0);
          g_SmallPacketManage.WriteInteger(0);
      end;
      end else begin
      //人被攻击 会带有时间参数
      g_SmallPacketManage.WriteInteger(DateTimeToWolTIme(Now));
      if (BaseObject = Self) then begin
          m_defMsg := MakeDefaultMsg(SM_STRUCK,
            Integer(BaseObject),                                                                  //被攻击者
            BaseObject.m_WAbil.dwHP,
            BaseObject.m_WAbil.dwMaxHP,
            nDamage);

          g_SmallPacketManage.WriteWord(BaseObject.m_WAbil.wElementForce);                        //自己被攻击才会发送元力的信息
          g_SmallPacketManage.WriteWord(BaseObject.m_WAbil.wElementForceMax);
          g_SmallPacketManage.WriteInteger(BaseObject.m_WAbil.dwHP);
          g_SmallPacketManage.WriteInteger(BaseObject.m_WAbil.dwMaxHP);
      end else begin
          m_defMsg := MakeDefaultMsg(SM_STRUCK,
            Integer(BaseObject),                                                                  //被攻击者
            CalcCent(BaseObject.m_WAbil.dwHP, BaseObject.m_WAbil.dwMaxHP),
            CalcCent(BaseObject.m_WAbil.wElementForce, BaseObject.m_WAbil.wElementForceMax),
            nDamage);

          g_SmallPacketManage.WriteInteger(0);
          g_SmallPacketManage.WriteInteger(0);
      end;
      end;
    end else begin
      if wIdent = RM_STRUCK_NEWMAG1 then begin
      m_defMsg := MakeDefaultMsg(SM_47,
          Integer(BaseObject),
          CalcCent(BaseObject.m_WAbil.dwHP, BaseObject.m_WAbil.dwMaxHP),
          BaseObject.m_wMaxHPCent,
          nDamage);

      g_SmallPacketManage.WriteInteger(MakeLong(0, wEffect));
      g_SmallPacketManage.WriteInteger(0);
      g_SmallPacketManage.WriteByte(0);
      if BaseObject.m_WAbil.dwMaxHP > High(word) then begin
          g_SmallPacketManage.WriteInteger(BaseObject.m_WAbil.dwHP);
          g_SmallPacketManage.WriteInteger(BaseObject.m_WAbil.dwMaxHP);
      end else begin
          g_SmallPacketManage.WriteInteger(CalcCent(BaseObject.m_WAbil.dwHP, BaseObject.m_WAbil.dwMaxHP));
          g_SmallPacketManage.WriteInteger($64);
      end;
      end else begin
      m_defMsg := MakeDefaultMsg(SM_STRUCK,
          Integer(BaseObject),                                                                      //被攻击者
          CalcCent(BaseObject.m_WAbil.dwHP, BaseObject.m_WAbil.dwMaxHP),
          BaseObject.m_wMaxHPCent,
          nDamage);
      g_SmallPacketManage.WriteInteger(0);
      if BaseObject.m_WAbil.dwMaxHP > High(word) then begin
          g_SmallPacketManage.WriteInteger(BaseObject.m_WAbil.dwHP);
          g_SmallPacketManage.WriteInteger(BaseObject.m_WAbil.dwMaxHP);
      end else begin
          g_SmallPacketManage.WriteInteger(CalcCent(BaseObject.m_WAbil.dwHP, BaseObject.m_WAbil.dwMaxHP));
          g_SmallPacketManage.WriteInteger($64);
      end;
      end;
    end;

    g_SmallPacketManage.WriteInteger(0);
    g_SmallPacketManage.WriteInteger(0);
    SendSocket(@m_defMsg, g_SmallPacketManage.GetMsg);
end;
end;

procedure TPlayObject.OnEnvirnomentChanged(OldEnvir: TEnvirnoment; boChanged: Boolean = True);
begin
inherited OnEnvirnomentChanged(OldEnvir, boChanged);
if boChanged then begin
    if (m_Pet <> nil) and (m_PetInfo.btType in ) and (not m_PEnvir.m_MapFlag.boCanRideShark) then begin //鲨鱼在普通地图不能出现
      PetHide(m_PetInfo.nMakeIndex);
    end;

    if (m_Tiger <> nil) and m_PEnvir.m_MapFlag.boNOTIGER then begin
      ClientReCallTiger;
    end;

    //心魔控制面板
    if (m_nEvilFollowerPower > 0) then begin
      ClientQueryEvilFollower;
    end;

    m_sTimerLabel := '';
    m_dwTimerLong := 0;
    m_sMapNewDesc := '';

    if (OldEnvir <> nil) then
      m_sScriptParam := OldEnvir.m_sMapName
    else
      m_sScriptParam := '';

    ExecuteScript(g_FunctionNPC, '@地图变更');
end;
end;

//升级灵兽装备

procedure TPlayObject.ClientPetEquipUp(nPetItemIdx, nStoreItemIdx: Integer; sData: string);
var
nGemItemIdx                           : array of Integer;
begin
if (nPetItemIdx = 0) or (nStoreItemIdx = 0) then Exit;
if (sData = '') then Exit;
FillChar(nGemItemIdx, SizeOf(Integer) * 2, 0);
DeCodeBuffer(sData, @nGemItemIdx, SizeOf(Integer) * 2);

m_sScriptParam := IntToStr(nPetItemIdx);
m_sScriptParam := IntToStr(nStoreItemIdx);
m_sScriptParam := IntToStr(nGemItemIdx);
m_sScriptParam := IntToStr(nGemItemIdx);

if m_ClickNPC <> nil then
    TNormNpc(m_ClickNPC).GotoLable(Self, '@@PetEquipUp', False);
end;

procedure TPlayObject.SlaveTransferDamage(var nDamage: Integer);
var
i, nTransfer, nObjCount               : Integer;
BaseObject                            : TBaseObject;
begin
for i := 0 to m_SlaveList.Count - 1 do begin
    BaseObject := m_SlaveList;
    if BaseObject.m_boIsGodCallBoss or BaseObject.m_boScapeGoat or BaseObject.m_boIsPet or
      BaseObject.m_boGodCallBoss or (BaseObject.m_btRaceServer in ) or (BaseObject.m_boStickMode) or
      (BaseObject.m_btRaceServer in ) then
      Continue;

    if CretInNear10XY(BaseObject, m_nCurrX, m_nCurrY) then begin
      nObjCount := Integer(Self);
      BaseObject.SendRefMsg(RM_510, HiWord(nObjCount), LoWord(nObjCount), 104, 0, '');
      nTransfer := Round(nDamage * (_MIN(m_WAbil.btShiftDamage, 90)) / 100);
      Dec(nDamage, nTransfer);
      if nTransfer > 0 then begin
      BaseObject.StruckDamage(nTransfer);
      BaseObject.SendRefMsg(RM_STRUCK, 0, nTransfer, 0, Integer(Self), '');
      end;
    end;
    Break;
end;
end;

procedure TPlayObject.BaoBaoTransferDamage(var nDamage: Integer);                                 //道神符印斗转
var
i, nTransfer, nObjCount               : Integer;
BaseObject                            : TBaseObject;
begin
for i := 0 to m_SlaveList.Count - 1 do begin
    BaseObject := m_SlaveList;
    if (not BaseObject.m_boProBaoBao) then
      Continue;
    if CretInNear10XY(BaseObject, m_nCurrX, m_nCurrY) then begin
      nObjCount := Integer(Self);
      BaseObject.SendRefMsg(RM_510, HiWord(nObjCount), LoWord(nObjCount), 104, 0, '');
      nTransfer := Round(nDamage * (_MIN(g_Config.nDouZhuanDamagePercent, 90)) / 100);
      Dec(nDamage, nTransfer);
      if nTransfer > 0 then begin
      BaseObject.StruckDamage(nTransfer);
      BaseObject.SendRefMsg(RM_STRUCK, 0, nTransfer, 0, Integer(Self), '');
      end;
    end;
    Break;
end;
end;

//化身蝙蝠、遁地、移行换影

function TPlayObject.MagDoBatfly(UserMagic: pTUserMagic; nTargetX, nTargetY: Integer): Boolean;
var
FlyData                               : TShunyiData;
s1C, sName                            : string;
nPower, nMagID, nSecPwr, n20          : Integer;
nOldX, nOldY                        : Integer;
i, nDir, nX, nY, nRage                : Integer;
nFireTime                           : Integer;
nBatflyRate, nBatflyMaxRage         : Integer;
Event                                 : TEvent;
BaseObjectList                        : TList;
BaseObject                            : TBaseObject;
bo18, boCanHit                        : Boolean;
begin
Result := False;
bo18 := False;
boCanHit := m_PEnvir.CanWalk(nTargetX, nTargetY, False);
//if (GetTickCount - UserMagic.nTranPoint) < UserMagic.MagicInfo.dwCoolDownTime then begin
//    SysMsg(format('无法连续使用该技能,请%d秒后再使用。', [(UserMagic.MagicInfo.dwCoolDownTime - (GetTickCount - UserMagic.nTranPoint)) div 1000]), c_Red, t_Hint);
//    Exit;
//end;
//UserMagic.nTranPoint := GetTickCount;            //保存技能的使用时间
if not boCanHit then begin
    //先获取首要方向
    nDir := GetNextDirection(nTargetX, nTargetY, m_nCurrX, m_nCurrY);
    while True do begin
      if m_PEnvir.GetNextPosition(nTargetX, nTargetY, nDir, 1, nX, nY) then begin
      boCanHit := m_PEnvir.CanWalk(nX, nY, False);
      end;
      if boCanHit or (nDir >= 7) then Break;

      //如果没有找到位置,就换个方向
      if not bo18 then begin
      nDir := 0;
      bo18 := True;
      end else
      Inc(nDir);
    end;
end else begin
    nX := nTargetX;
    nY := nTargetY;
end;

//技能参数
if g_Config.boUseXMLMagicSkill then begin
    nBatflyRate := g_MagicSkill.btLv.btVal;
    nBatflyMaxRage := g_MagicSkill.btLv.btVal;
end else begin
    nBatflyRate := UserMagic.btLevel + 1;
    nBatflyMaxRage := g_Config.nBatflyMaxRage;
end;

if (m_wStatusTimeArr <> 0) then begin
    SysMsg('被冰冻无法使用瞬移技能。', c_Red, t_Hint);
end else if m_PEnvir.m_MapFlag.boNoBatfly then begin
    SysMsg('此地图禁止使用瞬移技能。', c_Red, t_Hint);
end else if m_boArrow then begin
    SysMsg('你正在执行抢宝任务,禁止使用瞬移技能。', c_Red, t_Hint);
end else if (not boCanHit) or
    (abs(nTargetX - m_nCurrX) > nBatflyMaxRage) or (abs(nTargetY - m_nCurrY) > nBatflyMaxRage) then begin
    SysMsg('此点不能到达', c_Red, t_Hint);
end else if InWarSnareZone(m_PEnvir, m_nCurrX, m_nCurrY) and (not g_EventManager.InWarSnareZone(m_PEnvir, nTargetX, nTargetY)) then begin
    SysMsg('你已被战争牢笼困住,无法逃脱!', c_Red, t_Hint);
end else begin
    //检测下附近有没有人在使用战争旋风
    if not g_Config.boAntiWarWhirlWind then begin
      BaseObjectList := TList.Create;
      try
      GetMapBaseObjects(m_PEnvir, m_nCurrX, m_nCurrY, 3, BaseObjectList);
      for i := 0 to BaseObjectList.Count - 1 do begin
          BaseObject := TBaseObject(BaseObjectList.Items);
          if (BaseObject.m_btRaceServer <> RC_PLAYOBJECT) then Continue;
          if (BaseObject.m_wStatusTimeArr > 0) and (BaseObject.IsProperTarget(Self)) then begin
            SysMsg('因为中了战争旋风,此技能被限制', c_Red, t_Hint);
            Exit;
          end;
      end;
      finally
      BaseObjectList.free;
      end;
    end;

    if (Random(g_Config.nBatflyRate) < nBatflyRate) and
      (m_PEnvir.DeleteFromMap(m_nCurrX, m_nCurrY, OS_MOVINGOBJECT, Self) > 0) then begin
      m_btDirection := GetNextDirection(m_nCurrX, m_nCurrY, nX, nY);
      nOldX := m_nCurrX;
      nOldY := m_nCurrY;
      m_nCurrX := nX;
      m_nCurrY := nY;
      m_PEnvir.AddToMap(m_nCurrX, m_nCurrY, OS_MOVINGOBJECT, Self);
      RunStepToDamage(_Max(abs(nOldX - m_nCurrX), abs(nOldY - m_nCurrY)));
      Result := True;
    end;

    if Result then begin
      FlyData.CharDesc.Feature := GetFeatureToLong(Self);
      FlyData.CharDesc.Status := m_nCharStatus;
      FlyData.CharDesc.Featurex := GetMaxHPCent(Self);
      FlyData.nX := nOldX;
      FlyData.nY := nOldY;
      FlyData.wKnow := $01FF;
      FlyData.MagCode := UserMagic.GetMagIdx;
      sName := GetShowName;
      g_SmallPacketManage.Init;
      g_SmallPacketManage.WriteBuffer(FlyData, SizeOf(TShunyiData));
      g_SmallPacketManage.WriteBuffer(sName, Length(sName));
      g_SmallPacketManage.FillWrite(27, 0);
      s1C := g_SmallPacketManage.GetMsg;
      n20 := 0;
      if UserMagic.btLevel > 3 then n20 := $0A;
      SendRefMsg(RM_170, MakeWord(m_btDirection, n20 or m_btGender), m_nCurrX, m_nCurrY, 0, s1C);

      if (m_btRaceServer = RC_PLAYOBJECT) and m_boRideFightOn then begin
      case UserMagic.GetMagIdx of
          SKILL_WINDTEBO: begin
            //火蝙蝠
            if (m_MagicSkills <> nil) and (m_MagicSkills.btKey = 1) and (m_MagicSkills <> nil) then begin
                n20 := m_PetInfo.wLevel + m_MagicSkills.btLevel + m_MagicSkills.btLevel + UserMagic.btLevel;
                if (Random(g_Config.nMagBatFireRate) < n20) then begin
                  //获得火蝙蝠的威力
                  nPower := GetAttackPower(GetPower(MPow(m_MagicSkills), m_MagicSkills) + loword(m_WAbil.MC), SmallInt(hiword(m_WAbil.MC) - loword(m_WAbil.MC)) + 1, SKILL_BATFIRE);
                  nSecPwr := Trunc(nPower * n20 / 500);
                  Inc(nPower, nSecPwr);
                  //控制时间
                  nFireTime := GetPower(10, UserMagic) + (word(GetRPow(m_WAbil.MC)) shr 1);
                  if g_Config.boUseFireDelayTime and (g_Config.nFireDelayTime > 0) then nFireTime := _MIN(nFireTime, g_Config.nFireDelayTime);
                  //最长距离
                  nRage := _Max(abs(nOldX - m_nCurrX), abs(nOldY - m_nCurrY));
                  //从原始坐标到目标坐标
                  nDir := GetNextDirection(nOldX, nOldY, m_nCurrX, m_nCurrY);
                  nX := nOldX;
                  nY := nOldY;
                  for i := 1 to nRage do begin
                  Event := TEvent(m_PEnvir.GetEvent(nX, nY));
                  //清除火墙和流星火雨
                  if (Event <> nil) and (Event.m_nEventType in ) then begin
                      Event.m_boClosed := True;
                      Event.Close;
                      Event := nil;
                  end;

                  if Event = nil then begin
                      SendDelayMsg(Self, RM_DELAYFIREBURN, ET_BATFIRE, MakeLong(nX, nY), nFireTime * 1000, nPower, '', 100);
                  end;

                  if not ((abs(nX - m_nCurrX) <= 0) and (abs(nY - m_nCurrY) <= 0)) then begin
                      nDir := GetNextDirection(nX, nY, m_nCurrX, m_nCurrY);
                      if not m_PEnvir.GetNextPosition(nX, nY, nDir, 1, nX, nY) then
                        Break;
                  end else
                      Break;
                  end;
                end;
            end;
            end;
          SKILL_75: ;
          SKILL_77: begin
            if (m_MagicSkills <> nil) then nMagID := SKILL_BANWOL else nMagID := SKILL_43;

            if (m_MagicSkills <> nil) and (m_MagicSkills.btKey = 1) and (m_MagicSkills <> nil) then begin
                //影袭杀
                n20 := m_PetInfo.wLevel + m_MagicSkills.btLevel + m_MagicSkills.btLevel + UserMagic.btLevel;
                if (Random(g_Config.nMagShadowKillRate) < n20) then begin
                  SendAttackMsg(RM_WIDEHIT, $1800 or m_btDirection, m_nCurrX, m_nCurrY);
                  nPower := GetAttackPower(GetPower(MPow(UserMagic), UserMagic) + loword(m_WAbil.DC), SmallInt(hiword(m_WAbil.DC) - loword(m_WAbil.DC)) + 1, SKILL_SHADOWKILL);
                  nSecPwr := Trunc(nPower * n20 / 500);
                  Inc(nPower, nSecPwr);
                  MagicManager.MagBigExplosion(Self, nPower, m_nCurrX, m_nCurrY, 1);
                end;
            end;
            end;
      end;
      end;
    end else begin
      case UserMagic.GetMagIdx of
      SKILL_WINDTEBO: SysMsg('化身蝙蝠失败', c_Red, t_Hint);
      SKILL_75: SysMsg('使用遁地失败', c_Red, t_Hint);
      SKILL_77: SysMsg('移形换影失败', c_Red, t_Hint);

      end;
      Result := False;
    end;
end;
end;

function TPlayObject.CheckEatItems(StdItem: pTStdItem): Boolean;
var
n, i                                  : Integer;
begin
Result := False;
n := 0;
i := 0;
case StdItem.Need of
    0: Result := True;
    1: begin;                                                                                       //需要等级
      if (StdItem.NeedLevel > 71) then begin
          n := Ceil((StdItem.NeedLevel - 71) / 99);
          i := (StdItem.NeedLevel - 71) - 99 * (n - 1);

          if ((Ceil(m_btAmbitKind / 2) - 1) > n) or (((Ceil(m_btAmbitKind / 2) - 1) = n) and (m_btAmbitLevel >= i)) then begin
            Result := True;
          end;
      end else begin
          if m_Abil.level >= StdItem.NeedLevel then begin
            Result := True;
          end;
      end;
      end;
    2: begin;                                                                                       //需要勋爵等级
      if m_wCentsOfficerLevel > StdItem.NeedLevel then begin
          Result := True;
      end;
      end;
end;
end;

procedure TPlayObject.ClientPerfectStoreMoveHome(nParam1: Integer; nMapIdx: Integer);
const
mapName                               : array of string = ('0', '1', '4', '7', '2', '5', 'haidi', 'zqd');
HomeX                                 : array of Integer = (474, 229, 350, 54, 223, 462, 157, 156);
HomeY                                 : array of Integer = (222, 241, 165, 41, 448, 107, 182, 118);
mapName1                              : array of string = ('0', '0', '4', '7', '2', '5', '1');
HomeX1                              : array of Integer = (474, 0, 350, 54, 223, 462, 229);
HomeY1                              : array of Integer = (222, 0, 165, 41, 448, 107, 241);
var
i, j                                  : Integer;
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
begin
if (m_wShopItemCount > 0) or m_boArrow then Exit;                                                 //禁止使用回城石的条件
if (GetTickCount - m_dwUseStoreTick) < 10000 then begin
    SysMsg('每隔10秒才允许使用回城石一次。', c_Red, t_Hint);
    Exit;
end;

if m_PEnvir.m_MapFlag.boNOSTOREMOVE then begin
    SysMsg('当前地图禁止使用回城石。', c_Red, t_Hint);
    Exit;
end;

if (nMapIdx < 0) or (nMapIdx > 7) then Exit;
for i := 0 to m_ItemList.Count - 1 do begin
    UserItem := pTUserItem(m_ItemList);
    if UserItem.MakeIndex = nParam1 then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if (StdItem.StdMode = 3) and ((StdItem.Shape = 15) or (StdItem.Shape = 17)) then begin
      if not (g_Config.boClassicServer) then begin
          m_sScriptParam := m_PEnvir.m_sMapName;
          m_sScriptParam := mapName1;
          SendRefMsg(RM_SPACEMOVE_FIRE, 0, 0, 0, 0, '');
          SpaceMove(mapName1, HomeX1 + Random(8) - 4, HomeY1 + Random(8) - 4, 0, nil);
      end else begin
          m_sScriptParam := m_PEnvir.m_sMapName;
          m_sScriptParam := mapName;
          SendRefMsg(RM_SPACEMOVE_FIRE, 0, 0, 0, 0, '');
          SpaceMove(mapName, HomeX + Random(8) - 4, HomeY + Random(8) - 4, 0, nil);
      end;
      m_dwUseStoreTick := GetTickCount;
      SendRefMsg(RM_510, 1, 0, 29, 0, '');
      ExecuteScript(g_FunctionNPC, '@使用回城石');
      if (StdItem.Shape = 17) then begin
          if UserItem.Dura > 0 then Dec(UserItem.Dura);
          if (UserItem.Dura <= 0) then begin
            SendDelItems(UserItem);
            DelBagItem(UserItem.MakeIndex, '');
          end else begin
            SendDefMessage(SM_EAT_FAIL, 0, 0, 0, 0, '');
            SendUpdateItem(UserItem);
          end;
      end;
      end;
      Break;
    end;
end;

end;

procedure TPlayObject.KillMonsterFunc();
begin
if (m_PEnvir.m_MapFlag.sMapFuncLabel <> '') then begin
    ExecuteScript(g_ManageNPC, m_PEnvir.m_MapFlag.sMapFuncLabel);
end;
ExecuteScript(g_FunctionNPC, '@杀怪触发');
end;

procedure TPlayObject.KillPlayerFunc();
begin
if (m_LastHiter <> nil) and (m_LastHiter.m_btRaceServer = RC_PLAYOBJECT) then begin
    TPlayObject(m_LastHiter).m_sScriptParam := m_sCharName;
    TPlayObject(m_LastHiter).m_sScriptParam := m_PEnvir.m_sMapName;
    TPlayObject(m_LastHiter).m_sScriptParam := IntToStr(m_nCurrX);
    TPlayObject(m_LastHiter).m_sScriptParam := IntToStr(m_nCurrY);
    TPlayObject(m_LastHiter).m_sScriptParam := m_PEnvir.m_sMapDesc;
    TPlayObject(m_LastHiter).m_sScriptParam := IntToStr(m_btCountry);

    (m_LastHiter as TPlayObject).ExecuteScript(g_FunctionNPC, '@谋杀他人');
    //被人谋杀执行脚本
    TPlayObject(Self).m_sScriptParam := m_LastHiter.m_sCharName;
    TPlayObject(Self).m_sScriptParam := m_LastHiter.m_PEnvir.m_sMapName;
    TPlayObject(Self).m_sScriptParam := IntToStr(m_LastHiter.m_nCurrX);
    TPlayObject(Self).m_sScriptParam := IntToStr(m_LastHiter.m_nCurrY);
    TPlayObject(Self).m_sScriptParam := m_LastHiter.m_PEnvir.m_sMapDesc;
    TPlayObject(Self).m_sScriptParam := IntToStr(m_LastHiter.m_btCountry);
    ExecuteScript(g_FunctionNPC, '@被人谋杀');
end;
end;

procedure TPlayObject.RecalcAddProvisionalAbil;
var
i                                     : Integer;
begin
for i := Low(TProvisionalAbil) to High(TProvisionalAbil) do begin
    case i of
      0: m_AddAbil.wAC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wAC) + m_ProvisionalAbil), hiword(m_AddAbil.wAC)); //AC1          //防御
      1: m_AddAbil.wAC := MakeLong(loword(m_AddAbil.wAC), _MIN(High(MaxInt), hiword(m_AddAbil.wAC) + m_ProvisionalAbil)); //AC2          //防御
      2: m_AddAbil.wMAC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wMAC) + m_ProvisionalAbil), hiword(m_AddAbil.wMAC)); //MAC1         //魔法防御
      3: m_AddAbil.wMAC := MakeLong(loword(m_AddAbil.wMAC), _MIN(High(MaxInt), hiword(m_AddAbil.wMAC) + m_ProvisionalAbil)); //MAC2         //魔法防御
      4: m_AddAbil.wDC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wDC) + m_ProvisionalAbil), hiword(m_AddAbil.wDC)); //DC1          //攻击
      5: m_AddAbil.wDC := MakeLong(loword(m_AddAbil.wDC), _MIN(High(MaxInt), hiword(m_AddAbil.wDC) + m_ProvisionalAbil)); //DC2          //攻击
      6: m_AddAbil.wMC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wMC) + m_ProvisionalAbil), hiword(m_AddAbil.wMC)); //MC1          //魔法
      7: m_AddAbil.wMC := MakeLong(loword(m_AddAbil.wMC), _MIN(High(MaxInt), hiword(m_AddAbil.wMC) + m_ProvisionalAbil)); //MC2          //魔法
      8: m_AddAbil.wSC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wSC) + m_ProvisionalAbil), hiword(m_AddAbil.wSC)); //SC1          //道术
      9: m_AddAbil.wSC := MakeLong(loword(m_AddAbil.wSC), _MIN(High(MaxInt), hiword(m_AddAbil.wSC) + m_ProvisionalAbil)); //SC2          //道术
      10: m_AddAbil.dwHP := _MIN(MAXHUMHP, m_AddAbil.dwHP + m_ProvisionalAbil);                  //HP         //生命值
      11: m_AddAbil.dwMP := _MIN(MAXHUMMP, m_AddAbil.dwMP + m_ProvisionalAbil);                  //MP         //魔法值
      12: m_AddAbil.btLuck := _MIN(High(byte), m_AddAbil.btLuck + m_ProvisionalAbil);            //Luck         //幸运
      13: m_AddAbil.btUnLuck := _MIN(High(byte), m_AddAbil.btUnLuck + m_ProvisionalAbil);      //UnLuck       //诅咒
      14: m_AddAbil.wSpeedPoint := _MIN(High(MaxInt), m_AddAbil.wSpeedPoint + m_ProvisionalAbil); //SPEED      //躲避
      15: m_AddAbil.wAntiMagic := _MIN(High(MaxInt), m_AddAbil.wAntiMagic + m_ProvisionalAbil);//AntiMagic    //魔法躲避
      16: m_AddAbil.wAntiPoison := _MIN(High(MaxInt), m_AddAbil.wAntiPoison + m_ProvisionalAbil); //AntiPoison   //中毒躲避
      17: m_AddAbil.wHitPoint := _MIN(High(MaxInt), m_AddAbil.wHitPoint + m_ProvisionalAbil);    //HIT          //命中
      18: m_AddAbil.btMagicNicety := _MIN(High(MaxInt), m_AddAbil.btMagicNicety + m_ProvisionalAbil); //MagicNicety//魔法命中
      19: m_AddAbil.btPoisonNicety := _MIN(High(MaxInt), m_AddAbil.btPoisonNicety + m_ProvisionalAbil); //PoisonNicety //中毒命中
      20: Inc(m_nHongMoSuite, m_ProvisionalAbil);
      21: m_AddAbil.btShiftDamage := _MIN(High(byte), m_AddAbil.btShiftDamage + m_ProvisionalAbil); //ShiftDamage,/伤害转移
      22: m_AddAbil.btReflexDamage := _MIN(High(byte), m_AddAbil.btReflexDamage + m_ProvisionalAbil); //ReflexDamage, /伤害反射
      23: m_AddAbil.wPetFelementPoint := _MIN(High(Word), m_AddAbil.wPetFelementPoint + m_ProvisionalAbil); //Gold金属性
      24: m_AddAbil.wPetFelementPoint := _MIN(High(Word), m_AddAbil.wPetFelementPoint + m_ProvisionalAbil); //Wood木属性
      25: m_AddAbil.wPetFelementPoint := _MIN(High(Word), m_AddAbil.wPetFelementPoint + m_ProvisionalAbil); //Soil水属性
      26: m_AddAbil.wPetFelementPoint := _MIN(High(Word), m_AddAbil.wPetFelementPoint + m_ProvisionalAbil); //Water 火属性
      27: m_AddAbil.wPetFelementPoint := _MIN(High(Word), m_AddAbil.wPetFelementPoint + m_ProvisionalAbil); //Fire土属性
      28: m_AddAbil.btThump := _MIN(High(Word), m_AddAbil.btThump + m_ProvisionalAbil);          //Thump 爆击机率
      29: m_AddAbil.btReduceAC := _MIN(High(Byte), m_AddAbil.btReduceAC + m_ProvisionalAbil);    //ReduceAC,         /减免对方物理防御
      30: m_AddAbil.btReduceMAC := _MIN(High(Byte), m_AddAbil.btReduceMAC + m_ProvisionalAbil);//ReduceMAC,      /减免对方魔法防御
      31: m_AddAbil.btReduceSpeedPoint := _MIN(High(Byte), m_AddAbil.btReduceSpeedPoint + m_ProvisionalAbil); //ReduceSpeedPoint, /减免对方物理躲避
      32: m_AddAbil.btReduceAntiMagic := _MIN(High(Byte), m_AddAbil.btReduceAntiMagic + m_ProvisionalAbil); //ReduceAntiMagic,/减免对方魔法躲避
      33: m_AddAbil.wAgainst := _MIN(High(Word), m_AddAbil.wAgainst + m_ProvisionalAbil);      //Against 抗性
      34: m_AddAbil.btThump2 := _MIN(High(byte), m_AddAbil.btThump2 + m_ProvisionalAbil);      //双倍暴击
      35: m_AddAbil.dwGC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.dwGC) + m_ProvisionalAbil), hiword(m_AddAbil.dwGC)); //GC1          //妖力
      36: m_AddAbil.dwGC := MakeLong(loword(m_AddAbil.dwGC), _MIN(High(MaxInt), hiword(m_AddAbil.dwGC) + m_ProvisionalAbil)); //GC2          //妖力
      37: m_AddAbil.wSacredDamMin := _MIN(High(Word), m_AddAbil.wSacredDamMin + m_ProvisionalAbil); //神圣伤害下限
      38: m_AddAbil.wSacredDamMax := _MIN(High(Word), m_AddAbil.wSacredDamMax + m_ProvisionalAbil); //神圣伤害上限
      39: m_AddAbil.dwSacredThump := _MIN(High(MaxInt), m_AddAbil.dwSacredThump + m_ProvisionalAbil);
      40: m_AddAbil.dwSacredExempt := _MIN(High(MaxInt), m_AddAbil.dwSacredExempt + m_ProvisionalAbil);
      41: m_AddAbil.dwSacredPenetRation := _MIN(High(MaxInt), m_AddAbil.dwSacredPenetRation + m_ProvisionalAbil);
    end;
end;
end;

procedure TPlayObject.RecalcAddPetAbil;
var
UserItem                              : pTUserItem;
StdItem                               : pTStdItem;
begin
//骑战附加属性
if m_boRideOn then begin
    if m_boPneuma and (m_PneumaObject <> nil) then begin
      TPlayObject(m_PneumaObject).GetUserItemByMakeIndex(TPlayObject(m_PneumaObject).m_PetInfo.nMakeIndex, UserItem);
    end else begin
      GetUserItemByMakeIndex(m_PetInfo.nMakeIndex, UserItem);
    end;

    if (UserItem <> nil) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if (StdItem <> nil) and (StdItem.StdMode = 49) and (StdItem.Shape = 51) then begin
      GetAccessory(UserItem^, m_AddAbil);
      end;
    end;
end;

//魂佑灵兽属性
if m_boBeast then begin
    GetUserItemByMakeIndex(m_PetInfo.nMakeIndex, UserItem);
    if (UserItem <> nil) then begin
      StdItem := UserEngine.GetStdItem(UserItem.wIndex);
      if (StdItem <> nil) and (StdItem.StdMode = 49) and (StdItem.Shape = 51) then begin
      GetAccessory(UserItem^, m_AddAbil);
      end;
    end;
end;
end;

procedure TPlayObject.RecalcAddSuiteAbil(Idx: Integer; boPercent: Boolean);
var
SuiteAbility                        : pTSuiteAbility;
begin
SuiteAbility := UserEngine.GetSuiteAbility(Idx);
if (SuiteAbility <> nil) then begin
    if boPercent then begin
      m_AddAbil.dwHP := _MIN(MAXHUMHP, m_AddAbil.dwHP + Round(m_Abil.dwMaxHP * SuiteAbility.HP / 100));
      m_AddAbil.dwMP := _MIN(MAXHUMMP, m_AddAbil.dwMP + Round(m_Abil.dwMaxMP * SuiteAbility.MP / 100));
      m_AddAbil.wElementForceMax := _MIN(High(MaxInt), m_AddAbil.wElementForceMax + Round(m_Abil.wElementForceMax * SuiteAbility.EF / 100));
      m_AddAbil.wAC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wAC) + Round(loword(m_Abil.AC) * (100 + SuiteAbility.AC) / 100)), hiword(m_AddAbil.wAC));
      m_AddAbil.wAC := MakeLong(loword(m_AddAbil.wAC), _MIN(High(MaxInt), hiword(m_AddAbil.wAC) + Round(hiword(m_Abil.AC) * (100 + SuiteAbility.AC2) / 100)));
      m_AddAbil.wMAC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wMAC) + Round(loword(m_Abil.MAC) * (100 + SuiteAbility.MAC) / 100)), hiword(m_AddAbil.wMAC));
      m_AddAbil.wMAC := MakeLong(loword(m_AddAbil.wMAC), _MIN(High(MaxInt), hiword(m_AddAbil.wMAC) + Round(hiword(m_Abil.MAC) * (100 + SuiteAbility.MAC2) / 100)));
      m_AddAbil.wDC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wDC) + Round(loword(m_Abil.DC) * (100 + SuiteAbility.DC) / 100)), hiword(m_AddAbil.wDC));
      m_AddAbil.wDC := MakeLong(loword(m_AddAbil.wDC), _MIN(High(MaxInt), hiword(m_AddAbil.wDC) + Round(hiword(m_Abil.DC) * (100 + SuiteAbility.DC2) / 100)));
      m_AddAbil.wMC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wMC) + Round(loword(m_Abil.MC) * (100 + SuiteAbility.MC) / 100)), hiword(m_AddAbil.wMC));
      m_AddAbil.wMC := MakeLong(loword(m_AddAbil.wMC), _MIN(High(MaxInt), hiword(m_AddAbil.wMC) + Round(hiword(m_Abil.MC) * (100 + SuiteAbility.MC2) / 100)));
      m_AddAbil.wSC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wSC) + Round(loword(m_Abil.SC) * (100 + SuiteAbility.SC) / 100)), hiword(m_AddAbil.wSC));
      m_AddAbil.wSC := MakeLong(loword(m_AddAbil.wSC), _MIN(High(MaxInt), hiword(m_AddAbil.wSC) + Round(hiword(m_Abil.SC) * (100 + SuiteAbility.SC2) / 100)));
      m_AddAbil.dwGC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.dwGC) + Round(loword(m_Abil.GC) * (100 + SuiteAbility.GC) / 100)), hiword(m_AddAbil.dwGC));
      m_AddAbil.dwGC := MakeLong(loword(m_AddAbil.dwGC), _MIN(High(MaxInt), hiword(m_AddAbil.dwGC) + Round(hiword(m_Abil.GC) * (100 + SuiteAbility.GC2) / 100)));

      m_AddAbil.wHitPoint := Round(m_AddAbil.wHitPoint * (100 + SuiteAbility.HitPoint) / 100);
      m_AddAbil.wSpeedPoint := Round(m_AddAbil.wSpeedPoint * (100 + SuiteAbility.SpeedPoint) / 100);
      m_AddAbil.btMagicNicety := Round(m_AddAbil.btMagicNicety * (100 + SuiteAbility.MagicNicety) / 100);
      m_AddAbil.wAntiMagic := Round(m_AddAbil.wAntiMagic * (100 + SuiteAbility.AntiMagic) / 100);
      m_AddAbil.btPoisonNicety := Round(m_AddAbil.btPoisonNicety * (100 + SuiteAbility.PoisonNicety) / 100);
      m_AddAbil.wAntiPoison := Round(m_AddAbil.wAntiPoison * (100 + SuiteAbility.AntiPoison) / 100);
      m_AddAbil.wHealthRecover := Round(m_AddAbil.wHealthRecover * (100 + SuiteAbility.HealthRecover) / 100);
      m_AddAbil.wSpellRecover := Round(m_AddAbil.wSpellRecover * (100 + SuiteAbility.SpellRecover) / 100);
      m_AddAbil.btVampirePoint := Round(m_AddAbil.btVampirePoint * (100 + SuiteAbility.VampirePoint) / 100);
      m_AddAbil.btVampireRate := _MIN(100, Round(m_AddAbil.btVampireRate * (100 + SuiteAbility.VampireRate) / 100));
      m_AddAbil.btLuck := Round(m_AddAbil.btLuck * (100 + SuiteAbility.Luck) / 100);

      m_AddAbil.btShiftDamage := m_AddAbil.btShiftDamage + Round(m_Abil.btShiftDamage * (100 + SuiteAbility.ShiftDamage) / 100);
      m_AddAbil.btReflexDamage := m_AddAbil.btReflexDamage + Round(m_Abil.btReflexDamage * (100 + SuiteAbility.ReflexDamage) / 100);
      m_AddAbil.wPetFelementPoint := m_AddAbil.wPetFelementPoint + Round(m_Abil.wPetFelementAbil * (100 + SuiteAbility.Gold) / 100);
      m_AddAbil.wPetFelementPoint := m_AddAbil.wPetFelementPoint + Round(m_Abil.wPetFelementAbil * (100 + SuiteAbility.Wood) / 100);
      m_AddAbil.wPetFelementPoint := m_AddAbil.wPetFelementPoint + Round(m_Abil.wPetFelementAbil * (100 + SuiteAbility.Soil) / 100);
      m_AddAbil.wPetFelementPoint := m_AddAbil.wPetFelementPoint + Round(m_Abil.wPetFelementAbil * (100 + SuiteAbility.Water) / 100);
      m_AddAbil.wPetFelementPoint := m_AddAbil.wPetFelementPoint + Round(m_Abil.wPetFelementAbil * (100 + SuiteAbility.Fire) / 100);
      m_AddAbil.btThump := m_AddAbil.btThump + Round(m_Abil.btThump * (100 + SuiteAbility.Thump) / 100);
      m_AddAbil.btReduceAC := m_AddAbil.btReduceAC + Round(m_Abil.btReduceAC * (100 + SuiteAbility.ReduceAC) / 100);
      m_AddAbil.btReduceMAC := m_AddAbil.btReduceMAC + Round(m_Abil.btReduceMAC * (100 + SuiteAbility.ReduceMAC) / 100);
      m_AddAbil.btReduceSpeedPoint := m_AddAbil.btReduceSpeedPoint + Round(m_Abil.btReduceSpeedPoint * (100 + SuiteAbility.ReduceSpeedPoint) / 100);
      m_AddAbil.btReduceAntiMagic := m_AddAbil.btReduceAntiMagic + Round(m_Abil.btReduceAntiMagic * (100 + SuiteAbility.ReduceAntiMagic) / 100);
      m_AddAbil.wAgainst := m_AddAbil.wAgainst + Round(m_Abil.wAgainst * (100 + SuiteAbility.Against) / 100);
      m_AddAbil.wZazen2ExpRate := m_AddAbil.wZazen2ExpRate + Round(m_Abil.wZazen2ExpRate * (100 + SuiteAbility.Zazen2ExpRate) / 100);

      m_AddAbil.btBreakShield := m_AddAbil.btBreakShield + Round(m_Abil.btBreakShield * (100 + SuiteAbility.BreakShield) / 100);
      m_AddAbil.btShieldPower := m_AddAbil.btShieldPower + Round(m_Abil.btShieldPower * (100 + SuiteAbility.ShieldPower) / 100);
      m_AddAbil.btBloodAttack := m_AddAbil.btBloodAttack + Round(m_Abil.btBloodAttack * (100 + SuiteAbility.BloodAttack) / 100);
      m_AddAbil.btBloodDefense := m_AddAbil.btBloodDefense + Round(m_Abil.btBloodDefense * (100 + SuiteAbility.BloodDefense) / 100);
      m_AddAbil.btSacredArmor := m_AddAbil.btSacredArmor + Round(m_Abil.btSacredArmor * (100 + SuiteAbility.SacredArmor) / 100);
      m_AddAbil.btDevilGuard := m_AddAbil.btDevilGuard + Round(m_Abil.btDevilGuard * (100 + SuiteAbility.DevilGuard) / 100);
      m_AddAbil.btNatureGuard := m_AddAbil.btNatureGuard + Round(m_Abil.btNatureGuard * (100 + SuiteAbility.NatureGuard) / 100);
      m_AddAbil.btFightWill := m_AddAbil.btFightWill + Round(m_Abil.btFightWill * (100 + SuiteAbility.FightWill) / 100);
      m_AddAbil.wSacredDamMin := m_AddAbil.wSacredDamMin + Round(m_Abil.wSacredDamMin * (100 + SuiteAbility.SacredDamMin) / 100);
      m_AddAbil.wSacredDamMax := m_AddAbil.wSacredDamMax + Round(m_Abil.wSacredDamMax * (100 + SuiteAbility.SacredDamMax) / 100);
      m_AddAbil.btPowerRate := m_AddAbil.btPowerRate + Round(100 * (100 + SuiteAbility.PowerRate) / 100); //读取攻击倍数
      m_AddAbil.btDefenceRate := m_AddAbil.btDefenceRate + Round(100 * (100 + SuiteAbility.DefenceRate) / 100); //读取防御倍数
    end else begin
      m_AddAbil.dwHP := _MIN(MAXHUMHP, m_AddAbil.dwHP + SuiteAbility.HP);
      m_AddAbil.dwMP := _MIN(MAXHUMMP, m_AddAbil.dwMP + SuiteAbility.MP);
      m_AddAbil.wElementForceMax := _MIN(High(MaxInt), m_AddAbil.wElementForceMax + SuiteAbility.EF);
      m_AddAbil.wDC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wDC) + SuiteAbility.DC), _MIN(High(MaxInt), hiword(m_AddAbil.wDC) + SuiteAbility.DC2));
      m_AddAbil.wMC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wMC) + SuiteAbility.MC), _MIN(High(MaxInt), hiword(m_AddAbil.wMC) + SuiteAbility.MC2));
      m_AddAbil.wSC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wSC) + SuiteAbility.SC), _MIN(High(MaxInt), hiword(m_AddAbil.wSC) + SuiteAbility.SC2));
      m_AddAbil.dwGC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.dwGC) + SuiteAbility.GC), _MIN(High(MaxInt), hiword(m_AddAbil.dwGC) + SuiteAbility.GC2));
      m_AddAbil.wAC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wAC) + SuiteAbility.AC), _MIN(High(MaxInt), hiword(m_AddAbil.wAC) + SuiteAbility.AC2));
      m_AddAbil.wMAC := MakeLong(_MIN(High(MaxInt), loword(m_AddAbil.wMAC) + SuiteAbility.MAC), _MIN(High(MaxInt), hiword(m_AddAbil.wMAC) + SuiteAbility.MAC2));
      m_AddAbil.wHitPoint := _MIN(High(MaxInt), m_AddAbil.wHitPoint + SuiteAbility.HitPoint);
      m_AddAbil.wSpeedPoint := _MIN(High(MaxInt), m_AddAbil.wSpeedPoint + SuiteAbility.SpeedPoint);
      m_AddAbil.btMagicNicety := _MIN(High(MaxInt), m_AddAbil.btMagicNicety + SuiteAbility.MagicNicety);
      m_AddAbil.wAntiMagic := _MIN(High(MaxInt), m_AddAbil.wAntiMagic + SuiteAbility.AntiMagic);
      m_AddAbil.btPoisonNicety := _MIN(High(MaxInt), m_AddAbil.btPoisonNicety + SuiteAbility.PoisonNicety);
      m_AddAbil.wAntiPoison := _MIN(High(MaxInt), m_AddAbil.wAntiPoison + SuiteAbility.AntiPoison);
      m_AddAbil.wHealthRecover := _MIN(High(word), m_AddAbil.wHealthRecover + SuiteAbility.HealthRecover);
      m_AddAbil.wSpellRecover := _MIN(High(word), m_AddAbil.wSpellRecover + SuiteAbility.SpellRecover);
      m_AddAbil.btVampirePoint := _MIN(High(byte), m_AddAbil.btVampirePoint + SuiteAbility.VampirePoint);
      m_AddAbil.btVampireRate := _MIN(High(byte), m_AddAbil.btVampireRate + SuiteAbility.VampireRate);
      m_AddAbil.btLuck := _MIN(High(byte), m_AddAbil.btLuck + SuiteAbility.Luck);
      m_AddAbil.btShiftDamage := _MIN(High(byte), m_AddAbil.btShiftDamage + SuiteAbility.ShiftDamage);
      m_AddAbil.btReflexDamage := _MIN(High(byte), m_AddAbil.btReflexDamage + SuiteAbility.ReflexDamage);
      m_AddAbil.wPetFelementPoint := _MIN(High(word), m_AddAbil.wPetFelementPoint + SuiteAbility.Gold);
      m_AddAbil.wPetFelementPoint := _MIN(High(word), m_AddAbil.wPetFelementPoint + SuiteAbility.Wood);
      m_AddAbil.wPetFelementPoint := _MIN(High(word), m_AddAbil.wPetFelementPoint + SuiteAbility.Soil);
      m_AddAbil.wPetFelementPoint := _MIN(High(word), m_AddAbil.wPetFelementPoint + SuiteAbility.Water);
      m_AddAbil.wPetFelementPoint := _MIN(High(word), m_AddAbil.wPetFelementPoint + SuiteAbility.Fire);

      m_AddAbil.btThump := _MIN(High(word), m_AddAbil.btThump + SuiteAbility.Thump);
      m_AddAbil.btReduceAC := _MIN(High(Byte), m_AddAbil.btReduceAC + SuiteAbility.ReduceAC);
      m_AddAbil.btReduceMAC := _MIN(High(Byte), m_AddAbil.btReduceMAC + SuiteAbility.ReduceMAC);
      m_AddAbil.btReduceSpeedPoint := _MIN(High(Byte), m_AddAbil.btReduceSpeedPoint + SuiteAbility.ReduceSpeedPoint);
      m_AddAbil.btReduceAntiMagic := _MIN(High(Byte), m_AddAbil.btReduceAntiMagic + SuiteAbility.ReduceAntiMagic);
      m_AddAbil.wAgainst := _MIN(High(word), m_AddAbil.wAgainst + SuiteAbility.Against);
      m_AddAbil.wZazen2ExpRate := _MIN(High(word), m_AddAbil.wZazen2ExpRate + SuiteAbility.Zazen2ExpRate);

      m_AddAbil.btBreakShield := _MIN(High(byte), m_AddAbil.btBreakShield + SuiteAbility.BreakShield);
      m_AddAbil.btShieldPower := _MIN(High(byte), m_AddAbil.btShieldPower + SuiteAbility.ShieldPower);
      m_AddAbil.btBloodAttack := _MIN(High(byte), m_AddAbil.btBloodAttack + SuiteAbility.BloodAttack);
      m_AddAbil.btBloodDefense := _MIN(High(byte), m_AddAbil.btBloodDefense + SuiteAbility.BloodDefense);
      m_AddAbil.btSacredArmor := _MIN(High(byte), m_AddAbil.btSacredArmor + SuiteAbility.SacredArmor);
      m_AddAbil.btDevilGuard := _MIN(High(byte), m_AddAbil.btDevilGuard + SuiteAbility.DevilGuard);
      m_AddAbil.btNatureGuard := _MIN(High(byte), m_AddAbil.btNatureGuard + SuiteAbility.NatureGuard);
      m_AddAbil.btFightWill := _MIN(High(byte), m_AddAbil.btFightWill + SuiteAbility.FightWill);
      m_AddAbil.wSacredDamMin := _MIN(High(Integer), m_AddAbil.wSacredDamMin + SuiteAbility.SacredDamMin);
      m_AddAbil.wSacredDamMax := _MIN(High(Integer), m_AddAbil.wSacredDamMax + SuiteAbility.SacredDamMax);
      m_AddAbil.btPowerRate := _MIN(High(byte), m_AddAbil.btPowerRate + SuiteAbility.PowerRate);
      m_AddAbil.btDefenceRate := _MIN(High(byte), m_AddAbil.btDefenceRate + SuiteAbility.DefenceRate);
    end;

    if CheckSPCode(SuiteAbility.Special, 0) then m_boParalysis := True;
    if CheckSPCode(SuiteAbility.Special, 1) then m_boMagicShield := True;
    if CheckSPCode(SuiteAbility.Special, 2) then m_boRevival := True;
    if CheckSPCode(SuiteAbility.Special, 3) then m_boMuscleRing := True;
    if CheckSPCode(SuiteAbility.Special, 4) then m_boFastTrain := True;
    if CheckSPCode(SuiteAbility.Special, 5) then m_boProbeNecklace := True;
    if CheckSPCode(SuiteAbility.Special, 6) then m_boHideMode := True;
    if CheckSPCode(SuiteAbility.Special, 7) then m_boUnParalysis := True;
    if CheckSPCode(SuiteAbility.Special, 8) then m_boUnMagicShield := True;
    if CheckSPCode(SuiteAbility.Special, 9) then m_boUnRevival := True;
    if CheckSPCode(SuiteAbility.Special, 10) then m_boParalysisEx := True;
    if CheckSPCode(SuiteAbility.Special, 11) then m_boMagicShieldEx := True;
    if CheckSPCode(SuiteAbility.Special, 12) then m_boRevivalEx := True;
    if CheckSPCode(SuiteAbility.Special, 13) then m_boNoDropUseItem := True;
    if CheckSPCode(SuiteAbility.Special, 14) then m_boNoDropItem := True;
    if CheckSPCode(SuiteAbility.Special, 15) then m_boMcParalysis := True;
end;
end;

procedure TPlayObject.SendBroadVehicle(btCreatorType: Byte; VehicleExp: TVehicleExp);
var
i, II, nUseTeam                     : Integer;
boCreator                           : Boolean;
btState                               : Byte;
sMemBer                               : string;
GuildVehicle                        : pTGuildVehicle;
begin
g_SmallPacketManage.Init;
if btCreatorType = 0 then begin
    g_SmallPacketManage.FillWrite(29, 0);
end else begin
    g_SmallPacketManage.WriteByte(3);
    if g_GuildDartList.Count > 0 then begin
      for I := 0 to g_GuildDartList.Count - 1 do begin
      boCreator := False;
      btState := 0;
      GuildVehicle := g_GuildDartList.Items;
      for II := 0 to 2 do begin
          if CompareText(m_sCharName, GuildVehicle.sMember.UserName) = 0 then begin
            boCreator := True;
            nUseTeam := GuildVehicle.nTeam;
            btState := GuildVehicle.btState;
          end;
      end;
      end;
      if (boCreator) and (btState = 1) then begin
      g_SmallPacketManage.WriteByte(0);
      g_SmallPacketManage.WriteString('running', SizeOf('running'));
      g_SmallPacketManage.WriteByte(0);
      end else g_SmallPacketManage.WriteWord(0);

      g_SmallPacketManage.WriteInteger(g_GuildDartList.Count);
      for I := 0 to g_GuildDartList.Count - 1 do begin
      GuildVehicle := g_GuildDartList.Items;
      g_SmallPacketManage.WriteInteger(GuildVehicle.nTeam);
      end;

      g_SmallPacketManage.WriteInteger(g_GuildDartList.Count);
      for I := 0 to g_GuildDartList.Count - 1 do begin
      GuildVehicle := g_GuildDartList.Items;
      sMemBer := Format('%s#%d#%s', .UserName, GuildVehicle.sMember.btType, GuildVehicle.sGuildName]);
      g_SmallPacketManage.WriteString(sMemBer, SizeOf(sMemBer));
      g_SmallPacketManage.WriteByte(0);
      end;

      g_SmallPacketManage.WriteInteger(g_GuildDartList.Count);
      for I := 0 to g_GuildDartList.Count - 1 do begin
      GuildVehicle := g_GuildDartList.Items;
      g_SmallPacketManage.WriteInteger(GuildVehicle.nMemberCount);
      end;

      g_SmallPacketManage.WriteInteger(g_GuildDartList.Count);
      for I := 0 to g_GuildDartList.Count - 1 do begin
      GuildVehicle := g_GuildDartList.Items;
      g_SmallPacketManage.WriteInteger(GuildVehicle.nMaxMember);
      end;

      g_SmallPacketManage.WriteInteger(g_GuildDartList.Count);
      for I := 0 to g_GuildDartList.Count - 1 do begin
      GuildVehicle := g_GuildDartList.Items;
      g_SmallPacketManage.WriteInteger(GuildVehicle.btFullStart);
      end;

      if boCreator then g_SmallPacketManage.WriteInteger(nUseTeam)
      else g_SmallPacketManage.WriteInteger(0);
      g_SmallPacketManage.WriteWord(0);
    end else g_SmallPacketManage.FillWrite(28, 0);
end;

g_SmallPacketManage.WriteInteger(3);
g_SmallPacketManage.WriteInteger(VehicleExp.nExp * 10000);
g_SmallPacketManage.WriteInteger(VehicleExp.nExp * 10000);
g_SmallPacketManage.WriteInteger(VehicleExp.nExp * 10000);
g_SmallPacketManage.WriteInteger(3);
g_SmallPacketManage.WriteInteger(VehicleExp.nExp * 10000);
g_SmallPacketManage.WriteInteger(VehicleExp.nExp * 10000);
g_SmallPacketManage.WriteInteger(VehicleExp.nExp * 10000);

if btCreatorType = 0 then begin
    g_SmallPacketManage.FillWrite(12, 0);
end else begin
    if boCreator then begin
      GuildVehicle := g_GuildDartList.Items;
      g_SmallPacketManage.WriteInteger(GuildVehicle.nMemBerCount);
      for II := 0 to 2 do begin
      if (GuildVehicle.nMemBerCount > II) and (GuildVehicle.sMember.UserName <> '') then begin
          g_SmallPacketManage.WriteString(GuildVehicle.sMember.UserName, SizeOf(GuildVehicle.sMember.UserName));
          g_SmallPacketManage.WriteByte(0);
      end;
      end;
      g_SmallPacketManage.WriteInteger(GuildVehicle.nMemBerCount);
      for II := 0 to 2 do begin
      if (GuildVehicle.nMemBerCount > II) and (GuildVehicle.sMember.UserName <> '') then
          g_SmallPacketManage.WriteInteger(GuildVehicle.sMember.btJob);
      end;
      g_SmallPacketManage.WriteInteger(GuildVehicle.nMemBerCount);
      for II := 0 to 2 do begin
      if (GuildVehicle.nMemBerCount > II) and (GuildVehicle.sMember.UserName <> '') then
          g_SmallPacketManage.WriteInteger(GuildVehicle.sMember.nLevel);
      end;
    end else g_SmallPacketManage.FillWrite(12, 0);
end;

SendDefMessage(2417, Integer(Self), 0, 0, 0, g_SmallPacketManage.GetMsg(), True);
end;

//修复铁血神技顺序图标错乱的问题


procedure TPlayObject.SendWishAwardInfo();
var
i, ii, nRandSeed, nAward, n14         : Integer;
SetRadom                              : TRandomEngine;
sAwardName                            : string;
nAwardCount, nCount                   : Integer;
begin
ExecuteScript(g_FunctionNPC, '@_许愿_开始许愿');
try
    nRandSeed := StrToIntDef(g_FunctionNPC.GetPlayObjectInfo(TPlayObject(Self),
      UserEngine.WishAward.nRandSeed), 0);
    nAward := Random(30);
    SetRadom := TRandomEngine.Create;
    SetRadom.MinNumber := 1;
    SetRadom.MaxNumber := UserEngine.WishAward.nCount;
    SetRadom.Unique := True;
    SetRadom.nRandSeed := nRandSeed;
    g_LargePacketManage.Init;
    g_LargePacketManage.WriteWord($2D);
    g_LargePacketManage.WriteWord($2D);
    g_LargePacketManage.WriteByte(nAward);
    g_LargePacketManage.WriteInteger($1E);
    for I := 1 to 30 do begin
      ii := SetRadom.GetRandom;
      nCount := StrToIntDef(g_FunctionNPC.GetPlayObjectInfo(TPlayObject(Self),
      UserEngine.WishAward.AwardItem.Count), 0);
      n14 := Length(UserEngine.WishAward.AwardItem.ItemName) +
      Length(UserEngine.WishAward.AwardItem.Name) + 10;
      g_LargePacketManage.WriteInteger(n14);
      g_LargePacketManage.WriteString(UserEngine.WishAward.AwardItem.ItemName,
      SizeOf(UserEngine.WishAward.AwardItem.ItemName));
      g_LargePacketManage.WriteByte(0);
      g_LargePacketManage.WriteString(UserEngine.WishAward.AwardItem.Name,
      SizeOf(UserEngine.WishAward.AwardItem.Name));
      g_LargePacketManage.WriteByte(0);
      g_LargePacketManage.WriteWord(nCount);
      g_LargePacketManage.WriteWord(UserEngine.WishAward.AwardItem.nLook);
      if (I - 1) = nAward then begin
      g_LargePacketManage.WriteInteger($01000000);
      sAwardName := UserEngine.WishAward.AwardItem.ItemName;
      nAwardCount := nCount;
      end else
      g_LargePacketManage.WriteInteger(0);
    end;
finally
    SetRadom.Free;
end;
SendDefMessage(2176, integer(Self), 0, 0, 0, g_LargePacketManage.GetMsg, True);
m_sScriptParam := sAwardName;
m_sScriptParam := IntToStr(nAwardCount);
ExecuteScript(g_FunctionNPC, '@_许愿_领取奖励');
end;

end.
页: [1]
查看完整版本: 单元的cnpack很卡,求大佬指点迷津