public void SetElements(int[] elements) { if (elements.Any(x => x > 0)) { var ratedWeapons = Weapons .Select((wvm, i) => new { Rate = MH.ComputeSimpleDamage(wvm.Weapon, isSharpnessPlusOne, elements), Index = i }) .ToArray(); var orderedSubset = ratedWeapons .OrderByDescending(x => x.Rate) .Take(DisplayedWeaponCountPerCategory) .ToArray(); var maxRate = orderedSubset.First().Rate; foreach (var weapon in Weapons) { weapon.IsVisible = false; } var firstIndex = orderedSubset[0].Index; Weapons[firstIndex].DamageRate = maxRate; Weapons[firstIndex].DamageRateText = "MAX"; Weapons[firstIndex].IsVisible = true; foreach (var x in orderedSubset.Skip(1)) { Weapons[x.Index].DamageRate = x.Rate; Weapons[x.Index].DamageRateText = string.Format("{0:#.##} %", x.Rate * 100.0f / maxRate); Weapons[x.Index].IsVisible = true; } } else { foreach (var weapon in Weapons) { weapon.IsVisible = false; } } IsVisible = Weapons.Any(x => x.IsVisible); }
public bool CanTarget(ITargetable target) { // TODO - alliances return(target.Owner != Owner && Weapons.Any(c => !c.IsDestroyed && c.Template.ComponentTemplate.WeaponInfo.Targets.HasFlag(target.WeaponTargetType))); }
// 戦闘アニメを再生 public void PlayAnimation(string main_situation, string sub_situation = "", bool keep_message_form = false) { var in_bulk = false; // 戦闘アニメデータを検索 var anime = AnimationData(main_situation, sub_situation); // 見つからなかった場合は一括指定を試してみる if (string.IsNullOrEmpty(anime)) { switch (Strings.Right(main_situation, 4) ?? "") { case "(準備)": case "(攻撃)": case "(命中)": { anime = AnimationData(Strings.Left(main_situation, Strings.Len(main_situation) - 4), sub_situation); in_bulk = true; break; } case "(発動)": { anime = AnimationData(Strings.Left(main_situation, Strings.Len(main_situation) - 4), sub_situation); break; } } } anime = anime.Trim(); // 表示キャンセル if (string.IsNullOrEmpty(anime) || anime == "-") { return; } // マウスの右ボタンでキャンセル if (GUI.IsRButtonPressed()) { // アニメの終了処理はキャンセルしない if (main_situation != "終了" && Strings.Right(main_situation, 4) != "(終了)") { // 式評価のみ行う Expression.FormatMessage(ref anime); return; } } // メッセージウィンドウは表示されている? var is_message_form_opened = GUI.MessageFormVisible; // TODO Impl オブジェクト色等 //// オブジェクト色等を記録しておく //prev_obj_color = Event.ObjColor; //prev_obj_fill_color = Event.ObjFillColor; //prev_obj_fill_style = Event.ObjFillStyle; //prev_obj_draw_width = Event.ObjDrawWidth; //prev_obj_draw_option = Event.ObjDrawOption; //// オブジェクト色等をデフォルトに戻す //Event.ObjColor = ColorTranslator.ToOle(Color.White); //Event.ObjFillColor = ColorTranslator.ToOle(Color.White); //Event.ObjFillStyle = vbFSTransparent; //Event.ObjDrawWidth = 1; //Event.ObjDrawOption = ""; // 検索するシチュエーションが武器名かどうか調べる var is_weapon = Weapons.Any(w => main_situation == w.Name + "(攻撃)"); // 検索するシチュエーションがアビリティかどうか調べる var is_ability = Abilities.Any(a => main_situation == a.Data.Name + "(発動)"); // イベント用ターゲットを記録しておく var prev_selected_target = Event.SelectedTargetForEvent; // 攻撃でもアビリティでもない場合、ターゲットが設定されていなければ // 自分自身をターゲットに設定する // (発動アニメではアニメ表示にSelectedTargetForEventが使われるため) if (!is_weapon && !is_ability) { if (Event.SelectedTargetForEvent is null) { Event.SelectedTargetForEvent = this; } } // アニメ指定を分割 var animes = anime.Split(";").ToList(); try { var need_refresh = false; var wait_time = 0; var sname = ""; var buf = ""; foreach (var a in animes) { var animepart = a; // 最後に実行されたのがサブルーチン呼び出しかどうかを判定するため // サブルーチン名をあらかじめクリアしておく sname = ""; // 式評価 Expression.FormatMessage(ref animepart); // 画面クリア? if (Strings.LCase(animepart) == "clear") { GUI.ClearPicture(); need_refresh = true; goto NextAnime; } // 戦闘アニメ以外の特殊効果 switch (Strings.LCase(Strings.Right(GeneralLib.LIndex(animepart, 1), 4)) ?? "") { case ".wav": case ".mp3": { // 効果音 Sound.PlayWave(animepart); if (wait_time > 0) { if (need_refresh) { GUI.UpdateScreen(); need_refresh = false; } GUI.Sleep(wait_time); wait_time = 0; } goto NextAnime; } case ".bmp": case ".jpg": case ".gif": case ".png": { // カットインの表示 if (wait_time > 0) { animepart = (wait_time / 100d) + ";" + animepart; wait_time = 0; need_refresh = false; } else if (Strings.Left(animepart, 1) == "@") { need_refresh = false; } else { need_refresh = true; } GUI.DisplayBattleMessage("-", animepart, msg_mode: ""); goto NextAnime; } } switch (Strings.LCase(GeneralLib.LIndex(animepart, 1)) ?? "") { case "line": case "circle": case "arc": case "oval": case "color": case "fillcolor": case "fillstyle": case "drawwidth": { // 画面処理コマンド if (wait_time > 0) { animepart = (wait_time / 100d) + ";" + animepart; wait_time = 0; need_refresh = false; } else { need_refresh = true; } GUI.DisplayBattleMessage("-", animepart, msg_mode: ""); goto NextAnime; } case "center": { // 指定したユニットを中央表示 buf = Expression.GetValueAsString(GeneralLib.ListIndex(animepart, 2)); if (SRC.UList.IsDefined(buf)) { { var withBlock = SRC.UList.Item(buf); GUI.Center(withBlock.x, withBlock.y); GUI.RedrawScreen(); need_refresh = false; } } goto NextAnime; } case "keep": { // そのまま終了 break; } } // ウェイト? if (Information.IsNumeric(animepart)) { wait_time = (int)(100d * Conversions.ToDouble(animepart)); goto NextAnime; } // サブルーチンの呼び出しが確定 // 戦闘アニメ再生用のサブルーチン名を作成 sname = GeneralLib.LIndex(animepart, 1); if (Strings.Left(sname, 1) == "@") { sname = Strings.Mid(sname, 2); } else if (is_weapon) { // 武器名の場合 sname = "戦闘アニメ_" + sname + "攻撃"; } else { // その他の場合 // 括弧を含んだ武器名に対応するため、"("は後ろから検索 var idx = GeneralLib.InStr2(main_situation, "("); // 変形系のシチュエーションではサフィックスを無視 if (idx > 0) { switch (Strings.Left(main_situation, idx - 1) ?? "") { case "変形": case "ハイパーモード": case "ノーマルモード": case "パーツ分離": case "合体": case "分離": { idx = 0; break; } } } // 武器名(攻撃無効化)の場合もサフィックスを無視 if (idx > 0) { if (Strings.Mid(main_situation, idx) == "(攻撃無効化)") { idx = 0; } } if (idx > 0) { // サフィックスあり sname = "戦闘アニメ_" + sname + Strings.Mid(main_situation, idx + 1, Strings.Len(main_situation) - idx - 1); } else { sname = "戦闘アニメ_" + sname + "発動"; } } // サブルーチンが見つからなかった if (Event.FindNormalLabel(sname) == 0) { if (in_bulk) { // 一括指定を利用している場合 switch (Strings.Right(main_situation, 4) ?? "") { case "(準備)": { // 表示をキャンセル goto NextAnime; } case "(攻撃)": { // 複数のアニメ指定がある場合は諦めて他のものを使う if (animes.Count > 1) { goto NextAnime; } // そうでなければ「デフォルト」を使用 sname = "戦闘アニメ_デフォルト攻撃"; break; } case "(命中)": { // 複数のアニメ指定がある場合は諦めて他のものを使う if (animes.Count > 1) { goto NextAnime; } // そうでなければ「ダメージ」を使用 sname = "戦闘アニメ_ダメージ命中"; break; } } } else { if (wait_time > 0) { animepart = (wait_time / 100d) + ";" + animepart; wait_time = 0; } if (!GUI.MessageFormVisible) { if (ReferenceEquals(Commands.SelectedTarget, this)) { GUI.OpenMessageForm(this, u2: null); } else { GUI.OpenMessageForm(Commands.SelectedTarget, this); } } GUI.DisplayBattleMessage("-", animepart, msg_mode: ""); goto NextAnime; } } sname = "`" + sname + "`"; // 引数の構築 sname = sname + "," + string.Join(",", GeneralLib.ToList(animepart).Skip(1)); if (in_bulk) { sname = sname + ",`一括指定`"; } // 戦闘アニメ再生前にウェイトを入れる if (need_refresh) { GUI.UpdateScreen(); need_refresh = false; } if (wait_time > 0) { GUI.Sleep(wait_time); wait_time = 0; } // 画像描画が行われたかどうかの判定のためにフラグを初期化 GUI.IsPictureDrawn = false; // 戦闘アニメ再生 Event.SaveBasePoint(); Expression.CallFunction("Call(" + sname + ")", Expressions.ValueType.StringType, out buf, out _); Event.RestoreBasePoint(); // 画像を消去しておく if (GUI.IsPictureDrawn && Strings.LCase(buf) != "keep") { GUI.ClearPicture(); GUI.UpdateScreen(); } NextAnime: ; } // 戦闘アニメ再生後にウェイトを入れる? if (need_refresh) { GUI.UpdateScreen(); need_refresh = false; } if (wait_time > 0) { GUI.Sleep(wait_time); wait_time = 0; } // 画像を消去しておく if (GUI.IsPictureDrawn && string.IsNullOrEmpty(sname) && Strings.InStr(main_situation, "(準備)") == 0 && Strings.LCase(anime) != "keep") { GUI.ClearPicture(); GUI.UpdateScreen(); } // 最初から表示されていたのでなければメッセージウィンドウを閉じる if (!is_message_form_opened && !keep_message_form) { GUI.CloseMessageForm(); } //// オブジェクト色等を元に戻す //Event.ObjColor = prev_obj_color; //Event.ObjFillColor = prev_obj_fill_color; //Event.ObjFillStyle = prev_obj_fill_style; //Event.ObjDrawWidth = prev_obj_draw_width; //Event.ObjDrawOption = prev_obj_draw_option; // イベント用ターゲットを元に戻す Event.SelectedTargetForEvent = prev_selected_target; } catch (Exception ex) { // TODO Handle error //if (Strings.Len(Event.EventErrorMessage) > 0) //{ // Event.DisplayEventErrorMessage(Event.CurrentLineNum, Event.EventErrorMessage); // Event.EventErrorMessage = ""; //} //else //{ // Event.DisplayEventErrorMessage(Event.CurrentLineNum, ""); //} Event.DisplayEventErrorMessage(Event.CurrentLineNum, ex.Message); } }
public void UpdateInventory() { // Crafting if (currentlyCrafting > 0) { for (int i = 0; i < Globals.Randomizer.Next(5, 10); i++) { SceneManager.GameObjects.Add(new Piece(new Vector2(864, 350), TextureManager.explosion, 90, 1.5f)); } } craft.Update(); currentlyCrafting--; if (CanCraft() && currentlyCrafting < 0) { if (craft.Press()) { currentlyCrafting = 60; SoundManager.craft.Play(); } } if (currentlyCrafting == 0) { SoundManager.explosion.Play(); int itemLevel = (int)((Inventory[0, 6].ItemLevel + Inventory[1, 6].ItemLevel + Inventory[2, 6].ItemLevel) / 3 + MathHelper.Lerp(-0.2f, 0.2f, (float)Globals.Randomizer.NextDouble())); Inventory[0, 6] = new Item(Globals.Nothing); Inventory[1, 6] = new Item(Globals.Nothing); Inventory[2, 6] = new Item(Globals.Nothing); if (Inventory[3, 6].Type != ItemType.nothing) { AddItem(Inventory[3, 6]); } int random = Globals.Randomizer.Next(0, 3); if (random == 0) { Inventory[3, 6] = new Weapon(this, Globals.Randomizer.Next(0, Weapon.ListOfMethods().Count()), itemLevel); } else if (random == 1) { Inventory[3, 6] = new Hull(this, Globals.Randomizer.Next(0, Hull.ListOfHullMethods().Count()), itemLevel); } else if (random == 2) { Inventory[3, 6] = new Shield(new Vector2(200, Globals.ScreenSize.Y - 35), 100, 20, 60 + itemLevel * 20 + Globals.Randomizer.Next(-5, 15), Globals.Randomizer.Next(0, Shield.ListOfShieldMethods().Count()), itemLevel); } } for (int i = 0; i < Inventory.GetLength(0); i++) { for (int j = 0; j < Inventory.GetLength(1); j++) { if (Inventory[i, j].Pressed() && Inventory[i, j].Type != ItemType.nothing) { selectedItem = Inventory[i, j]; selectedItemArrayPosition = new Point(i, j); } // Right click if (Inventory[i, j].PressedRight() && Inventory[i, j].Type != ItemType.nothing) { Inventory[i, j].UseItem(this, Inventory[i, j]); } } } if (Globals.MState.LeftButton == ButtonState.Released) { if (selectedItem != null) { // Move item in inventory for (int i = 0; i < Inventory.GetLength(0); i++) { for (int j = 0; j < Inventory.GetLength(1); j++) { if (Inventory[i, j].HoverOver()) { if ((i == 0 && j == 5) || (selectedItemArrayPosition.X == 0 && selectedItemArrayPosition.Y == 5)) // shield { if (selectedItem.Type == ItemType.shield && Inventory[i, j].Type == ItemType.shield) { SwapItem(new Point(i, j)); break; } } else if ((i == 1 && j == 5) || (selectedItemArrayPosition.X == 1 && selectedItemArrayPosition.Y == 5)) // hull { if (selectedItem.Type == ItemType.hull && Inventory[i, j].Type == ItemType.hull) { SwapItem(new Point(i, j)); break; } } else if ((i > 1 && j == 5) || (selectedItemArrayPosition.X > 1 && selectedItemArrayPosition.Y == 5)) // weapons { if ((((selectedItem.Type == ItemType.weapon || Inventory[i, j].Type == ItemType.weapon) && Inventory[i, j].Type == ItemType.nothing) && (Weapons.Count > 1 || !Weapons.Any(item => item == selectedItem)) || (selectedItem.Type == ItemType.weapon && Inventory[i, j].Type == ItemType.weapon))) { int numberOfWeapons = Weapons.Count(); SwapItem(new Point(i, j)); if (numberOfWeapons > Weapons.Count()) { SelectedWeapon = 0; } break; } } else if (!(i > 2 && j == 6)) // inventory { SwapItem(new Point(i, j)); break; } } } } } selectedItem = null; selectedItemArrayPosition = new Point(0, 0); // remove for (int i = Inventory.GetLength(0) - 1; i >= 0; i--) { for (int j = Inventory.GetLength(1) - 1; j >= 0; j--) { if (Inventory[i, j].Dead) { Inventory[i, j] = new Item(Item.Nothing, ItemType.nothing, TextureManager.none, "", ""); } } } } }