using CommonAI.Zone; using CommonAI.Zone.ZoneEditor; using CommonAI.ZoneClient; using CommonLang; using CommonLang.Vector; using pomelo.area; using pomelo.connector; using Pomelo.DotNetClient; using System; using System.Collections.Generic; using System.Linq; using System.Text; using XmdsCommon.Message; using XmdsCommon.ZoneClient; using XmdsCommon.EditorData; namespace XmdsBattleClientBot.Bot { // 游戏服相关 // partial class BotClient { public EnterSceneResponse LastEnterSceneResponse { get; private set; } public ChangeAreaResponse LastChangeAreaResponse { get; private set; } public RegionManager CurrentRegionManager { get; private set; } public NpcManager CurrentNpcManager { get; private set; } public HZZoneLayer CurrentZoneLayer { get; private set; } public ZoneActor CurrentZoneActor { get; private set; } public CommonAI.Data.SceneType CurrentSceneType { get; private set; } public void SendUnitGuard(bool guard) { if(CurrentZoneActor != null) { CurrentZoneActor.SendUnitGuard(guard); } } private void callback_gs_ChangeAreaPush(ChangeAreaPush push) { CurrentSceneType = (CommonAI.Data.SceneType)push.s2c_sceneType; this.IsFree = (CurrentSceneType == CommonAI.Data.SceneType.Normal || CurrentSceneType == CommonAI.Data.SceneType.HUANJING); } public void gs_EnterScene(Action action, Action error = null) { lock (this) { //TODO this.Client.LoginHandler.Request_EnterScene("" ,(r) => { this.LastEnterSceneResponse = r; action(r); }, (err) => { if (error != null) error(err); }); } } /// /// /// /// 0:普通进入,1:收到弹框点确认进副本 /// /// public void gs_ChangeSceneByTransport(string name, int type, Action action, Action error = null) { client.GameSocket.playerHandler.changeAreaRequest(name, type, (err, msg) => { if (type == 0) { client.GameSocket.playerHandler.changeAreaRequest(name, 1, (ex1, msg1) => { this.LastChangeAreaResponse = msg1; if (msg1 != null && action != null) { action(msg1); } if (ex1 != null && error != null) { error(ex1); } }); } else { this.LastChangeAreaResponse = msg; if (msg != null && action != null) { action(msg); } if (err != null) { if (error != null) { error(err); } else { log.Log(err.Message); } } } }); } //监听战斗层已创建 private void callback_client_OnCreateBattleClient(XmdsBattleClient.Battle.XmdsBattleClient obj) { if (CurrentNpcManager != null) { CurrentNpcManager.Dispose(); } CurrentNpcManager = new NpcManager(this); obj.Layer.LayerInit += callback_layer_OnInit; obj.Layer.ActorAdded += callback_layer_OnActorAdded; obj.Layer.DecorationChanged += callback_layer_OnDecorationChanged; obj.Layer.MessageReceived += callback_layer_MessageReceived; obj.Layer.OnScriptCommand += callback_layer_OnScriptCommand; ; } private void callback_layer_OnInit(CommonAI.ZoneClient.ZoneLayer layer) { CurrentZoneLayer = layer as HZZoneLayer; CurrentZoneActor = null; if (CurrentRegionManager != null) CurrentRegionManager.Dispose(); CurrentRegionManager = new RegionManager(this); Client.GameSocket.resourceHandler.queryAreaDataRequest((ex, msg) => { if (ex == null) { CurrentNpcManager.AddAreaNpcList(msg); } }); } private void callback_layer_OnActorAdded(CommonAI.ZoneClient.ZoneLayer layer, CommonAI.ZoneClient.ZoneActor actor) { CurrentZoneActor = layer.Actor; if (CurrentRegionManager != null) { CurrentRegionManager.callback_layer_OnActorAdded(actor); } } private void callback_layer_OnDecorationChanged(CommonAI.ZoneClient.ZoneLayer layer, CommonAI.ZoneClient.ZoneEditorDecoration ed) { } private void callback_layer_MessageReceived(ZoneLayer layer, CommonLang.Protocol.IMessage e) { if (e is ScriptCommandEvent) { // ScriptCommandEvent evt = e as ScriptCommandEvent; // string[] evt_param = evt.message.Split('|'); // if (evt_param.Length == 2) // { // object[] param = evt_param[1].Split(','); // string funcName = "GlobalHooks." + evt_param[0]; // if (LuaScriptMgr.Instance.IsFuncExists(funcName)) // { // LuaScriptMgr.Instance.CallLuaFunction(funcName, param); // } // } } else if (e is ScriptAddUnitEventsB2C) { CurrentNpcManager.AddNpc(e as ScriptAddUnitEventsB2C); } else if (e is ScriptRemoveUnitEventsB2C) { CurrentNpcManager.RemoveNpc(e as ScriptRemoveUnitEventsB2C); } } private void callback_layer_OnScriptCommand(ZoneLayer layer, string msg) { string[] cmds = msg.Split(new char[] { '|' }); if (cmds[0] == "ScriptAddUnitEvent") { CurrentNpcManager.AddNPC(cmds); } else if (cmds[0] == "ScriptRemoveUnitEvent") { } } public class NpcManager : IDisposable { private readonly BotClient bot; private HashMap AreaNpcList = new HashMap(); private HashMap ZoneNpcList = new HashMap(); internal NpcManager(BotClient bot) { this.bot = bot; } public void Dispose() { AreaNpcList.Clear(); ZoneNpcList.Clear(); } internal void AddAreaNpcList(pomelo.area.QueryAreaDataResponse msg) { AreaNpcList.Clear(); if (msg.s2c_npcs != null) { foreach (var npc in msg.s2c_npcs) { AreaNpcList.Add(npc.id, npc); } } } internal void AddNPC(string[] param) { int templateId = 0; int.TryParse(param[1], out templateId); //int x = 0; //int.TryParse(param[2], out x); //int y = 0; //int.TryParse(param[3], out y); // npcs[fake_id_count] = templateId; // --fake_id_count; } internal void AddNpc(ScriptAddUnitEventsB2C e) { ZoneNpcList.Put(e.ObjectID, e); } internal void RemoveNpc(ScriptRemoveUnitEventsB2C e) { ZoneNpcList.RemoveByKey(e.ObjectID); } /// /// 根据模板找单位 /// /// /// public Vector2 GetNpcByTemplateID(int templateID) { foreach (var u in ZoneNpcList.Values) { if (u.TemplateID == templateID) { return new Vector2(u.X, u.Y); } } if (bot.CurrentZoneLayer != null) { foreach (var u in AreaNpcList.Values) { if (u.templateId == templateID) { var vu = bot.CurrentZoneLayer.GetUnit(u.id); if (vu != null) { return new Vector2(vu.X, vu.Y); } } } var tu = bot.CurrentZoneLayer.GetUnitByTemplateID(templateID); if (tu != null) { return new Vector2(tu.X, tu.Y); } var fu = bot.CurrentZoneLayer.GetUnitFlagByTemplateID(templateID); if (fu != null) { return new Vector2(fu.X, fu.Y); } } return null; } } public class RegionManager : IDisposable { private readonly BotClient bot; /// /// 客户端本地维护的Region集合 /// private List mRegions = null; private List mSceneTransRegionList = null; internal RegionManager(BotClient bot) { this.bot = bot; this.mRegions = new List(bot.Client.BattleClient.Layer.Data.Regions); this.mSceneTransRegionList = new List(); foreach (var flag in bot.Client.BattleClient.Layer.Flags) { var ab = flag.EditorData.GetAbilityOf(); if (ab != null) { mSceneTransRegionList.Add(new SceneTransRegion(bot, flag, ab)); } } } public void Dispose() { mRegions.Clear(); mSceneTransRegionList.Clear(); } public List AllRegions() { return new List(mRegions); } public List AllTransports() { List ret = new List(); for (int i = 0; i < mSceneTransRegionList.Count; i++) { ret.Add(mSceneTransRegionList[i].Data.EditorData); } return ret; } public bool CheckTrans(int type, bool force_trans, Action error = null) { for (int i = 0; i < mSceneTransRegionList.Count; i++) { if (mSceneTransRegionList[i].CheckTrans(type, force_trans, error)) { return true; } } return false; } internal void Update() { for (int i = 0; i < mSceneTransRegionList.Count; i++) { mSceneTransRegionList[i].Update(); } } /// /// 监听主角进入 /// /// internal void callback_layer_OnActorAdded(CommonAI.ZoneClient.ZoneActor actor) { for (int i = 0; i < mSceneTransRegionList.Count; i++) { mSceneTransRegionList[i].BindActor(actor); } } private class SceneTransRegion { private readonly BotClient bot; private AbilityData m_Ability = null; private ZoneFlag m_Data = null; private CommonAI.ZoneClient.ZoneActor mActor = null; private float mRadius = 0; private bool mSendMsg = true; public AbilityData Ability { get { return m_Ability; } } public ZoneFlag Data { get { return m_Data; } } internal SceneTransRegion(BotClient bot, ZoneFlag rd, AbilityData data) { this.bot = bot; this.m_Ability = data; this.m_Data = rd; this.mRadius = m_Data.EditorData.Radius; } internal void BindActor(CommonAI.ZoneClient.ZoneActor actor) { this.mActor = actor; } internal void Update() { if (mActor != null) { if (CMath.intersectRound(m_Data.X, m_Data.Y, mRadius, mActor.X, mActor.Y, mActor.BodySize)) { if (mSendMsg == false) { mSendMsg = true; SendTransRequest(1, false); } } else { mSendMsg = false; } } } internal bool CheckTrans(int type, bool force_trans, Action error = null) { if (mActor != null) { if (CMath.intersectRound(m_Data.X, m_Data.Y, mRadius, mActor.X, mActor.Y, mActor.BodySize)) { return SendTransRequest(type, force_trans, error); } } return false; } //发送协议. private bool SendTransRequest(int type, bool force_trans, Action error = null) { if (m_Data.Enable || force_trans) { bot.gs_ChangeSceneByTransport(m_Data.Name, type, (msg) => { }, error); return true; } return false; } } } public enum DungeonType { 单人副本 = 1, 组队副本 = 2, 秘境副本 = 3, 超级副本 = 4, } public enum DungeonLevel { 普通 = 1, 精英 = 2, 英雄 = 3, } } }