// 特殊状態を付加 public void AddCondition(string cname, int ltime, double clevel = Constants.DEFAULT_LEVEL, string cdata = "") { var new_condition = new Condition(); // 同じ特殊状態が既に付加されている? foreach (Condition cnd in colCondition.List) { if ((cnd.Name ?? "") == (cname ?? "")) { if (cnd.Lifetime < 0 || ltime < 0) { cnd.Lifetime = -1; } else { cnd.Lifetime = GeneralLib.MaxLng(cnd.Lifetime, ltime); } cnd.Name = cname; cnd.Level = clevel; cnd.StrData = cdata; return; } } // 特殊状態を付加 new_condition.Name = cname; new_condition.Lifetime = ltime; new_condition.Level = clevel; new_condition.StrData = cdata; colCondition.Add(new_condition, cname); }
// 「最後から選択」ボタンをクリック private void cmdSelectAll2_Click(object eventSender, EventArgs eventArgs) { foreach (var item in ListBoxItems) { item.ListItemFlag = false; } foreach (var item in ListBoxItems.Reverse().Take(MaxListItem)) { item.ListItemFlag = true; } UpdateList(); _lstItems.TopIndex = GeneralLib.MaxLng(_lstItems.Items.Count - 14, 0); }
// 「最後から選択」ボタンをクリック private void cmdSelectAll2_Click(object eventSender, EventArgs eventArgs) { short i; lstItems.Visible = false; var loopTo = (short)lstItems.Items.Count; for (i = 1; i <= loopTo; i++) { ItemFlag[i - 1] = false; Microsoft.VisualBasic.Compatibility.VB6.Support.SetItemString(lstItems, i - 1, " " + Strings.Mid(Microsoft.VisualBasic.Compatibility.VB6.Support.GetItemString(lstItems, i - 1), 2)); } var loopTo1 = (short)GeneralLib.MinLng(GUI.MaxListItem, lstItems.Items.Count); for (i = 1; i <= loopTo1; i++) { if (!ItemFlag[lstItems.Items.Count - i]) { ItemFlag[lstItems.Items.Count - i] = true; Microsoft.VisualBasic.Compatibility.VB6.Support.SetItemString(lstItems, lstItems.Items.Count - i, "○" + Strings.Mid(Microsoft.VisualBasic.Compatibility.VB6.Support.GetItemString(lstItems, lstItems.Items.Count - i), 2)); } } lstItems.TopIndex = GeneralLib.MaxLng(lstItems.Items.Count - 14, 0); lstItems.Visible = true; SelectedItemNum = 0; var loopTo2 = (short)(lstItems.Items.Count - 1); for (i = 0; i <= loopTo2; i++) { if (ItemFlag[i]) { SelectedItemNum = (short)(SelectedItemNum + 1); } } lblNumber.Text = Microsoft.VisualBasic.Compatibility.VB6.Support.Format(SelectedItemNum) + "/" + Microsoft.VisualBasic.Compatibility.VB6.Support.Format(GUI.MaxListItem); if (SelectedItemNum > 0 & SelectedItemNum <= GUI.MaxListItem) { if (!cmdFinish.Enabled) { cmdFinish.Enabled = true; } } else if (cmdFinish.Enabled) { cmdFinish.Enabled = false; } }
// 「アビリティ一覧」コマンド private void AbilityListCommand() { LogDebug(); GUI.LockGUI(); while (true) { var currentAbility = GUI.AbilityListBox(SelectedUnit, new UnitAbilityList(AbilityListMode.List, SelectedUnit), Expression.Term("アビリティ", SelectedUnit) + "一覧", "一覧"); if (currentAbility == null) { SelectedAbility = 0; // キャンセル if (SRC.AutoMoveCursor) { GUI.RestoreCursorPos(); } GUI.CloseListBox(); GUI.UnlockGUI(); CommandState = "ユニット選択"; return; } SelectedAbility = currentAbility.AbilityNo(); // 指定されたアビリティの属性一覧を作成 { var list = new List <string>(); var i = 0; var u = SelectedUnit; var aclass = currentAbility.Data.Class; while (i <= Strings.Len(aclass)) { i = (i + 1); var buf = GeneralLib.GetClassBundle(aclass, ref i); var atype = ""; var alevel = ""; // 非表示? if (buf == "|") { break; } // M属性 if (Strings.Mid(aclass, i, 1) == "M") { i = (i + 1); buf = buf + Strings.Mid(aclass, i, 1); } // レベル指定 if (Strings.Mid(aclass, i + 1, 1) == "L") { i = (i + 2); var c = Strings.Mid(aclass, i, 1); while (Information.IsNumeric(c) || c == "." || c == "-") { alevel = alevel + c; i = (i + 1); c = Strings.Mid(aclass, i, 1); } i = (i - 1); } // 属性の名称 atype = Help.AttributeName(SelectedUnit, buf); if (Strings.Len(atype) > 0) { if (Strings.Len(alevel) > 0) { list.Add(GeneralLib.RightPaddedString(buf + "L" + alevel, 8) + atype + "レベル" + alevel); } else { list.Add(GeneralLib.RightPaddedString(buf, 8) + atype); } } } if (!Map.IsStatusView) { list.Add("射程範囲"); } if (list.Count > 0) { GUI.TopItem = 1; while (true) { if (list.Count == 1 && list[0] == "射程範囲") { i = 1; } else { i = GUI.ListBox(new ListBoxArgs { lb_caption = "アビリティ属性一覧", Items = list.Select(x => new ListBoxItem(x)).ToList(), lb_info = "属性 効果", lb_mode = "連続表示", }); } if (i == 0) { // キャンセル break; } else if (list[i - 1] == "射程範囲") { GUI.CloseListBox(); // 武器の射程を求めておく var min_range = currentAbility.AbilityMinRange(); var max_range = currentAbility.AbilityMaxRange(); // 射程範囲表示 if ((max_range == 1 || currentAbility.IsAbilityClassifiedAs("P")) && !currentAbility.IsAbilityClassifiedAs("Q")) { Map.AreaInReachable(SelectedUnit, max_range, u.Party + "の敵"); } else if (currentAbility.IsAbilityClassifiedAs("M直")) { Map.AreaInCross(u.x, u.y, min_range, max_range); } else if (currentAbility.IsAbilityClassifiedAs("M拡")) { Map.AreaInWideCross(u.x, u.y, min_range, max_range); } else if (currentAbility.IsAbilityClassifiedAs("M扇")) { Map.AreaInSectorCross(u.x, u.y, min_range, max_range, (int)currentAbility.AbilityLevel("M扇")); } else if (currentAbility.IsAbilityClassifiedAs("M全") || currentAbility.IsAbilityClassifiedAs("M線")) { Map.AreaInRange(u.x, u.y, max_range, min_range, "すべて"); } else if (currentAbility.IsAbilityClassifiedAs("M投")) { max_range = ((int)(max_range + currentAbility.AbilityLevel("M投"))); min_range = ((int)(min_range - currentAbility.AbilityLevel("M投"))); min_range = GeneralLib.MaxLng(min_range, 1); Map.AreaInRange(u.x, u.y, max_range, min_range, "すべて"); } else if (currentAbility.IsAbilityClassifiedAs("M移")) { Map.AreaInMoveAction(SelectedUnit, max_range); } else { Map.AreaInRange(u.x, u.y, max_range, min_range, u.Party + "の敵"); } GUI.Center(u.x, u.y); GUI.MaskScreen(); // 先行入力されていたクリックイベントを解消 GUI.DoEvents(); WaitClickMode = true; GUI.IsFormClicked = false; // クリックされるまで待つ while (!GUI.IsFormClicked) { GUI.Sleep(25); if (GUI.IsRButtonPressed(true)) { break; } } GUI.RedrawScreen(); if (list.Count == 1) { break; } } else { // 指定された属性の解説を表示 GUI.CloseListBox(); Help.AttributeHelp(SelectedUnit, GeneralLib.LIndex(list[i - 1], 1), currentAbility.AbilityNo(), true); } } } } } }
public void ShowItems(frmMain MainForm, ListBoxArgs args) { ListBoxItems = args.Items; HasFlag = args.HasFlag; var list = args.Items; var lb_caption = args.lb_caption; var lb_info = args.lb_info; var lb_mode = args.lb_mode; // コメントウィンドウの処理 if (Strings.InStr(lb_mode, "コメント") > 0) { if (!txtComment.Enabled) { txtComment.Enabled = true; txtComment.Visible = true; txtComment.Width = labCaption.Width; txtComment.Text = ""; txtComment.Top = lstItems.Top + lstItems.Height + 5; Height = Height + 40; } } else if (txtComment.Enabled) { txtComment.Enabled = false; txtComment.Visible = false; Height = Height - 40; } // キャプション Text = lb_caption; if (HasFlag) { labCaption.Text = " " + lb_info; } else { labCaption.Text = lb_info; } // リストボックスにアイテムを追加 lstItems.Visible = false; lstItems.Items.Clear(); if (HasFlag) { var itemTexts = list.Select(x => x.ListItemFlag ? $"×{x.Text}" : $" {x.Text}"); foreach (var text in itemTexts) { lstItems.Items.Add(text); } // XXX 後でクリアしてるから意味ないのでは? //i = (short)Information.UBound(list); //while (i > 0) //{ // if (!ListItemFlag[i]) // { // lstItems.SelectedIndex = i - 1; // break; // } // i = (short)(i - 1); //} } else { foreach (var text in list.Select(x => x.Text)) { lstItems.Items.Add(text); } } lstItems.SelectedIndex = -1; lstItems.Visible = true; //// コメント付きのアイテム? //if (Information.UBound(ListItemComment) != Information.UBound(list)) //{ // Array.Resize(ListItemComment, Information.UBound(list) + 1); //} // 先頭のアイテムを設定 if (GUI.TopItem > 0) { if (lstItems.TopIndex != GUI.TopItem - 1) { lstItems.TopIndex = GeneralLib.MaxLng(GeneralLib.MinLng(GUI.TopItem - 1, lstItems.Items.Count - 1), 0); } lstItems.SelectedIndex = Math.Min(lstItems.Items.Count, GUI.TopItem) - 1; } else if (lstItems.Items.Count > 0) { lstItems.SelectedIndex = 0; } // コメントウィンドウの表示 if (txtComment.Enabled) { txtComment.Text = SelectedItem?.ListItemComment; } // 最小化されている場合は戻しておく if (WindowState != FormWindowState.Normal) { WindowState = FormWindowState.Normal; Show(); } // 表示位置を設定 // メインが表示されているのに画面中央に持っていかれると違和感があるので、 // メインが表示されているときはそちらを基準にする if (MainForm.Visible) { if (HorizontalSize == "S") { Left = MainForm.Left; } else { Left = Math.Max( MainForm.Left, MainForm.Left + (MainForm.Width - Width) / 2); } } else { Left = (Screen.PrimaryScreen.Bounds.Width - Width) / 2; } if (MainForm.Visible) { if (MainForm.WindowState != FormWindowState.Minimized && VerticalSize == "M" && Strings.InStr(lb_mode, "中央表示") == 0) { Top = MainForm.Top + MainForm.Height - Height; } else { Top = Math.Max( MainForm.Top, MainForm.Top + (MainForm.Height - Height) / 2); } } else { Top = (Screen.PrimaryScreen.Bounds.Height - Height) / 2; } // XXX この辺からは親にいたほうがしっくりくる Commands.SelectedItem = 0; GUI.IsFormClicked = false; Application.DoEvents(); // リストボックスを表示 if (Strings.InStr(lb_mode, "表示のみ") > 0) { // 表示のみを行う GUI.IsMordal = false; Show(); lstItems.Focus(); //SetWindowPos(Handle.ToInt32(), -1, 0, 0, 0, 0, 0x3); Refresh(); //return ListBoxRet; } else if (Strings.InStr(lb_mode, "連続表示") > 0) { // 選択が行われてもリストボックスを閉じない GUI.IsMordal = false; if (!Visible) { Show(); //SetWindowPos(Handle.ToInt32(), -1, 0, 0, 0, 0, 0x3); lstItems.Focus(); } if (Strings.InStr(lb_mode, "カーソル移動") > 0) { if (SRC.AutoMoveCursor) { GUI.MoveCursorPos("ダイアログ"); } } while (!GUI.IsFormClicked) { Application.DoEvents(); //// 右ボタンでのダブルクリックの実現 //if ((GetAsyncKeyState(RButtonID) && 0x8000) == 0) //{ // is_rbutton_released = true; //} //else if (is_rbutton_released) //{ // IsFormClicked = true; //} Thread.Sleep(50); } } else { // 選択が行われた時点でリストボックスを閉じる GUI.IsMordal = false; Show(); //SetWindowPos(Handle.ToInt32(), -1, 0, 0, 0, 0, 0x3); lstItems.Focus(); if (Strings.InStr(lb_mode, "カーソル移動") > 0) { if (SRC.AutoMoveCursor) { GUI.MoveCursorPos("ダイアログ"); } } while (!GUI.IsFormClicked) { Application.DoEvents(); //// 右ボタンでのダブルクリックの実現 //if ((GetAsyncKeyState(RButtonID) && 0x8000) == 0) //{ // is_rbutton_released = true; //} //else if (is_rbutton_released) //{ // IsFormClicked = true; //} Thread.Sleep(50); } Hide(); if (Strings.InStr(lb_mode, "カーソル移動") > 0 && Strings.InStr(lb_mode, "カーソル移動(行きのみ)") == 0) { if (SRC.AutoMoveCursor) { GUI.RestoreCursorPos(); } } if (txtComment.Enabled) { txtComment.Enabled = false; txtComment.Visible = false; Height = Height - 40; } } }
protected override int ExecInternal() { // short unum; // short ux, uy; // var uclass = default(string); // string buf, opt = default; // short j, i, num; // int tmp; // int min_value; // short max_item; // int max_value; // int[] lv_list; // string[] list; // short ret; // bool without_refresh; // bool without_animation; var opt = ""; var num = ArgNum; for (var i = 5; i <= num; i++) { switch (GetArgAsString(i) ?? "") { case "密集": opt = opt + " 出撃"; break; case "非同期": opt = opt + " 非同期"; break; case "アニメ非表示": opt = opt + " アニメ非表示"; break; } } if (Strings.InStr(opt, "出撃") <= 0) { opt = opt + " 部隊配置"; } if (num < 4) { throw new EventErrorException(this, "Organizeコマンドの引数の数が違います"); } var unum = GetArgAsLong(2); if (unum < 1) { throw new EventErrorException(this, "ユニット数が不正です"); } var ux = GetArgAsLong(3); if (ux < 1) { ux = 1; } else if (ux > Map.MapWidth) { ux = Map.MapWidth; } var uy = GetArgAsLong(4); if (uy < 1) { uy = 1; } else if (uy > Map.MapHeight) { uy = Map.MapHeight; } var uclass = ""; if (num < 5) { uclass = "全て"; } else { var loopTo1 = num; for (var i = 5; i <= num; i++) { uclass = uclass + " " + GetArgAsString(i); } uclass = Strings.Trim(uclass); } Beginning: ; var units = SRC.UList.Items .Where(u => !(u.Party0 != "味方" || u.Status != "待機" || u.CountPilot() == 0)) // パイロット数のチェック .Where(u => !((u.Data.PilotNum == 1 || Math.Abs(u.Data.PilotNum) == 2) && u.CountPilot() < Math.Abs(u.Data.PilotNum) && !u.IsFeatureAvailable("1人乗り可能"))) .Where(u => { var td = Map.Terrain(1, 1); switch (td.Class) { case "宇宙": case "月面": if (u.get_Adaption(4) == 0) { return(false); } break; default: // 宇宙専用ユニットは宇宙でしか活動できない if (u.Transportation == "宇宙") { return(false); } // 空中マップか? if (td.Name == "空" && Map.Terrain((Map.MapWidth / 2), (Map.MapHeight / 2)).Name == "空" && Map.Terrain(Map.MapWidth, Map.MapHeight).Name == "空") { if (!u.IsTransAvailable("空")) { return(false); } } break; } return(true); }) .Where(u => { switch (uclass) { case "全て": case "": break; // 全てのユニット case "通常ユニット": if (u.IsFeatureAvailable("母艦")) { return(false); } break; case "母艦ユニット": if (!u.IsFeatureAvailable("母艦")) { return(false); } break; case "LL": if (u.Size == "XL") { return(false); } break; case "L": if (u.Size == "XL" || u.Size == "LL") { return(false); } break; case "M": if (u.Size == "XL" || u.Size == "LL" || u.Size == "L") { return(false); } break; case "S": if (u.Size == "XL" || u.Size == "LL" || u.Size == "L" || u.Size == "M") { return(false); } break; case "SS": if (u.Size == "XL" || u.Size == "LL" || u.Size == "L" || u.Size == "M" || u.Size == "S") { return(false); } break; default: // ユニットクラス指定した場合 // 指定されたクラスに該当するか return(GeneralLib.ToL(uclass).Any(x => x == u.Class0)); } return(true); }) .ToList(); if (!units.Any()) { return(EventData.NextID); } // レベルの一覧と最大値・最小値を求める var min_value = units.Min(u => u.MainPilot().Level + u.MainPilot().Exp); var max_value = units.Max(u => u.MainPilot().Level + u.MainPilot().Exp); // レベルにばらつきがある時にのみレベルでソート if (min_value != max_value) { units = units.OrderByDescending(u => u.MainPilot().Level + u.MainPilot().Exp).ToList(); } var list = units .Select(u => { var msg = ""; if (Expression.IsOptionDefined("等身大基準")) { msg = u.Nickname0 + Strings.Space(GeneralLib.MaxLng(52 - Strings.LenB(u.Nickname0), 1)) + GeneralLib.LeftPaddedString("" + u.MainPilot().Level, 2); } else { msg = u.Nickname0 + Strings.Space(GeneralLib.MaxLng(36 - Strings.LenB(u.Nickname0), 1)) + u.MainPilot().get_Nickname(false) + Strings.Space(GeneralLib.MaxLng(17 - Strings.LenB(u.MainPilot().get_Nickname(false)), 1)) + GeneralLib.LeftPaddedString("" + u.MainPilot().Level, 2); } return(new ListBoxItem(msg, u.ID)); }).ToList(); int ret; do { string info; if (Expression.IsOptionDefined("等身大基準")) { info = "ユニット Lv"; } else { info = "ユニット パイロット Lv"; } ret = GUI.MultiSelectListBox(new ListBoxArgs { lb_caption = "出撃ユニット選択", lb_info = info, Items = list, }, unum); if (ret == 0) { Commands.CommandState = "ユニット選択"; GUI.UnlockGUI(); Commands.ViewMode = true; while (Commands.ViewMode) { GUI.Sleep(50); } GUI.LockGUI(); goto Beginning; } }while (ret == 0); if (Strings.InStr(opt, "非同期") > 0) { GUI.Center(ux, uy); GUI.RefreshScreen(); } foreach (var u in list.Where(x => x.ListItemFlag) .Select(x => SRC.UList.Item(x.ListItemID))) { u.UsedAction = 0; u.UsedSupportAttack = 0; u.UsedSupportGuard = 0; u.UsedSyncAttack = 0; u.UsedCounterAttack = 0; u.StandBy(ux, uy, opt); } SRC.UList.CheckAutoHyperMode(); return(EventData.NextID); }
protected override int ExecInternal() { Pilot p = null; int num; switch (ArgNum) { case 3: { p = GetArgAsPilot(2); num = GetArgAsLong(3); break; } case 2: { var u = Event.SelectedUnitForEvent; if (u.CountPilot() > 0) { p = u.Pilots.First(); } num = GetArgAsLong(2); break; } default: throw new EventErrorException(this, "LevelUpコマンドの引数の数が違います"); } if (p != null) { var hp_ratio = 0d; var en_ratio = 0d; if (p.Unit is object) { { var u = p.Unit; hp_ratio = 100 * u.HP / (double)u.MaxHP; en_ratio = 100 * u.EN / (double)u.MaxEN; } } if (Expression.IsOptionDefined("レベル限界突破")) { p.Level = GeneralLib.MinLng(GeneralLib.MaxLng(p.Level + num, 1), 999); } else { p.Level = GeneralLib.MinLng(GeneralLib.MaxLng(p.Level + num, 1), 99); } // 闘争本能入手? if (p.IsSkillAvailable("闘争本能")) { if (p.MinMorale > 100) { if (p.Morale == p.MinMorale) { p.Morale = ((int)(p.MinMorale + 5d * p.SkillLevel("闘争本能", ref_mode: ""))); } } else if (p.Morale == 100) { p.Morale = ((int)(100d + 5d * p.SkillLevel("闘争本能", ref_mode: ""))); } } // SP&霊力をアップデート p.SP = p.SP; p.Plana = p.Plana; if (p.Unit is object) { { var u = p.Unit; u.Update(); u.HP = (int)(u.MaxHP * hp_ratio / 100d); u.EN = (int)(u.MaxEN * en_ratio / 100d); } SRC.PList.UpdateSupportMod(p.Unit); } } return(EventData.NextID); }
// 「アビリティ」コマンドを開始 // is_item=True の場合は「アイテム」コマンドによる使い捨てアイテムのアビリティ private void StartAbilityCommand(bool is_item = false) { string cap; GUI.LockGUI(); // 使用するアビリティを選択 if (is_item) { cap = "アイテム選択"; } else { cap = Expression.Term("アビリティ", SelectedUnit) + "選択"; } UnitAbility unitAbility; if (CommandState == "コマンド選択") { unitAbility = GUI.AbilityListBox(SelectedUnit, new UnitAbilityList(AbilityListMode.BeforeMove, SelectedUnit), cap, "移動前", is_item); } else { unitAbility = GUI.AbilityListBox(SelectedUnit, new UnitAbilityList(AbilityListMode.AfterMove, SelectedUnit), cap, "移動後", is_item); } // キャンセル if (unitAbility == null) { SelectedAbility = 0; if (SRC.AutoMoveCursor) { GUI.RestoreCursorPos(); } CancelCommand(); GUI.UnlockGUI(); return; } SelectedAbility = unitAbility.AbilityNo(); var currentUnit = SelectedUnit; // アビリティ専用BGMがあればそれを演奏 if (currentUnit.IsFeatureAvailable("アビリティBGM")) { var BGM = currentUnit.Features.Where(x => x.Name == "アビリティBGM") .Where(x => GeneralLib.LIndex(x.Data, 1) == unitAbility.Data.Name) .Select(x => Sound.SearchMidiFile(Strings.Mid(x.Data, Strings.InStr(x.Data, " ") + 1))) .FirstOrDefault(); if (!string.IsNullOrEmpty(BGM)) { Sound.ChangeBGM(BGM); } } // 射程0のアビリティはその場で実行 if (unitAbility.Data.MaxRange == 0) { SelectedTarget = SelectedUnit; // 変身アビリティであるか判定 var is_transformation = unitAbility.Data.Effects.Any(x => x.EffectType == "変身"); SelectedAbilityName = unitAbility.Data.Name; // 使用イベント Event.HandleEvent("使用", SelectedUnit.MainPilot().ID, SelectedAbilityName); if (SRC.IsScenarioFinished) { SRC.IsScenarioFinished = false; GUI.UnlockGUI(); return; } if (SRC.IsCanceled) { SRC.IsCanceled = false; WaitCommand(); return; } // アビリティを実行 SelectedUnit.ExecuteAbility(unitAbility, SelectedUnit); SelectedUnit = SelectedUnit.CurrentForm(); GUI.CloseMessageForm(); // 破壊イベント { var withBlock1 = SelectedUnit; if (withBlock1.Status == "破壊") { if (withBlock1.CountPilot() > 0) { Event.HandleEvent("破壊", withBlock1.MainPilot().ID); if (SRC.IsScenarioFinished) { SRC.IsScenarioFinished = false; GUI.UnlockGUI(); return; } if (SRC.IsCanceled) { SRC.IsCanceled = false; GUI.UnlockGUI(); return; } } WaitCommand(); return; } } // 使用後イベント { var withBlock2 = SelectedUnit; if (withBlock2.CountPilot() > 0) { Event.HandleEvent("使用後", withBlock2.MainPilot().ID, SelectedAbilityName); if (SRC.IsScenarioFinished) { SRC.IsScenarioFinished = false; GUI.UnlockGUI(); return; } if (SRC.IsCanceled) { SRC.IsCanceled = false; GUI.UnlockGUI(); return; } } } // 変身アビリティの場合は行動終了しない if (!is_transformation || CommandState == "移動後コマンド選択") { WaitCommand(); } else { if (SelectedUnit.Status == "出撃") { // カーソル自動移動 if (SRC.AutoMoveCursor) { GUI.MoveCursorPos("ユニット選択", SelectedUnit); } Status.DisplayUnitStatus(SelectedUnit); } else { Status.ClearUnitStatus(); } CommandState = "ユニット選択"; GUI.UnlockGUI(); } return; } // アビリティの射程を求めておく var min_range = unitAbility.AbilityMinRange(); var max_range = unitAbility.AbilityMaxRange(); { // マップ型アビリティかどうかで今後のコマンド処理の進行の仕方が異なる if (is_item) { if (unitAbility.IsAbilityClassifiedAs("M")) { SelectedCommand = "マップアイテム"; } else { SelectedCommand = "アイテム"; } } else { if (unitAbility.IsAbilityClassifiedAs("M")) { SelectedCommand = "マップアビリティ"; } else { SelectedCommand = "アビリティ"; } } // アビリティの効果範囲を設定 if (unitAbility.IsAbilityClassifiedAs("M直")) { Map.AreaInCross(currentUnit.x, currentUnit.y, min_range, max_range); } else if (unitAbility.IsAbilityClassifiedAs("M拡")) { Map.AreaInWideCross(currentUnit.x, currentUnit.y, min_range, max_range); } else if (unitAbility.IsAbilityClassifiedAs("M扇")) { Map.AreaInSectorCross(currentUnit.x, currentUnit.y, min_range, max_range, (int)unitAbility.AbilityLevel("M扇")); } else if (unitAbility.IsAbilityClassifiedAs("M移")) { Map.AreaInMoveAction(SelectedUnit, max_range); } else { Map.AreaInRange(currentUnit.x, currentUnit.y, max_range, min_range, "すべて"); } // 射程1の合体技はパートナーで相手を取り囲んでいないと使用できない if (unitAbility.IsAbilityClassifiedAs("合") && !unitAbility.IsAbilityClassifiedAs("M") && unitAbility.Data.MaxRange == 1) { foreach (var t in Map.AdjacentUnit(currentUnit)) { if (currentUnit.IsAlly(t)) { var partners = unitAbility.CombinationPartner(t.x, t.y); if (partners.Count == 0) { Map.MaskData[t.x, t.y] = true; } } } } } // ユニットがいるマスの処理 if (!unitAbility.IsAbilityClassifiedAs("M投") && !unitAbility.IsAbilityClassifiedAs("M線") && !unitAbility.IsAbilityClassifiedAs("M移")) { var loopTo2 = GeneralLib.MinLng(currentUnit.x + max_range, Map.MapWidth); for (var i = GeneralLib.MaxLng(currentUnit.x - max_range, 1); i <= loopTo2; i++) { var loopTo3 = GeneralLib.MinLng(currentUnit.y + max_range, Map.MapHeight); for (var j = GeneralLib.MaxLng(currentUnit.y - max_range, 1); j <= loopTo3; j++) { if (!Map.MaskData[i, j]) { var t = Map.MapDataForUnit[i, j]; if (t is object) { // 有効? if (unitAbility.IsAbilityEffective(t)) { Map.MaskData[i, j] = false; } else { Map.MaskData[i, j] = true; } } } } } } // 支援専用アビリティは自分には使用できない if (!Map.MaskData[currentUnit.x, currentUnit.y]) { if (unitAbility.IsAbilityClassifiedAs("援")) { Map.MaskData[currentUnit.x, currentUnit.y] = true; } } if (!Expression.IsOptionDefined("大型マップ")) { GUI.Center(currentUnit.x, currentUnit.y); } GUI.MaskScreen(); if (CommandState == "コマンド選択") { CommandState = "ターゲット選択"; } else { CommandState = "移動後ターゲット選択"; } // カーソル自動移動を行う? if (!SRC.AutoMoveCursor) { GUI.UnlockGUI(); return; } // 自分から最も近い味方ユニットを探す { Unit t = null; foreach (Unit u in SRC.UList.Items) { if (u.Status == "出撃" && u.Party == "味方") { if (Map.MaskData[u.x, u.y] == false && !ReferenceEquals(u, SelectedUnit)) { if (t is null) { t = u; } else if (Math.Pow(Math.Abs((SelectedUnit.x - u.x)), 2d) + Math.Pow(Math.Abs((SelectedUnit.y - u.y)), 2d) < Math.Pow(Math.Abs((SelectedUnit.x - t.x)), 2d) + Math.Pow(Math.Abs((SelectedUnit.y - t.y)), 2d)) { t = u; } } } } // 適当がユニットがなければ自分自身を選択 if (t is null) { t = SelectedUnit; } // カーソルを移動 GUI.MoveCursorPos("ユニット選択", t); // ターゲットのステータスを表示 if (!ReferenceEquals(SelectedUnit, t)) { Status.DisplayUnitStatus(t); } } GUI.UnlockGUI(); }
// スペシャルパワー自爆による自爆 public void SuicidalExplosion(bool is_event = false) { PilotMessage("自爆", msg_mode: ""); GUI.DisplaySysMessage(Nickname + "は自爆した。"); // ダメージ量設定 var dmg = HP; // 効果範囲の設定 Map.AreaInRange(x, y, 1, 1, ""); Map.MaskData[x, y] = true; // 爆発 GUI.EraseUnitBitmap(x, y); Effect.ExplodeAnimation(Size, x, y); // パーツ分離できれば自爆後にパーツ分離 if (IsFeatureAvailable("パーツ分離")) { var uname = GeneralLib.LIndex(FeatureData("パーツ分離"), 2); if (OtherForm(uname).IsAbleToEnter(x, y)) { Transform(uname); { var cf = CurrentForm(); cf.HP = cf.MaxHP; cf.UsedAction = cf.MaxAction(); } var fname = FeatureName("パーツ分離"); if (!SysMessageIfDefined(new string[] { "破壊時分離(" + Name + ")", "破壊時分離(" + fname + ")", "破壊時分離", "分離(" + Name + ")", "分離(" + fname + ")", "分離", })) { GUI.DisplaySysMessage(Nickname + "は破壊されたパーツを分離させた。"); } goto SkipSuicide; } } // 自分を破壊 HP = 0; GUI.UpdateMessageForm(this, u2: null); // 既に爆発アニメーションを表示しているので AddCondition("破壊キャンセル", 1, cdata: ""); Map.MapDataForUnit[x, y] = null; Die(); if (!is_event) { var u = Commands.SelectedUnit; Commands.SelectedUnit = this; Event.HandleEvent("破壊", MainPilot().ID); Commands.SelectedUnit = u; if (SRC.IsScenarioFinished) { SRC.IsScenarioFinished = false; return; } } SkipSuicide: ; // 周りのエリアに爆発効果を適用 var loopTo = Map.MapWidth; for (var i = 1; i <= loopTo; i++) { var loopTo1 = Map.MapHeight; for (var j = 1; j <= loopTo1; j++) { if (Map.MaskData[i, j]) { goto NextLoop; } var t = Map.MapDataForUnit[i, j]; if (t is null) { goto NextLoop; } { GUI.ClearMessageForm(); if (CurrentForm().Party == "味方" || CurrentForm().Party == "NPC") { GUI.UpdateMessageForm(t, CurrentForm()); } else { GUI.UpdateMessageForm(CurrentForm(), t); } // ダメージの適用 var prev_hp = t.HP; int tdmg; if (t.IsConditionSatisfied("無敵")) { tdmg = 0; } else if (t.IsConditionSatisfied("不死身")) { t.HP = GeneralLib.MaxLng(t.HP - dmg, 10); tdmg = prev_hp - t.HP; } else { t.HP = t.HP - dmg; tdmg = prev_hp - t.HP; } // 特殊能力「不安定」による暴走チェック if (t.IsFeatureAvailable("不安定")) { if (t.HP <= t.MaxHP / 4 && !t.IsConditionSatisfied("暴走")) { t.AddCondition("暴走", -1, cdata: ""); t.Update(); } } // ダメージを受ければ眠りからさめる if (t.IsConditionSatisfied("睡眠")) { t.DeleteCondition("睡眠"); } if (CurrentForm().Party == "味方" || CurrentForm().Party == "NPC") { GUI.UpdateMessageForm(t, CurrentForm()); } else { GUI.UpdateMessageForm(CurrentForm(), t); } if (t.HP > 0) { GUI.DrawSysString(t.x, t.y, SrcFormatter.Format(tdmg)); GUI.RefreshScreen(); } if (t.HP == 0) { if (t.IsUnderSpecialPowerEffect("復活")) { t.HP = t.MaxHP; t.RemoveSpecialPowerInEffect("破壊"); GUI.DisplaySysMessage(t.Nickname + "は復活した!"); goto NextLoop; } if (t.IsFeatureAvailable("パーツ分離")) { var uname = GeneralLib.LIndex(t.FeatureData("パーツ分離"), 2); if (t.OtherForm(uname).IsAbleToEnter(t.x, t.y)) { t.Transform(uname); { var cf = t.CurrentForm(); cf.HP = cf.MaxHP; cf.UsedAction = cf.MaxAction(); } GUI.DisplaySysMessage(t.Nickname + "は破壊されたパーツを分離させた。"); goto NextLoop; } } t.Die(); } if (!is_event) { var u = Commands.SelectedUnit; Commands.SelectedUnit = t.CurrentForm(); Commands.SelectedTarget = this; if (t.Status == "破壊") { GUI.DisplaySysMessage((string)(t.Nickname + "は破壊された")); Event.HandleEvent("破壊", t.MainPilot().ID); } else { GUI.DisplaySysMessage(t.Nickname + "は" + tdmg + "のダメージを受けた。;" + "残りHPは" + SrcFormatter.Format(t.HP) + "(損傷率 = " + 100 * (t.MaxHP - t.HP) / t.MaxHP + "%)"); Event.HandleEvent("損傷率", t.MainPilot().ID, "" + (int)(100 - t.HP * 100 / t.MaxHP)); } Commands.SelectedUnit = u; if (SRC.IsScenarioFinished) { SRC.IsScenarioFinished = false; return; } } } NextLoop: ; } } }
// 資金の量を変更する public void IncrMoney(int earnings) { Money = GeneralLib.MinLng(Money + earnings, 999999999); Money = GeneralLib.MaxLng(Money, 0); }
public void MoveUnitBitmap(Unit u, int x1, int y1, int x2, int y2, int wait_time0, int division) { int start_time = 0; int cur_time = 0; int wait_time = wait_time0 / division; SaveScreen(); using (var unitImage = new Bitmap(MapCellPx, MapCellPx)) { // ユニット画像を作成 using (var g = Graphics.FromImage(unitImage)) { DrawUnit(g, Map.CellAtPoint(u.x, u.y), u, new Rectangle(0, 0, unitImage.Width, unitImage.Height)); } // 移動の始点を設定 var xx = GUI.MapToPixelX(x1); var yy = GUI.MapToPixelY(y1); var vx = 0; var vy = 0; // 背景上の画像をまず消去 // (既に移動している場合を除く) if (ReferenceEquals(u, Map.MapDataForUnit[x1, y1])) { EraseUnitBitmap(x1, y1, false); } // 最初の移動方向を設定 if (Math.Abs((x2 - x1)) > Math.Abs((y2 - y1))) { if (x2 > x1) { vx = 1; } else { vx = -1; } vy = 0; } else { if (y2 > y1) { vy = 1; } else { vy = -1; } vx = 0; } if (wait_time > 0) { start_time = GeneralLib.timeGetTime(); } // 移動の描画 var loopTo = (division * GeneralLib.MaxLng(Math.Abs((x2 - x1)), Math.Abs((y2 - y1)))); for (var i = 1; i <= loopTo; i++) { using (var g = Graphics.FromImage(MainDoubleBuffer)) { // 画像を消去 var sourceRect = new Rectangle(xx, yy, MapCellPx, MapCellPx); g.DrawImage(MainBuffer, sourceRect, sourceRect, GraphicsUnit.Pixel); // 座標を移動 xx = (xx + MapCellPx * vx / division); yy = (yy + MapCellPx * vy / division); // 画像を描画 g.DrawImage(unitImage, xx, yy); } UpdataMain(); if (wait_time > 0) { do { Application.DoEvents(); cur_time = GeneralLib.timeGetTime(); }while (start_time + wait_time > cur_time); start_time = cur_time; } } // 2回目の移動方向を設定 if (Math.Abs((x2 - x1)) > Math.Abs((y2 - y1))) { if (y2 > y1) { vy = 1; } else { vy = -1; } vx = 0; } else { if (x2 > x1) { vx = 1; } else { vx = -1; } vy = 0; } // 移動の描画 var loopTo1 = (division * GeneralLib.MinLng(Math.Abs((x2 - x1)), Math.Abs((y2 - y1)))); for (var i = 1; i <= loopTo1; i++) { using (var g = Graphics.FromImage(MainDoubleBuffer)) { // 画像を消去 var sourceRect = new Rectangle(xx, yy, MapCellPx, MapCellPx); g.DrawImage(MainBuffer, sourceRect, sourceRect, GraphicsUnit.Pixel); // 座標を移動 xx = (xx + MapCellPx * vx / division); yy = (yy + MapCellPx * vy / division); // 画像を描画 g.DrawImage(unitImage, xx, yy); } UpdataMain(); if (wait_time > 0) { do { Application.DoEvents(); cur_time = GeneralLib.timeGetTime(); }while (start_time + wait_time > cur_time); start_time = cur_time; } } } // 画面が書き換えられたことを記録 GUI.ScreenIsSaved = false; }