API: Difference between revisions

From Citizens Wiki

No edit summary
Line 41: Line 41:
To register a trait, we use the '''TraitFactory''' class. This controls registration for your custom traits.
To register a trait, we use the '''TraitFactory''' class. This controls registration for your custom traits.
{{codebox|height=300px|Example registration and simple trait|<syntaxhighlight lang="java5">
{{codebox|height=300px|Example registration and simple trait|<syntaxhighlight lang="java5">
public class MyTrait extends Trait {
//This is your trait that will be applied to a npc using the /trait mytraitname command. Each NPC gets its own instance of this class.
    public MyTrait() {
//You can add your functionality here, or create new classes to implement listeners, run logic, etc.
          super("mytraitname")
//the Trait class has a reference to the attached NPC class through 'npc' or getNPC().
    }
public class MyTrait extends Trait {
    public void load(DataKey key) {
 
    }
public MyTrait() {
 
super("mytraitname");
    public void save(DataKey key) {
plugin = (MyPlugin) Bukkit.getServer().getPluginManager().getPlugin("MyPlugin");
    }
}
}
 
public class MyPlugin extends JavaPlugin {
MyPlugin plugin = null;
    public void onEnable() {
 
        TraitFactory factory = CitizensAPI.getTraitFactory();
boolean SomeSetting = false;
        TraitInfo info = TraitInfo.create(MyTrait.class).withName("mytraitname");
 
        factory.registerTrait(info);
//Here you should load up any values you have previously saved. This does NOT get called when applying the trait for the first time, only loading onto an existing npc at server start.
    }
public void load(DataKey key) {
}
SomeSetting = key.getBoolean("SomeSetting", false);
}
 
//Save settings for this NPC. These values will be added to the citizens saves.yml under this NPC.
public void save(DataKey key) {
key.setBoolean("SomeSetting",SomeSetting);
}
 
@Override
public void onAttach() {
// Run code when your trait is attached to a NPC. This always runs before onSpawn. This would be a good place to load configurable defaults for new NPCs.
plugin.getServer().getLogger().info(npc.getName() + "has been assigned MyTrait!");
}
 
@Override
public void onDespawn() {
// Run code when the NPC is despawned
}
 
@Override
public void onSpawn() {
//Run code when the NPC is spawned. Note that npc.getBukkitEntity() will be null until this method is called.
}
 
@Override
public void onRemove() {
//run code when the NPC is removed. Use this to tear down any repeating tasks.
 
}
 
}
 
 
//This is your bukkit plugin class. Use it to hook your trait into Citizens and handle any commands.
public class MyPlugin extends org.bukkit.plugin.java.JavaPlugin {
 
public void onEnable() {
 
//check if Citizens is present and enabled.
if(getServer().getPluginManager().getPlugin("Citizens") == null || getServer().getPluginManager().getPlugin("Citizens").isEnabled() == false) {
//Register your trait with Citizens.       
net.citizensnpcs.api.trait.TraitInfo info = net.citizensnpcs.api.trait.TraitInfo.create(MyTrait.class).withName("mytraitname");
net.citizensnpcs.api.CitizensAPI.getTraitFactory().registerTrait(info);
}
 
}
 
@Override
public boolean onCommand(CommandSender sender, Command cmd, String cmdLabel, String[] inargs) {
//handle commands for /myplugin
}
}
 
 
</syntaxhighlight>
</syntaxhighlight>
}}
}}

Revision as of 17:55, 17 September 2012

Current Release Download: Jenkins

Developmental Builds: Jenkins

Documentation: JavaDocs

Source: Github

Citizens has an extensive API that can be used for making your plugins work with NPCs or even for adding a brand new character that can be attached to an NPC. Make sure you always are using an up-to-date build of the CitizensAPI to ensure that your plugin works with the latest release of Citizens.

Javadocs can be found at http://jd.citizensnpcs.com

Hooking Into Citizens

Hooking into Citizens is as simple as creating a basic plugin and adding the line depend: [Citizens] into your plugin.yml. From here, a common basic entry point is the CitizensAPI class. This gives you access to the NPCRegistry for NPC lookup, as well as the TraitFactory which allows trait registration.

Checking if an entity is a Citizens NPC

Citizens NPCs will have the "NPC" metadata set to true. Eg.

boolean isCitizensNPC = entity.hasMetadata("NPC");

PLEASE NOTE: Players sharing names with NPCs will have the same metadata as the NPC as per https://bukkit.atlassian.net/browse/BUKKIT-2501. Working on a fix for this.


Creating a Trait

Traits are persistent, attachable objects that are linked to an NPC and provide specific functionality. This can be anything from a full-blown dynamic villager AI to a simple talking trait.

To register a trait, we use the TraitFactory class. This controls registration for your custom traits.

Code: Example registration and simple trait

This sets up a simple trait. The user can already attach a trait to the NPC using the /trait [name] command, but you may want to create your own command that is more user-friendly.

There are various methods that Trait provides to make life easier for developers. For example, developers can override the run() method which is called every tick. @EventHandler can be used to listen for events without having to register them manually.

The onSpawn() method is also important -- this tells you when the npc field provided in Trait (accessible using this.npc or this.getNPC()) is safe to use.

The DataKey parameters provided in save and load allow saving of simple data types such as Strings and primitive values for persistence. These will be saved under the individual NPC's data storage.

Using the AI API

The AI API of Citizens can be broken down into two parts - GoalController and Navigator.

A Goal is a repeatable, abstract unit of work that can be performed by an NPC. It can be registered with a GoalController with a priority (higher is more important). The highest priority goal which can be executed will be prioritised. NPC contains getDefaultGoalController() for this purpose.

The GoalSelector allows a great deal of flexibility within goal implementations. It allows firstly the dynamic selection of sub-goals and the concurrent execution of many sub-goals, and can stop execution at any time.


Code: Example
{{{2}}}

The second concept is the Navigator. This controls the pathfinding aspects of the NPC. The Navigator can have one target at a time, and will call events to notify of completion/cancellation.

The pathfinding range of the Navigator is the maximum range it will search when attempting to find a path to the target. This is usually set by the server admin. The speed of the Navigator is the movement speed of the NPC while moving to the target. The default speed is around 0.3.

See Also

Characters