Skip to content

Hunter Pride

Scrab Joséline edited this page Aug 30, 2023 · 7 revisions

When fighting other NPC, Acheron may decide to intervene in regular combat behavior and put them into a special "Defeat"-state, a state in which they are no longer able to engage in combat and will usually be ignored by other NPC as well. In this state, they are immune to damage and about as useful as if they were dead, but this doesn't have to be:
Hunter's Pride is an ability that allows you to interact with these NPC in a variety of ways; to engage with such targets in some way or another.

Native Options

By default, the Hunter Pride Menu offers a total of 4 options to engage with defeated actors:

  • Rescue: Uses the most effective potion in your inventory to rescue your target. This will free them from the defeat status.
  • Plunder: This will open the targets inventory, allowing you take everything out of it. This will count as an assault tho and alarm surrounding NPC.
  • Execute: Defeated actors are usually immune to damage. You can use this setting to kill them through their defeat status. (This is treated as murder)
  • Drain (Feed): As a vampire, you may feed on defeated targets, killing them in the process. (This too, is treated as murder)

Custom Options

In addition, mod authors may add their own options to this menu, to expand on the things you can do. Addition of options can be temporary or permanent, so if you let's say wanted to Kidnap some specific NPC and only allow the option for one specific quest, you can do that!

Creating an Option

Hunter Pride option's are registered through papyrus, using the AddOption function in Acheron.psc. This function takes 4 arguments:

  • asOptionID: An unique ID-String that is representing the option. Use as callback to get its internal ID or to remove the option again.
  • asOptionName: The options name, this name will be displayed to them when they hover/select the option. Supports localization the same way as SkyUI MCM do.
  • asIconSource: A file path, relative to 'Interface\Acheron', leading to either a .dds, .png or .swf file with a icon to display.
  • asConditions: A json string compressed to a single line which lists all of the conditions to be allowed.

The Icon

Hunter Pride icons are images with a 1:1 aspect ratio which will be displayed in the menu when its open, to give players a chance to quickly find and use your option. The supported file types are .dds, .png and .swf:

  • DDS/PNG:
    These two file types behave essentially the same, they should have a minimum size of 512x512px. The squared image is important to allow you to properly determine how the image is placed in the icon box. Using a different ratio than 1:1 may cause the image to be stretched or not centered correctly.
  • SWF:
    .swf files are a little more complicated but have a some benefits over common .dds or .png files, most notably: They are vector arts, as opposed to pixels. As before, ensure that the background of the .swf file is squared to allow optimal placement inside the icon box.
    Additionally, .swf files allow you to store more than 1 image in a file by diving them into different frames. To tell Acheron which frame to render, append { followed by the frame number/name and then } to the end of the name. (For example: Imagine we have a .swf with a dog at frame 1 and a cat at frame 2, to render the dog, we would pass DogCat.swf{1} and to render the cat DogCat.swf{2})

Once you got your icon file, place it into Data\Interface\Acheron\ and state the file path in the asIconSource parameter, so Acheron can find it.

Conditions

The condition argument can be used to disable your option in certain situations, like when activating an essential actor, or maybe because you only want to enable an option on some specific type of actor. The string should use the following syntax, compressed into a single line:

{
  "Player": {
    "HAS": {
      "Keywords": [],
      "Factions": []
    },
    "NOT": {
      "Keywords": [],
      "Factions": []
    }
  },
  "Target": {
    "HAS": {
      "Keywords": [],
      "Factions": []
    },
    "NOT": {
      "Keywords": [],
      "Factions": []
    },
    "IS": [
      "Essential",
      "NonEssential",
      "Hostile",
      "NonHostile"
    ]
  }
}
  • Conditions can either be run on the player or on the target. The target is always a defeated NPC (human).
  • The HAS section is used to check if the condition target has the specified keywords/factions.
  • The NOT works in the same way as the HAS one, but in reverse, checking if condition is not valid.
  • The IS branch, only available to the target actor, checks some attribute on the target actor:
    • Essential asks if the target is essential, disabling itself if the target is not essential.
    • Hostile asks if the target is hostile towards the player, disabling itself when the target is friendly.
    • The non prefixed-conditions behave the same as their default ones, but negate the result.

Forms are given with the syntax FormID|Plugin. (for example: 0xA82BB|Skyrim.esm to look up the "Vampire"-Keyword in Skyrim.esm)

Reacting to Selection

A new option in the menu is all nice and well, but doesn't really do much if you cannot run any code when its selected. When you install a new option into the menu, you also want to listen for its usage using RegisterForHunterPrideSelect, RegisterForHunterPrideSelect_Alias or RegisterForHunterPrideSelect_MgEff. This will send you the Event OnHunterPrideSelect every time an option is selected.

In your code, add a new event to catch this event and check if the given option id matches one of the options you previously registered:

Event OnHunterPrideSelect(int aiOptionID, Actor akTarget)
  If (aiOptionID == Acheron.GetOptionID("MyOption"))
    Debug.Trace("My option has been selected on " + akTarget + "!")
  EndIf
EndEvent

A complete Example

ScriptName ExampleScript extends ReferenceAlias

String Property OptionID = "MyCoolCustomOption" AutoReadonly

Event OnInit()
  If(!Acheron.HasOption(OptionID))
    ; Register option
    int result = Acheron.AddOption(OptionID, "$Example_OptionName", "Example\\Icon.swf")
    If (result > -1)
      Debug.Trace("Successfully registered option!")
    EndIf
  EndIf
  ; Register callback
  Acheron.RegisterForHunterPrideSelect_Alias(self)
EndEvent

Event OnHunterPrideSelect(int aiOptionID, Actor akTarget)
  ; Check if the selected option is the one we just registered
  If (aiOptionID == Acheron.GetOptionID(OptionID))
    ; Handle option selection
    Debug.Trace("Example option has been selected on " + akTarget + "!")
  EndIf
EndEvent
Clone this wiki locally
  翻译: