using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Drawing.Drawing2D; using CommonAI.RTS; using CommonLang.Vector; using System.IO; using GameEditorPlugin.Win32.Runtime; using CommonFroms.Utils; using CommonLang.Log; using CommonAI.Zone; using GameEditorPlugin; using CommonLang; using GameEditorPlugin.Win32.BattleClient; using System.Runtime.InteropServices; using CommonFroms; using CommonAI.ZoneClient; using CommonAIEditor; using CommonAI.Zone.Replay; using GameEditorPlugin.Win32; using CommonAI.Zone.ZoneEditor; using CommonFroms.G2D; using CommonAI.ZoneClient.Agent; using static CommonAI.ZoneClient.ZoneUnit; namespace GameEditorPlugin.Win32.Runtime { public partial class FormRuntimeGameLocal : Form { private readonly DirectoryInfo dataDir; private int sceneID; private RuntimeGameLocal world; private bool step1 = false; private float TurboX = 1; private bool recorder; private ConsoleOutput console; private long lastUpdateTimeMS; private float mouseX, mouseY; private Vector2 pic_lastMouesDown; private Vector2 pic_lastCameraPos; public EditorScene Zone { get { return world.Battle.Zone; } } public RuntimeGameLocal Battle { get { return world; } } public PointF MousePos { get { return new PointF(mouseX, mouseY); } } public bool IsFreeView { get; set; } protected ZoneObject SelectedZoneObject { get { return propertyGrid_selected.SelectedObject as ZoneObject; } } public FormRuntimeGameLocal() : this(null, 0, false) { } public FormRuntimeGameLocal(DirectoryInfo data_dir, int sceneID, bool recorder = false) { this.dataDir = data_dir; this.sceneID = sceneID; this.IsFreeView = false; this.DoubleBuffered = true; this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); InitializeComponent(); if (dataDir == null) return; this.console = new ConsoleOutput(); this.recorder = recorder; this.pictureBox1.MouseWheel += pictureBox1_MouseWheel; this.pictureBox1.KeyDown += pictureBox1_KeyDown; this.Disposed += FormRuntimeGameLocal_Disposed; } private void FormRuntimeGameLocal_Disposed(object sender, EventArgs e) { if (this.world != null) { try { this.world.Dispose(); } catch (Exception err) { MessageBox.Show(err.Message + "\n" + err.StackTrace); } } } private void FormRuntimeGameLocal_Load(object sender, EventArgs e) { if (dataDir == null) return; try { EditorTemplates templates = new EditorTemplates(dataDir.FullName, TemplateManager.MessageCodec); templates.LoadAllTemplates(false, true); CommonAI.Zone.Replay.BattleRecorder rec = null; if (recorder) { string rec_name = string.Format("scene_{0}_{1}.rec", sceneID, CUtils.FormatTime(DateTime.Now)); rec = new CommonAI.Zone.Replay.BattleRecorder(templates.Templates, sceneID, rec_name); FileStream fos = new FileStream(dataDir.Parent.FullName + "\\" + rec.Name, FileMode.CreateNew, FileAccess.Write); rec.SetOut(fos); this.Disposed += (object sender2, EventArgs e2) => { try { fos.Flush(); fos.Close(); } catch (Exception ) { } try { fos.Dispose(); } catch (Exception ) { } }; } this.world = new RuntimeGameLocal(templates, sceneID, rec); // this.world.ShowTerrain = true; // this.world.ShowGrid = chk_ShowGrid.Checked; // this.world.ShowAttackRange = chkShowAttackRangeToolStripMenuItem.Checked; // this.world.ShowDamageRange = chkShowDamageRange.Checked; // this.world.ShowGuardRange = chkShowGuardRangeToolStripMenuItem.Checked; // this.world.ShowHP = chkShowHP.Checked; // this.world.ShowName = chkShowName.Checked; // this.world.ShowZ = chkShowZ.Checked; // this.world.ShowLog = chkShowLog.Checked; // this.world.ShowAllLog = chkShowLogToolStripMenuItem.Checked; this.world.GenShowItems(this.toolStripDropDownButton1); this.world.Layer.LayerInit += this.Layer_LayerInit; this.world.Layer.ActorAdded += this.Layer_ActorAdded; foreach (SyncMode mode in Enum.GetValues(typeof(SyncMode))) { ToolStripButton item = new ToolStripButton(mode.ToString()); item.Tag = mode; item.Click += item_SyncMode_Click; item.CheckOnClick = true; drop_SyncMode.DropDownItems.Add(item); if (world.Layer.ActorSyncMode == mode) { item.Checked = true; } } this.world.BindMessageFilter(pictureBox1); this.OnBattleCreated(world); this.timer2.Interval = (int)(1000f / world.Templates.Templates.CFG.SYSTEM_FPS); this.timer2.Enabled = true; this.timer2.Start(); } catch (Exception err) { MessageBox.Show(err.Message + "\n" + err.StackTrace); } } private void FormRuntimeGameLocal_Shown(object sender, EventArgs e) { if (dataDir == null) return; console.DockTo = this; console.Show(); } private void FormRuntimeGameLocal_FormClosed(object sender, FormClosedEventArgs e) { if (dataDir == null) return; console.Close(); if (this.world != null) { this.world.UnbindMessageFilter(); } } //--------------------------------------------------------------------------------------- #region LayerEvents protected virtual void OnBattleCreated(RuntimeGameLocal battle) { } protected virtual void Layer_LayerInit(ZoneLayer layer) { float scale = Math.Max( ((float)pictureBox1.Width) / world.Width, ((float)pictureBox1.Height) / world.Height); this.world.setCameraScale(scale, scale); } protected virtual void Layer_ActorAdded(ZoneLayer layer, ZoneActor actor) { actor.IsSkillAutoFocusTarget = btn_IsAutoFocusTarget.Checked; actor.SendUnitGuard(btn_AutoAttack.Checked); resetSkills(actor); actor.OnSkillChanged += Actor_OnSkillChanged; } protected virtual void Actor_OnSkillChanged(SkillOption op, ZoneUnit unit, int baseSkillID, params int[] skills) { resetSkills(unit as ZoneActor); } //--------------------------------------------------------------------------------------- protected virtual void resetSkills(ZoneActor actor) { toolStripActorSkills.Items.Clear(); int i = 1; using (var list = ListObjectPool.AllocAutoRelease()) { actor.GetSkillStatus(list); foreach (var skill in list) { ToolStripButton tb = new ToolStripButton(i.ToString()); tb.DisplayStyle = ToolStripItemDisplayStyle.Text; tb.ToolTipText = skill.Data.ToString(); tb.Tag = skill; tb.BackColor = Color.Black; tb.ForeColor = Color.White; tb.Click += new EventHandler((o, e) => { if (SelectedZoneObject != null) { actor.SendUnitLaunchSkill(skill.Data.ID, SelectedZoneObject.ObjectID); } else { actor.SendUnitLaunchSkill(skill.Data.ID, mouseX, mouseY); } }); toolStripActorSkills.Items.Add(tb); i++; } } } protected virtual void setSelectedObject(ZoneObject obj) { propertyGrid_selected.SelectedObject = obj; if (obj != null) { lbl_selected.Text = obj.Name; } else { lbl_selected.Text = ""; } } #endregion //--------------------------------------------------------------------------------------- #region PictureBoxEvents // timer 2 for render system protected virtual void timerUpdate_Tick(object sender, EventArgs e) { pictureBox1.Refresh(); btnTurbo.Text = "加速x" + TurboX; if ((!this.Visible) || (this.WindowState == FormWindowState.Minimized)) { world.Pause = true; } else { world.Pause = !(btn_Play.Checked || step1); step1 = false; } } protected virtual void pictureBox1_MouseDown(object sender, MouseEventArgs e) { pictureBox1.Focus(); try { pic_lastMouesDown = new Vector2(e.Location.X, e.Location.Y); if (world != null) { float wx = mouseX = world.screenToWorldX(e.X); float wy = mouseY = world.screenToWorldY(e.Y); pic_lastCameraPos = new Vector2(world.CameraX, world.CameraY); if (e.Button == MouseButtons.Left) { if (Keyboard.IsShiftDown) { if (world.Client.Actor != null) world.Client.Actor.SendUnitLaunchNormalAttack(wx, wy); } else { DisplayLayerObject selected = world.PickObject(wx, wy); ZoneItem item = pictureBox1_CheckPickItem(); if (item != null) { if (world.Client.Actor != null) { world.Client.Actor.SendUnitPickObject(item.ObjectID); } setSelectedObject(item); } else if (selected is DisplayGameUnit) { if (world.Client.Actor != null) { DisplayGameUnit su = selected as DisplayGameUnit; if (su.Data.Force != world.Client.Actor.Force) { world.Client.Actor.SendUnitFocuseTarget(selected.ObjectID); } else { world.Client.Actor.SendUnitPickObject(selected.ObjectID); } } setSelectedObject((selected as DisplayGameUnit).Data); } else if (selected is DisplayGameItem) { if (world.Client.Actor != null) { world.Client.Actor.SendUnitPickObject(selected.ObjectID); } setSelectedObject((selected as DisplayGameItem).Data); } else if (selected is DisplayGameSpell) { setSelectedObject((selected as DisplayGameSpell).Data); } else { setSelectedObject(null); } } } else if (e.Button == MouseButtons.Right) { if (world.Client.Actor != null) { if (Keyboard.GetKeyState(Keys.A)) { if (world.Client.Actor.IsGuard) { world.Client.Actor.SendUnitAttackMoveTo(wx, wy, true); } else { world.Client.Actor.AddAgent(new ActorMoveAgent(wx, wy, world.CellW / 10f)); } } else if (world.Client.Actor.IsGuard) { world.Client.Actor.SendUnitAttackMoveTo(wx, wy, false); } else { world.Client.Actor.SendUnitAxis( mouseX - world.Client.Actor.X, mouseY - world.Client.Actor.Y); } } } } } catch (Exception err) { Console.WriteLine(err.Message); } } protected virtual void pictureBox1_MouseMove(object sender, MouseEventArgs e) { try { if (world != null) { float wx = mouseX = world.screenToWorldX(e.X); float wy = mouseY = world.screenToWorldY(e.Y); if (world.Client.Actor == null || this.IsFreeView) { if (e.Button == System.Windows.Forms.MouseButtons.Right) { if (pic_lastMouesDown != null) { float x = pic_lastCameraPos.X + world.screenToWorldSizeX(pic_lastMouesDown.X - e.X); float y = pic_lastCameraPos.Y + world.screenToWorldSizeY(pic_lastMouesDown.Y - e.Y); world.setCamera(x, y); } } } if (world.Client.Actor != null) { if (Keyboard.IsShiftDown) { world.Client.Actor.SendUnitFaceTo(wx, wy); } if (e.Button == MouseButtons.Left) { } else if (e.Button == MouseButtons.Right) { if (world.Client.Actor.IsGuard) { //world.Client.Actor.SendUnitMove(wx, wy); } else { world.Client.Actor.SendUnitAxis((float)Math.Atan2( mouseY - world.Client.Actor.Y, mouseX - world.Client.Actor.X)); } } pictureBox1_CheckPickItem(); } } } catch (Exception err) { Console.WriteLine(err.Message); } } protected virtual void pictureBox1_MouseUp(object sender, MouseEventArgs e) { try { pic_lastMouesDown = null; pic_lastCameraPos = null; if (world != null && world.Client.Actor != null) { if (world.Client.Actor.IsGuard) { } else { world.Client.Actor.SendUnitStopMove(); } } } catch (Exception err) { Console.WriteLine(err.Message); } } protected virtual void pictureBox1_MouseWheel(object sender, MouseEventArgs e) { if (world != null) { try { int d = CMath.getDirect(e.Delta); if (d > 0) { float newD = world.getCameraScale() * 1.1f; world.setCameraScale(newD, newD); } else if (d < 0) { float newD = world.getCameraScale() / 1.1f; world.setCameraScale(newD, newD); } } catch (Exception err) { Console.WriteLine(err.Message); } } } protected virtual void pictureBox1_KeyDown(object sender, KeyEventArgs e) { try { if (world != null) { if (e.KeyCode == Keys.Space) { btn_Step_Click(btn_Step, e); } else { if (world.Client.Actor != null) { if (e.Shift) { world.ActorUseItem(e); } else { if (SelectedZoneObject != null) { world.ActorLaunchSkill(e, SelectedZoneObject); } else { world.ActorLaunchSkill(e, mouseX, mouseY); } } } } } } catch (Exception err) { Console.WriteLine(err.Message); } } protected virtual void pictureBox1_Paint(object sender, PaintEventArgs e) { if (world != null) { try { long curTime = CUtils.CurrentTimeMS; int intervalMS = (int)Math.Min(curTime - lastUpdateTimeMS, timer2.Interval); lastUpdateTimeMS = curTime; world.update(intervalMS, TurboX); world.setWindow(new RectangleF(0, 0, pictureBox1.Width, pictureBox1.Height)); if (world.Layer.Actor != null) { world.setCamera(world.Layer.Actor.X, world.Layer.Actor.Y); } if (!chkNoRender.Checked) { world.render(e.Graphics); } pictureBox1_CheckPickItem(); } catch (Exception err) { timer2.Stop(); MessageBox.Show(err.Message + "\n" + err.StackTrace); } } } protected virtual ZoneItem pictureBox1_CheckPickItem() { if (world.Battle.Actor != null) { pictureBox1.Cursor = Cursors.Default; ZoneItem item = world.Battle.Layer.GetNearPickableItem(world.Battle.Actor); if (item != null) { if (CMath.includeRoundPoint(item.X, item.Y, item.Info.BodySize, mouseX, mouseY)) { pictureBox1.Cursor = Cursors.Hand; return item; } } } return null; } #endregion //------------------------------------------------------------------------------------ #region MenuEvents protected virtual void btn_SkipClientEvent_Click(object sender, EventArgs e) { if (world != null) { world.SkipClientEvent(); } } protected virtual void btn_Stop_Click(object sender, EventArgs e) { if (btn_Play.Checked) { } } protected virtual void btn_Step_Click(object sender, EventArgs e) { if (btn_Play.Checked) { btn_Play.Checked = false; } step1 = true; } protected virtual void btn_AutoAttack_Click(object sender, EventArgs e) { if (world != null && world.Client.Actor != null) { world.Client.Actor.SendUnitGuard(btn_AutoAttack.Checked); } } protected virtual void btn_IsAutoFocusTarget_ToolStripMenuItem_Click(object sender, EventArgs e) { if (world.Layer.Actor != null) { world.Layer.Actor.IsSkillAutoFocusTarget = btn_IsAutoFocusTarget.Checked; } } protected virtual void btn_CleanBuff_Click(object sender, EventArgs e) { if (world.Layer.Actor != null) { using (var list = ListObjectPool.AllocAutoRelease()) { world.Layer.Actor.GetBuffStatus(list); foreach (ZoneUnit.BuffState bs in list) { world.Layer.Actor.SendCancelBuff(bs.Data.ID); } } } } protected virtual void pickUnitToolStripMenuItem_Click(object sender, EventArgs e) { if (world != null && world.Client.Actor != null) { if (world.SelectedObject != null && world.SelectedObject is DisplayGameUnit) { DisplayGameUnit su = world.SelectedObject as DisplayGameUnit; world.Client.Actor.SendUnitPickObject(su.ObjectID); } } } protected virtual void item_SyncMode_Click(object sender, EventArgs e) { ToolStripButton item = sender as ToolStripButton; if (item != null) { world.Layer.ActorSyncMode = (SyncMode)item.Tag; } foreach (ToolStripButton btn in drop_SyncMode.DropDownItems) { btn.Checked = ((SyncMode)btn.Tag == world.Layer.ActorSyncMode); } } #endregion //------------------------------------------------------------------------------------ #region QuestEmulate protected virtual void btn_QuestAccpetR2B_Click(object sender, EventArgs e) { if (world.Battle.Actor != null) { string quest = G2DTextDialog.Show("任务ID", "模拟【游戏服->】接取任务"); if (quest != null) { Zone.QuestAdapter.OnQuestAcceptedHandler(world.Battle.Actor.PlayerUUID, quest); } } } protected virtual void btn_QuestStatusChangeR2B_Click(object sender, EventArgs e) { if (world.Battle.Actor != null) { string quest = G2DTextDialog.Show("任务ID\r\nKey\r\nValue", "模拟【游戏服->】任务状态改变"); if (quest != null) { string[] kvs = quest.Split(new char[] { '\n' }, 3, StringSplitOptions.RemoveEmptyEntries); if (kvs.Length >= 3) { Zone.QuestAdapter.OnQuestStatusChangedHandler(world.Battle.Actor.PlayerUUID, kvs[0], kvs[1], kvs[2]); } } } } protected virtual void btn_QuestCommitR2B_Click(object sender, EventArgs e) { if (world.Battle.Actor != null) { string quest = G2DTextDialog.Show("任务ID", "模拟【游戏服->】提交任务"); if (quest != null) { Zone.QuestAdapter.OnQuestCommittedHandler(world.Battle.Actor.PlayerUUID, quest); } } } protected virtual void btn_QuestDropR2B_Click(object sender, EventArgs e) { if (world.Battle.Actor != null) { string quest = G2DTextDialog.Show("任务ID", "模拟【游戏服->】放弃任务"); if (quest != null) { Zone.QuestAdapter.OnQuestDroppedHandler(world.Battle.Actor.PlayerUUID, quest); } } } #endregion //------------------------------------------------------------------------------------ #region Turbo private void btn_1X_Click(object sender, EventArgs e) { TurboX = 1; } private void btn_2X_Click(object sender, EventArgs e) { TurboX = 2; } private void btn_3X_Click(object sender, EventArgs e) { TurboX = 3; } private void btn_4X_Click(object sender, EventArgs e) { TurboX = 4; } private void btn_5X_Click(object sender, EventArgs e) { TurboX = 5; } private void btn_10X_Click(object sender, EventArgs e) { TurboX = 10; } private void btn_0_5X_Click(object sender, EventArgs e) { TurboX = 0.5f; } private void btn_0_1X_Click(object sender, EventArgs e) { TurboX = 0.1f; } private void gCToolStripMenuItem_Click(object sender, EventArgs e) { System.GC.Collect(); } private void btn_TurboX_ToolStripMenuItem_Click(object sender, EventArgs e) { string turbo = G2DTextDialog.Show(TurboX.ToString(), "设置加速倍率"); float turbox = 1; if (turbo != null && float.TryParse(turbo, out turbox)) { this.TurboX = turbox; } } #endregion //------------------------------------------------------------------------------------ } }