### ScenarioInfo Class Wrapper Example Source: https://bveex.okaoka-depot.com/wiki/quickstart An example of a derived class wrapper, ScenarioInfo, which provides access to scenario file information. It demonstrates how wrapper classes use reflection to access properties of the original BVE objects, such as the scenario path. ```csharp using System; using System.Reflection; using TypeWrapping; namespace BveTypes.ClassWrappers { /// /// シナリオファイルから読み込んだ情報にアクセスするための機能を提供します。 /// public class ScenarioInfo : ClassWrapperBase { [InitializeClassWrapper] private static void Initialize(BveTypeSet bveTypes) { ClassMemberSet members = bveTypes.GetClassInfoOf(); PathGetMethod = members.GetSourcePropertyGetterOf(nameof(Path)).Source; PathSetMethod = members.GetSourcePropertySetterOf(nameof(Path)).Source; // ... } /// /// オリジナル オブジェクトから クラスの新しいインスタンスを初期化します。 /// /// ラップするオリジナル オブジェクト。 protected ScenarioInfo(object src) : base(src) { } private static MethodInfo PathGetMethod; private static MethodInfo PathSetMethod; /// /// シナリオファイルのパスを取得・設定します。 /// public string Path { get => PathGetMethod.Invoke(Src, null) as string; set => PathSetMethod.Invoke(Src, new object[] { value }); } // ... } } ``` -------------------------------- ### Define Map Plugin Main Class (C#) Source: https://bveex.okaoka-depot.com/wiki/quickstart This is the minimal code for a BveEX map plugin. Ensure you have installed the 'BveEx.PluginHost' NuGet package. ```csharp using System; using BveEx.PluginHost.Plugins; [Plugin(PluginType.MapPlugin)] internal class PluginMain : AssemblyPluginBase { public PluginMain(PluginBuilder builder) : base(builder) { } public override void Dispose() { } public override void Tick(TimeSpan elapsed) { } } ``` -------------------------------- ### Define Vehicle Plugin Main Class (C#) Source: https://bveex.okaoka-depot.com/wiki/quickstart This is the minimal code for a BveEX vehicle plugin. Ensure you have installed the 'BveEx.PluginHost' NuGet package. ```csharp using System; using BveEx.PluginHost.Plugins; [Plugin(PluginType.VehiclePlugin)] internal class PluginMain : AssemblyPluginBase { public PluginMain(PluginBuilder builder) : base(builder) { } public override void Dispose() { } public override void Tick(TimeSpan elapsed) { } } ``` -------------------------------- ### Checking Scenario Load Status with IsScenarioCreated Source: https://bveex.okaoka-depot.com/wiki/blog/entry/20250415/1 This example demonstrates how to check if the BVE scenario has been created using the BveHacker.IsScenarioCreated boolean property. It shows the property's value before and after the ScenarioCreated event. ```csharp public class PluginMain : AssemblyPluginBase { public PluginMain(PluginBuilder builder) : builder { BveHacker.ScenarioCreated += OnScenarioCreated; // false になる bool isScenarioCreated = BveHacker.IsScenarioCreated; } public override void Dispose() { BveHacker.ScenarioCreated -= OnScenarioCreated; // false になる // ここでも BveHacker.Scenario プロパティを使用できないことには変わりないため bool isScenarioCreated = BveHacker.IsScenarioCreated; } private void OnScenarioCreated(ScenarioCreatedEventArgs e) { // true になる bool isScenarioCreated = BveHacker.IsScenarioCreated; // true になる } // ...略 } ``` -------------------------------- ### Incorrectly Calling OpenScenario in Tick Method Source: https://bveex.okaoka-depot.com/wiki/blog/entry/20250416/1 Calling MainForm.OpenScenario directly within the Tick method can lead to errors due to object release issues. This example demonstrates the incorrect approach. ```csharp public class PluginMain : AssemblyPluginBase { // ...略 public override void Tick(TimeSpan elapsed) { // 12 時になったらシナリオを開きたい if (12 <= BveHacker.Scenario.TimeManager.Time.TotalHours) { BveHacker.MainForm.OpenScenario("シナリオファイルへのパス"); } } // ...略 } ``` -------------------------------- ### Define Extension Plugin Main Class (C#) Source: https://bveex.okaoka-depot.com/wiki/quickstart This is the minimal code for a BveEX extension plugin. It requires implementing the 'IExtension' interface in addition to inheriting from 'AssemblyPluginBase' and using the 'Plugin' attribute. ```csharp using System; using BveEx.PluginHost.Plugins; using BveEx.PluginHost.Plugins.Extensions; [Plugin(PluginType.Extension)] internal class PluginMain : AssemblyPluginBase, IExtension { public PluginMain(PluginBuilder builder) : base(builder) { } public override void Dispose() { } public override void Tick(TimeSpan elapsed) { } } ``` -------------------------------- ### Accessing Scenario Vehicle Speed via BveHacker Source: https://bveex.okaoka-depot.com/wiki/quickstart Demonstrates how to retrieve and modify the current speed of the player's vehicle using the BveHacker property. It shows accessing the Scenario object, then VehicleLocation, and finally the Speed property or SetSpeed method. ```csharp // 自列車の速度を [m/s] 単位で取得する double speed = BveHacker.Scenario.VehicleLocation.Speed; // 自列車を 10 km/h = (10 / 3.6) m/s 加速させる BveHacker.Scenario.VehicleLocation.SetSpeed(speed + 10 / 3.6); ``` -------------------------------- ### Implement Togglable Extension (C#) Source: https://bveex.okaoka-depot.com/wiki/quickstart To make an extension plugin toggleable from the BveEX UI, implement the 'ITogglableExtension' interface and apply the 'Togglable' attribute to the main class. The 'IsEnabled' property controls the enabled state. ```csharp using System; using BveEx.PluginHost.Plugins; using BveEx.PluginHost.Plugins.Extensions; [Plugin(PluginType.Extension)] [Togglable] internal class PluginMain : AssemblyPluginBase, ITogglableExtension { public bool IsEnabled { get { // ... } set { // ... } } // ...略... } ``` -------------------------------- ### Correctly Calling OpenScenario via Paint Event Source: https://bveex.okaoka-depot.com/wiki/blog/entry/20250416/1 Subscribe to the MainForm's Paint event to correctly call MainForm.OpenScenario. This ensures that BVE's internal processing does not access released objects, preventing errors. ```csharp public class PluginMain : AssemblyPluginBase { public PluginMain(PluginBuilder builder) : base(builder) { BveHacker.MainFormSource.Paint += OnPaint; } public override void Dispose() { // イベントの購読解除を忘れずに BveHacker.MainFormSource.Paint -= OnPaint; } private void OnPaint(object sender, PaintEventArgs e) { // 12 時になったらシナリオを開く if (BveHacker.IsScenarioCreated && 12 <= BveHacker.Scenario.TimeManager.Time.TotalHours) { BveHacker.MainForm.OpenScenario("シナリオファイルへのパス"); } } // ...略 } ``` -------------------------------- ### Reference External BveEX Extension Source: https://bveex.okaoka-depot.com/wiki/quickstart Use this to reference an external plugin as a library. Ensure the extension implements the specified interface. ```csharp IHogeExtension extension = Extensions.GetExtension(); ``` -------------------------------- ### Inherit from AssemblyPluginBase (C#) Source: https://bveex.okaoka-depot.com/wiki/quickstart When developing BveEX plugins, you typically inherit from the 'AssemblyPluginBase' abstract class, which is a derivative of 'PluginBase'. This class automatically handles assembly information like name and description from 'AssemblyInfo.cs'. ```csharp using System; using BveEx.PluginHost.Plugins; internal class 任意のクラス名 : AssemblyPluginBase { // ...略... } ``` -------------------------------- ### Specify Main Class Type with ExtensionMainDisplayType Source: https://bveex.okaoka-depot.com/wiki/quickstart Use the ExtensionMainDisplayType attribute to specify an interface or class that the main plugin class implements, allowing other plugins to retrieve its instance under a different type. This is useful for providing a consistent API across different plugin implementations. ```csharp using System; using BveEx.PluginHost.Plugins; using BveEx.PluginHost.Plugins.Extensions; [Plugin(PluginType.Extension)] [ExtensionMainDisplayType(typeof(IHogeExtension))] internal class PluginMain : AssemblyPluginBase, IHogeExtension { // ...略... } public interface IHogeExtension : IExtension { } ``` -------------------------------- ### Correct Scenario Access using ScenarioCreated Event Source: https://bveex.okaoka-depot.com/wiki/blog/entry/20250415/1 This code shows the correct way to access scenario data by subscribing to the BveHacker.ScenarioCreated event. The scenario is accessed via the ScenarioCreatedEventArgs parameter within the event handler. ```csharp // using BveEx.PluginHost; を追加 public class PluginMain : AssemblyPluginBase { private AssistantText TestText; public PluginMain(PluginBuilder builder) : builder { // イベントの購読 BveHacker.ScenarioCreated += OnScenarioCreated; } public override void Dispose() { // イベントの購読解除を忘れずに BveHacker.ScenarioCreated -= OnScenarioCreated; BveHacker.Assistants.Items.Remove(TestText); TestText.Dispose(); } private void OnScenarioCreated(ScenarioCreatedEventArgs e) { // このイベント内でシナリオへアクセスする場合も、BveHacker.Scenario プロパティはやはり使用不可なので注意 // シナリオは ScenarioCreatedEventArgs の Scenario プロパティから取得できる double firstStationLocation = e.Scenario.Map.Stations[0].Location; TestText = AssistantText.Create($"始発駅の距離程は {firstStationLocation} m です。"); BveHacker.Assistants.Items.Add(TestText); } // ...略 } ``` -------------------------------- ### Specify Plugin Type with PluginAttribute (C#) Source: https://bveex.okaoka-depot.com/wiki/quickstart To designate a class as a BveEX plugin and specify its type (e.g., VehiclePlugin), you must apply the 'Plugin' attribute. This attribute is used in conjunction with inheriting from a 'PluginBase' derivative. ```csharp using System; using BveEx.PluginHost.Plugins; [Plugin(PluginType.VehiclePlugin)] // 車両プラグインの場合 internal class 任意のクラス名 : AssemblyPluginBase { // ...略... } ``` -------------------------------- ### Incorrect Scenario Access in Plugin Constructor Source: https://bveex.okaoka-depot.com/wiki/blog/entry/20250415/1 This code demonstrates an incorrect attempt to access the BveHacker.Scenario property within a plugin's constructor, which occurs before the scenario is fully loaded, leading to an error. ```csharp public class PluginMain : AssemblyPluginBase { private AssistantText TestText; public PluginMain(PluginBuilder builder) : builder { // 始発駅の距離程を取得して、補助表示に出力したい // しかし、シナリオの読込完了前に BveHacker.Scenario プロパティへアクセスしているのでエラーとなる double firstStationLocation = BveHacker.Scenario.Map.Stations[0].Location; // 補助表示を作成・追加 TestText = AssistantText.Create($"始発駅の距離程は {firstStationLocation} m です。"); BveHacker.Assistants.Items.Add(TestText); } public override void Dispose() { // 補助表示を削除・解放 BveHacker.Assistants.Items.Remove(TestText); TestText.Dispose(); } // ...略 } ``` -------------------------------- ### ClassWrapperBase Abstract Class Definition Source: https://bveex.okaoka-depot.com/wiki/quickstart This abstract class serves as the base for all class wrappers, providing a way to access the original BVE object through the Src property. It's part of the BveEX framework for simplifying interaction with BVE's internal structures. ```csharp using System; namespace BveTypes.ClassWrappers { /// /// すべてのクラスラッパーの基本クラスを表します。 /// public abstract class ClassWrapperBase { /// /// ラップされているオリジナル オブジェクトを取得します。 /// public object Src { get; } /// /// クラスの新しいインスタンスを初期化します。 /// /// ラップするオリジナル オブジェクト。 public ClassWrapperBase(object src) { Src = src; } } } ``` -------------------------------- ### Hide Plugin Main Class with HideExtensionMain Source: https://bveex.okaoka-depot.com/wiki/quickstart Apply the HideExtensionMain attribute to your plugin's main class to prevent other plugins from obtaining its instance. This is useful for internal plugins or when you want to restrict access to the main class. ```csharp using System; using BveEx.PluginHost.Plugins; using BveEx.PluginHost.Plugins.Extensions; [Plugin(PluginType.Extension)] [HideExtensionMain] internal class 任意のクラス名 : AssemblyPluginBase, IExtension { // ...略... } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.