### 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.