• 欢迎来到Minecraft插件百科!
  • 对百科编辑一脸懵逼?帮助:快速入门带您快速熟悉百科编辑!
  • 因近日遭受攻击,百科现已限制编辑,有意编辑请加入插件百科企鹅群:223812289

Magic/Actions

来自Minecraft插件百科
跳转至: 导航搜索

行为系统

Magic有一个灵活的"action【行为】" 系统,你可以基于默认的法术构建自己独一无二的法术

大部分法术如今都使用行为系统,不再使用先前的&quotclass&quot【类】系统.

行为系统会根据施法者的施法量智能地平衡负载。 Magic will try to ensure that spells don't lag the server by modifying too many blocks or entities in a single tick.

This means that any spell has the potential to get "batched" for delayed processing. This is not strictly speaking "asynchronous", but it is the same general idea. If a spell requires too much "work" to complete in a single tick, it will spread out over multiple ticks.

Create your own spells

The action system lets you build your own spells for some really cool custom behavior! Take a look through the survival spell configurations to get a feel for what's possible. In particular, there are a few spells (laser, singularity, magichat) that are documented pretty well, I'm hoping to do better with that in the future.

Built in Actions

Please check out the Reference Manual for a list of all builtin spell actions and their parameters!

Create your own actions

If you can't seem to get the effect you want, and have a bit of Java/Bukkit experience, it's pretty each to code up some new SpellAction classes. This is now the preferred method to extend Magic, rather than creating a new Spell class.

This will let you mix your custom actions in with the builtin actions!

All you need to do is to implement the SpellAction interface found in MagicAPI. Alternately, you can extend BaseSpellAction in MagicLib, which takes care of some of the boilerplate code for you.

If using BaseSpellAction (which I would recommend), you will need to build against the Magic plugin itself, not the API. The plugin is not available in the Central Maven repo, so you will have to add the elMakers repo:

    <repositories>
        <repository>
            <id>elMakers</id>
            <url>http://maven.elmakers.com/repository/</url>
        </repository>
    </repositories>

Then you would add Magic as a dependency like this:

    <dependencies>
        <dependency>
            <groupId>com.elmakers.mine.bukkit.plugins</groupId>
            <artifactId>Magic</artifactId>
            <version>8.3</version>
            <scope>provided</scope>
        </dependency>
   </dependencies>

Action anatomy

Actions have a few important methods that get called at certain times. It is important, especially for performance, to know what to do and when.

initialize

This method is called whenever a spell is loaded for the first time. It is only called once per player per server session, and is given the action's parameters. Spells rarely use this, though in cases where you have a big list of things in your parameters or spell config it may be more efficient to pre-parse it here.

Any parameters read inside of initialize() cannot be overridden by /cast or /wand override.

prepare

This is called at the beginning of a spell cast, giving the action the current CastContext and parameters. This is generally when you'll want to read your parameters into class variables.

reset

This is called at the beginning of one "iteration" of a spell cast. This is generally only used by CompoundAction classes, to reset their counter to the beginning of their action list. It is rare you'll need to override this.

perform

This is the main body of your action, where you will do your work. This may be called many, many times during a spell cast, so try and keep things efficient.

finish

This is called for each action after the entire spell cast is complete, and is a good place to perform and cleanup or final actions.

Cast Context and Parameters

Most spells only need to override "prepare" and "perform". The "prepare" method is passed a ConfigurationSection, which can be used to read in the action's parameters.

Both "prepare" and "perform" are passed a CastContext object. This object is how you interact with all of the core Magic functionality- such as the undo system. Methods are constantly added to CastContext as needed by the builtin actions, so there is quite a bit there you can make use of.

Action Flow

Normally actions in a spell are processed "serially"- that is, one at a time, in a row.

If an action takes some time to complete (Delay action, in-flight Projectile, etc) the spell will sit and wait on that action until it completes.

Sometimes you'd like more than one thing to happen at a time in a spell.
There are a few different actions that can do that:

  • Multiply: Kind of like "Repeat" except all of the "cloned" actions run at the same time (in parallel) instead of one after another (in serial)
  • Parallel: Runs all of the actions in its "actions" list separately, in parallel
  • Asynchronous: Runs its actions list as normal (serially, one after another) except it does this in parallel with the rest of the spell- so an Asynchronous action always completely immediately, no matter how longer the actions inside it really take

Then there is this kind of odd case of the Serial action- this is basically just used to group actions together. Mainly this is used in "Parallel", since that one takes each action in its list as a separate "thread" to run, Serial may be used to group several actions together that you want to run one after another in parallel with other actions.

To try and tie all that together with an example- what does the Chain Lightning spell do?

It launches a projectile, when that projectile hits it does an AreaOfEffect.

AOE will run actions for each target in a radius, but we want to spawn a new projectile towards each of those targets.

However, we want them to all fly at once, rather than one firing, waiting for hit, then another firing, etc.

That is what the Asynchronous action does, it makes all of the chained projectiles fly at once.

Similarly Meteor Shower uses Multiply to launch several meteors at once.