NPC Object Use
This change allows NPCs to use activatable objects. This is a fairly large commit with some (minor) engine changes.
Basically, when a usable object is added to an Actor inventory (and can be activated -- generally worn in the appropriate slot, .no_inventory_access not true), the Actor may get a (hidden) talent that can be activated to use the power.
These are a new class of talents (.is_object_use) with a new flag (.never_fail) that prevents them from being interfered with by most actor effects. They are available to the player via the UseTalent dialog in a new section, and the usual automatic use, confirmation and ai_tactical weights are supported. (The parameters follow the object if they are moved within the party, as appropriate.)
Objects that use a talent for their power generally don't need any changes, but use_power and use_simple generally must include extra data/functions (range, radius, target, tactical) with the power definition for the ai to use them properly, similar to the structure for talent definitions. Generic powers with no tactical info will generally not be used by the tactical ai due to low weights, while dumb ai types may use them randomly.
(See the header section of mod.class.interface.ActorObjectUse.)
In summary:
Objects with a .use_power field are usable unless .no_npc_use (which may be a function(obj, who)) is true.
For these items:
use_power = {
name = constant or function(object, who), description of the power for the user
power = number, power points used when activated
use = function(object, who), called when the object is used, should include all effects and special log messages
target = table or function(object, who), targeting parameters (interpreted by engine.Target:getType and used by the AI when targeting the power)
requires_target<optional> = boolean or function(object, who), if true, the ai will not use the power if it's target is out of range, should generally be false for powers that target the user
tactical = {TACTIC1 = constant or function(who, t, aitarget),
TACTIC2 = constant or function(who, t, aitarget), ...} tactics table for interpretation by by the tactical AI (mod.ai.tactical.lua), uses the same format as talents, t is the talent defined here
range<optional> = number or function(object, who), should be defined here to allow the AI to determine the range of the power for targeting other Actors with the power, defaults to 1
radius<optional> = number or function(object, who), as range, defaults to 0
on_pre_use<optional> = function(object, who), optional function (similar to talent.on_pre_use, to test if the power is usable via the talents defined here (return true to allow use)
on_pre_use_ai<optional> = function(object, who), like on_pre_use, but only called by the AI, generally used to make the ai smarter by telling it when not to use the power
}
The raw talent level of the activation talent(defined here) equals the material level of the object.
Objects with a .use_simple field (uniquely defined, mostly for consumables), are not usable unless .allow_npc_use (which can be a function(object, who) is true or the .tactical field is defined. They otherwise use the same format as .use_power.
Objects with a .use_talent field use a defined talent as their power. They are usable if .allow_npc_use (which can be a function(object, who)) is true or talent.no_npc_use is not true and use_talent.no_npc_use (may be a function(object, who)) is not true.
For these items:
use_talent = {
id = string, talent_id to use (i.e. Talents.T_ILLUMINATE)
level = number, raw talent level for the power (uses the user's mastery levels)
power = number, power points used when activated
on_pre_use<optional> = function(who, t), override talent.on_pre_use function, t matches talent_id
on_pre_use_ai<optional> = function(who, t), override talent.on_pre_use_ai function, t matches talent_id
message<optional> = function(who, t), override talent use message if any, t matches talent_id
}
The raw talent level of the activation talent equals the talent level specified in use_talent.
This commit updates charms(amulet, belt, boots, cloak, light-armor, mindstars, ranged, staves, torques, totems, wands, weapons), some fixed arts and most of the boss artifacts with the required fields to use the items. This includes fixing the ai tactical tables for several related talents. Randombosses and several types of NPC's (with tactical AI) get a usable charm (in the tool slot).
Most of the general fixed-arts (those without use_talent) still need to be updated.