Writing Plugins that Interface With the Virindi Bundle

From VirindiPlugins
Jump to navigation Jump to search

Note: This page is designed for developers writing a Decal plugin.

Plugins in the Virindi Plugin Bundle are designed to be easy to extend by other plugins. Many addon functions have wrappers for your convenience provided in the Virindi Public Code Repo.

For plugins, functionality is typically exposed by an instance of the plugin's PluginCore object. Properly calling in requires referencing the target plugin, then verifying at runtime that the target assembly is loaded and the plugin is running. To avoid a JIT exception if the user is not running the target plugin, no types from the target assembly should be referenced in an executing method or instantiated class until it is known that the target assembly is already loaded. The example wrappers do this check for you.


Virindi Views

There are two approaches you can use to support Virindi Views: require them, or support them optionally with fallback to Decal views.

Most Bundle components have fallback functionality. Fallback functionality is achieved using the MetaViewWrappers. The MetaViewWrappers abstract the concept of a view provider with a set of classes for VVS and Decal views which implement a common interface set. When you ask the ViewSystemSelector to create a new view, it returns the implementation that corresponds to what is currently running. The MetaViewWrapper interfaces are designed to be as identical as possible to the builtin Decal.Adapter classes to facilitate porting. Wrapper_WireupHelper.cs contains a helper class you can call to emulate Decal's attribute-based wireup.

The MetaViewWrapper files are licensed under the MIT License so you can easily include them in any plugin.

Note that when using the MetaViewWrappers, you must add VVS_REFERENCED as a conditional compilation symbol under Project Properties/Build.


Applicable source files:

  • ViewSystemSelector.cs (Determines what is running and constructs views)
  • Wrapper.cs (Interface definitions)
  • Wrapper_Decal.cs (Implementation for Decal views)
  • Wrapper_MyHuds.cs (Implementation for VVS views)
  • Wrapper_WireupHelper.cs (Attribute wireup helper)


Example plugins which use VVS with fallback:


Example plugins which construct VVS views directly:


Virindi Hotkey System

HotkeyWrappers.cs and VHS_Connector.cs are provided to abstract providing hotkeys to both DHS and VHS. Include them in your project, add VirindiHotkeySystem as a reference, then call HotkeyWrapperManager.Startup() from Core.PluginInitComplete and HotkeyWrapperManager.Shutdown() from your plugin's Shutdown method. Once you call Startup() you can define hotkeys with HotkeyWrapperManager.AddHotkey() and they will be added to any hotkey system the user is running.


Example plugins which implement VHS hotkeys using HotkeyWrapperManager:


Example plugins which implement VHS hotkeys directly:

Virindi HUDs

Plugins can provide text items to the VHUDs Status HUD. VHUDs_Connector.cs provides this functionality. To use it, call SchedulePulse() during plugin startup (or Pulse() later). Then simply call Status_UpdateEntry() anytime any status item should be updated. If the entry doesn't exist it will be created.

Status HUD updates are designed to be very fast, so calling Status_UpdateEntry() very often is generally not a problem.

Example plugins which output to VHUD:

Virindi Tank

Virindi Tank contains a number of methods on PluginCore which are available for other plugins to use. Some of the available methods:

 /// Immediately classify an object with the currently selected loot profile.
 /// NOTE: Do not call from within a create or id received event, since VTank may not have gotten it yet.
 LootPlugins.LootAction FLootPluginClassifyImmediate(int obj)

 /// Query if the currently selected loot profile requires an ID to classify this object.
 /// NOTE: Do not call from within a create or id received event, since VTank may not have gotten it yet.
 bool FLootPluginQueryNeedsID(int obj)

 /// Classify an object with the current loot profile, IDing the item if necessary
 /// and executing a callback when it is done. NOTE: Do not call from within a create
 /// or id received event, since VTank may not have gotten it yet.
 void FLootPluginClassifyCallback(int obj, delFLootPluginClassifyCallback callback)

 ReadOnlyCollection<LootPlugins.GameItemInfo> FWorldTracker_GetAllInInventoryWithName(string name)

 ReadOnlyCollection<LootPlugins.GameItemInfo> FWorldTracker_GetInventory()

 ReadOnlyCollection<LootPlugins.GameItemInfo> FWorldTracker_GetInContainer(int container)

 ReadOnlyCollection<LootPlugins.GameItemInfo> FWorldTracker_GetWithName(string name)

 ReadOnlyCollection<LootPlugins.GameItemInfo> FWorldTracker_GetWithObjectClass(LootPlugins.ObjectClass objclass)

 LootPlugins.GameItemInfo FWorldTracker_GetWithID(int gameid)

 LootPlugins.GameItemInfo FWorldTracker_GetWithVendorObjectTemplateID(int gameid)

 int FWorldTracker_CountStackedInventoryObjectsWithName(string name)

 /// Query the auto-damage element list for a particular monster name.
 ReadOnlyCollection<eDamageElement> FGameInfo_QueryAutoDamageElementList(string monstername)

 /// Query the damage type the macro would use on a target,
 /// taking into account the player's monster list settings.
 eDamageElement FMonsterList_QueryFinalDamageType(LootPlugins.GameItemInfo monster)

These methods are called on uTank2.PluginCore.PC.


Example plugins which call VTank methods:

Virindi Tank Loot plugins

Virindi Tank allows others to define loot plugins which tell it which items to loot and salvage. This is designed so that any plugins which contain rule systems for defining items players want can be used by VTank automatic looting. Loot plugins can either be standalone or loaded alongside a full Decal plugin. Loot plugins are defined in the registry similarly to Decal plugins, and are loaded by VTank at login.

A loot plugin core class should implement uTank2.LootPlugins.LootPluginBase from the VTank assembly. By default, VTank uses builtin rules for salvage combination. To have your plugin specify which bags should be combined, your loot plugin core should implement either the ILootPluginCapability_SalvageCombineDecision or ILootPluginCapability_SalvageCombineDecision2 interfaces.


Example standalone loot plugins:


Example Decal plugins with a loot plugin component: