using CommonAI.Zone; using CommonAI.Zone.Helper; using CommonAI.Zone.ZoneEditor; using CommonAIServer.Connector.Client; using CommonLang; using CommonLang.Log; using CommonNetwork.Sockets; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace XmdsServerTestBots.Bot { public class BotPlayer : IDisposable { private static Random random = new Random(); private readonly Logger log; private readonly string mName; private readonly NetTestClient mClient; private readonly int mFixedIntervalMS; private System.Threading.Timer mTimer; private long mLastUpdateTime; public string Name { get { return mName; } } public bool IsRunning { get { return mClient.Client.Session.IsConnected; } } public BotPlayer(string name, string roomID, UnitInfo unit, int force, EditorTemplates dataroot, string connectString) { this.log = LoggerFactory.GetLogger("Bot[" + name + "]"); CommonAI.ZoneServer.CreateUnitInfoR2B ret = new CommonAI.ZoneServer.CreateUnitInfoR2B(); ret.UnitTemplateID = unit.TemplateID; ret.Force = (byte)force; this.mFixedIntervalMS = (1000 / dataroot.Templates.CFG.SYSTEM_FPS); this.mName = name; this.mClient = new NetTestClient(name, roomID, typeof(NetSession).FullName, connectString, mFixedIntervalMS, 20, ret, false, null, dataroot); this.mClient.Client.Layer.ActorAdded += Layer_ActorAdded; this.mClient.Client.Disconnectd += Client_Disconnectd; } private void Client_Disconnectd(CommonAIClient.Client.BattleClient bc) { this.Dispose(); } private void Layer_ActorAdded(CommonAI.ZoneClient.ZoneLayer layer, CommonAI.ZoneClient.ZoneActor actor) { actor.SendUnitGuard(true); startMoveToTarget(); } public void Start() { this.mClient.Start(); this.mTimer = new System.Threading.Timer(update, this, mFixedIntervalMS, mFixedIntervalMS); } private void update(object state) { lock (this) { long curTime = CommonLang.CUtils.CurrentTimeMS; if (mLastUpdateTime == 0) { mLastUpdateTime = curTime; } int intervalMS = (int)(curTime - mLastUpdateTime); this.mLastUpdateTime = curTime; try { updateInTarget(intervalMS); this.mClient.Update(intervalMS); } catch (Exception err) { log.Error(err.Message, err); } } } public void SendLeaveRoom() { mClient.Client.SendLeaveRoom(); } public void Dispose() { try { lock (this) { mTimer.Dispose(); } } catch (Exception err) { log.Error(err.Message, err); } try { mClient.Stop(); mClient.Dispose(); } catch (Exception err) { log.Error(err.Message, err); } } private TimeExpire target_expire; private void startMoveToTarget() { var list = new List(mClient.Client.Layer.Data.Regions); CUtils.RandomList(random, list); foreach (var rd in list) { foreach (var ab in rd.GetAbilities()) { if (ab is SpawnUnitAbilityData) { var suab = ab as SpawnUnitAbilityData; if (suab.Force != mClient.Client.Actor.Force) { target_expire = new TimeExpire(rd, random.Next(10000, 100000)); mClient.Client.Actor.SendUnitAttackMoveTo(rd.X, rd.Y, true); return; } } } } } private void updateInTarget(int intervalMS) { if (target_expire != null && target_expire.Update(intervalMS)) { var rg = target_expire.Tag; var actor = mClient.Client.Actor; startMoveToTarget(); // if (CMath.includeRoundPoint(actor.X, actor.Y, actor.Info.GuardRange ,rg.X, rg.Y)) // { // // } } } /* public class MoveAgent { public delegate void UpdateAction(float x, float y, object ud); public delegate void EndAction(bool complete, float x, float y, object ud); UpdateAction updateAction; EndAction endAction; object userdata = null; float speed = 0; //private List wayPoints; bool isActor = false; List path; bool active = false; private float mEndDistance; public bool IsActive { get { return active; } } public MoveAgent(bool isActor, UpdateAction updateAction, EndAction endAction) { this.isActor = isActor; this.updateAction = updateAction; this.endAction = endAction; path = new List(); } public List StartSeek(float fromX, float fromY, float toX, float toY, float speed, float endDis, object ud) { if (active) { fromX = path[0].x; fromY = path[0].y; } AstarManhattan.MWayPoint wayPoints; AstarManhattan.FindPathResult ret = layer.FindPathResult(fromX, fromY, toX, toY, out wayPoints); if (ret == AstarManhattan.FindPathResult.Destination) { path.Clear(); path.Add(new Vector2(toX, toY)); } else if (ret == AstarManhattan.FindPathResult.Cross) { //已经取过一次,不需要重复取.Editor by Alex.Yu //wayPoints = layer.FindPath(fromX, fromY, toX, toY); path.Clear(); path.Add(new Vector2(fromX, fromY)); do { path.Add(new Vector2(wayPoints.PosX, wayPoints.PosY)); wayPoints = wayPoints.Next; } while (wayPoints != null); //path.Add(new Vector2(toX, toY)); } else { return null; } this.speed = speed; this.mEndDistance = endDis; this.userdata = ud; active = true; return path; } public void update(int deltatime) { if (!active) return; Vector2 pos = path[0]; float length = speed * deltatime / 1000f; if (length > 0 && path.Count > 1) { float l = Vector2.Distance(path[1], path[0]); if (l <= length) { path.RemoveAt(0); } else { path[0] = Vector2.MoveTowards(path[0], path[1], length);//path[0] + (path[1] - path[0]).normalized * length; } } //pos = path[0] - pos; //pos = path[0]; updateAction(path[0].x, path[0].y, userdata); if (path.Count < 2) { StopSeek(true, path[0].x, path[0].y, userdata); } else if (mEndDistance > 0) { if (path.Count == 2) { if (Vector2.Distance(path[0], path[1]) <= mEndDistance) { StopSeek(true, path[0].x, path[0].y, userdata); } } } } private void StopSeek(bool complete, float x, float y, object ud) { if (active) { path.Clear(); //updateAction = null; active = false; if (endAction != null) endAction(complete, 0, 0, ud); userdata = null; } } /// /// 外部打断寻路. /// /// /// /// public void StopSeek(float x = 0, float y = 0, object ud = null) { this.StopSeek(false, x, y, ud); } }*/ } }