using CommonAI.Zone; using CommonAI.Zone.Helper; using CommonAI.Zone.Instance; using CommonLang; using CommonLang.Vector; using System.Collections.Generic; using XmdsCommon.EditorData; using XmdsCommon.Message; using XmdsCommon.Plugin; using XmdsCommonServer.Plugin; using XmdsCommonServer.Plugin.Quest; using XmdsCommonServer.Plugin.Units; namespace XmdsCommonQuest.Quest { /// <summary> /// 炼魂任务 /// </summary> [QuestTypeListen(XmdsQuestData.TaskType.RefineSoul)] class Quest_RefineSoul : QuestScript { private InstanceItem mRefineItem; public int mRefineItemTemplateID; public const string Attribute_Quality = "refine_quality"; public const string Attribute_Name = "refine_name"; public const string Attribute_ID = "refine_id"; public const string Attribute_Killed = "refine_killed"; public static int CheckIntervalMS = 3000; public static int OutDistanceOffset = 10; public enum RefineState { None, PutReady, Progress, GetReady, Complete, } private List<int> mTargetMasters; private TimeTaskMS mRefineTimeTask; private RefineState mRefineState; //private void SendPutEvent(bool canPut) //{ // PlayerPutRefineSoulItemB2c evt = new PlayerPutRefineSoulItemB2c(); // evt.CanPut = canPut; // evt.QuestID = QuestID; // Player.queueEvent(evt); //} private void SendRefineSeekEvent() { ChangeQuestSeekB2C evt = new ChangeQuestSeekB2C(); evt.SeekInfo = string.Format("{0},{1}", mRefineItem.X, mRefineItem.Y); evt.QuestID = QuestID; Player.queueEvent(evt); Virtual.SendMsgToClient(CommonAI.XmdsConstConfig.TIPS_REFINE_BLINK); } public RefineState State { get { return mRefineState; } set { mRefineState = value; switch (mRefineState) { case RefineState.PutReady: RemoveRefineItem(); break; case RefineState.Progress: Virtual.SendMsgToClient(CommonAI.XmdsConstConfig.TIPS_REFINE_PUT_OK); break; case RefineState.GetReady: var prop = (mRefineItem.Info.Properties as XmdsItemProperties); if (prop.RefineSuccessEffect != null) { UnitEffectEvent ue = new UnitEffectEvent(mRefineItem.ID, prop.RefineSuccessEffect); mRefineItem.Parent.queueObjectEvent(mRefineItem, ue); } mTargetMasters.Clear(); //推送临时寻路. SendRefineSeekEvent(); break; case RefineState.Complete: Zone.QuestAdapter.DoUpdateQuestStatus(Player.PlayerUUID, QuestID, XmdsQuestData.Attribute_SubState, "1"); (Player as XmdsInstancePlayer).RemoveQuestScript(QuestID); break; } } } private void RemoveRefineItem() { if (mRefineItem != null) { Zone.RemoveObjectByID(mRefineItem.ID); } } //private void AddRefineItem(Vector2 pos) //{ // if (mRefineItem != null) // { // mRefineItem.setPos(pos.X, pos.Y); // mRefineItem.SendForceSync(); // } // else // { // var itemInfo = Zone.Templates.getItem(mRefineItemTemplateID); // if (itemInfo != null) // { // //uuid 作为name同步到客户端,以便客户端隐藏/显示 // mRefineItem = Zone.AddItem(itemInfo, Player.PlayerUUID, pos.X, pos.Y, Player.Direction, Player.Force, Player.PlayerUUID, null); // mRefineItem.OnTryPickItem += MRefineItem_OnTryPickItem; // //mRefineItem.OnObjectRemoved += MRefineItem_OnObjectRemoved; // } // } // var q = Player.GetQuest(QuestID); // if (string.IsNullOrEmpty(q.Attributes.Get(Attribute_Killed))) // { // State = RefineState.Progress; // } // else // { // State = RefineState.GetReady; // } //} private void RefineItem_Tick(TimeTaskMS task) { if(mRefineItem == null || State == RefineState.GetReady) { return; } var prop = (mRefineItem.Info.Properties as XmdsItemProperties); var distance = CMath.getDistance(Player.X, Player.Y, mRefineItem.X, mRefineItem.Y); if(prop.RefineSoulRadius + OutDistanceOffset < distance) { State = RefineState.PutReady; } } private void MRefineItem_OnObjectRemoved(InstanceZoneObject obj) { mRefineItem = null; if(State == RefineState.Progress) { Virtual.SendMsgToClient(CommonAI.XmdsConstConfig.TIPS_REFINE_GET_OK); State = RefineState.PutReady; } } private bool MRefineItem_OnTryPickItem(InstanceItem item, InstanceUnit unit) { return unit == Player; } protected override void OnDispose() { if(State != RefineState.None) { Player.OnAttack -= Player_OnAttack; Player.OnGotInstanceItem -= Player_OnGotInstanceItem; } RemoveRefineItem(); if(mRefineTimeTask != null) { mRefineTimeTask.Stop(); } } protected override void OnStart() { //检测该任务目标场景 var q = Player.GetQuest(QuestID); int scenid = XmdsQuestData.GetTargetSceneID(q); var id = q.Attributes.Get(Attribute_ID); if (scenid != Zone.Data.GetID() || XmdsQuestData.IsTargetComplete(q) || !int.TryParse(id, out mRefineItemTemplateID)) { (Player as XmdsInstancePlayer).RemoveQuestScript(QuestID); } else { //初始化怪物列表, 进度 string target = XmdsQuestData.GetTarget(q); var tmps = target.Split(':'); mTargetMasters = new List<int>(); for(int i = 0; i < tmps.Length; i++) { int tmpId = 0; if(int.TryParse(tmps[i], out tmpId)) { mTargetMasters.Add(tmpId); } } State = RefineState.PutReady; Player.OnAttack += Player_OnAttack; Player.OnGotInstanceItem += Player_OnGotInstanceItem; mRefineTimeTask = Zone.AddTimePeriodicMS(CheckIntervalMS, RefineItem_Tick); } } public override void OnStatusChanged(string key, string v) { base.OnStatusChanged(key, v); if(mRefineItem != null && key == Attribute_Killed && !string.IsNullOrEmpty(v)) { //任务目标已达成 State = RefineState.GetReady; } } private void Player_OnGotInstanceItem(InstanceUnit obj, InstanceItem item) { if(mRefineItem != null && item == mRefineItem && State == RefineState.GetReady) { State = RefineState.Complete; } } private void Player_OnAttack(InstanceUnit obj, InstanceUnit target, int hp, CommonAI.Zone.Formula.AttackSource source) { //所杀怪是否正确 //处于杀怪半径内 //通知游戏服进度加一 if (mRefineItem != null && State == RefineState.Progress && hp > 0 && target.IsDead() && mTargetMasters.Count > 0 && mTargetMasters.IndexOf(target.Info.TemplateID) >= 0) { var prop = (mRefineItem.Info.Properties as XmdsItemProperties); bool inRound = CMath.intersectRound(mRefineItem.X, mRefineItem.Y, prop.RefineSoulRadius, target.X, target.Y, target.Info.BodySize); if(inRound) { Zone.QuestAdapter.DoUpdateQuestStatus(Player.PlayerUUID, QuestID, XmdsQuestData.Attribute_AddProgress, "1"); //添加spell, 从怪飞出到法器 //UnitLaunchShowSpellB2C evt = new UnitLaunchShowSpellB2C(); //evt.Spell = prop.RefineSoulSpell; //evt.LauncherID = target.ID; //evt.TargetX = mRefineItem.X; //evt.TargetY = mRefineItem.Y; //Player.queueEvent(evt); Zone.unitLaunchSpell(XmdsSkillType.none, target, prop.RefineSoulSpell, target.X, target.Y, 0, new Vector2(mRefineItem.X,mRefineItem.Y)); } } } private Vector2 CalcNextRefineItemPos() { Vector2 pos = new Vector2(Player.X, Player.Y); MathVector.movePolar(pos, Player.Direction, 3); return pos; } public override bool TryDoAction(ObjectAction act) { //if (act is PlayerPutRefineSoulItemAction && !Virtual.IsInSafeArea()) //{ // Vector2 pos = CalcNextRefineItemPos(); // int gx = 0, gy = 0; // Zone.PathFinder.PosToBlock(pos.X, pos.Y, out gx, out gy); // if(!Zone.PathFinder.TouchMapBlock(gx, gy)) // { // AddRefineItem(pos); // } // return true; //} return false; } } }