CTF-CR Battle Class Scripting

CTF-CR Battle Class Scripting API

This section is mostly for coders.

Please check documentation! This page may contain outdated instructions and/or description! Extract 'doc' folder from CTF-CR_v<version><build>.jar (open index.html).

General

Needed imports are essential Bukkit imports and ctf.* with ctf.eventmanipulation.*. When instantiating Bukkit Location, World argument should be getGameWorld().

  • By contract, implementations of this class should not modify inventory of any other player except the assigned player. This player can be accessed with call getPlayer().
  • By convention it is not permitted for a CTF Battle class implementation to teleport any entity outside the game world.
  • It is not advised to write heavy code in abstract methods of this class, as that will impact overall server performance. In general each implementation should use maximum one lightweight timer registration.
  • It is not efficient to make any initializations in constructor, so it is best to implement no constructor. All initializations should be done in onInitialization() method.
  • To ensure that any abilities of this BattleClass implementation are actually recorded as damage dealt from this player, it is important to call setDamager(Player). Direct hits are registered automatically, so it is not recommended to set damager in onEntityHit(Entity, DamageState, CancelState, DamageType) to save performance.
  • To set description of implementation simply create public static String field with variable name Description and assign String object that contains description.
  • Modifying material of any block with Block.setMaterial(Material) or Block.setData(byte) is not recommended. Better solution is to call modifyBlock(Block, Material, byte, int).
  • It is not recommended to register Bukkit events that are already handled in CTF Game Handler. If that must be done see registerBukkitHandler().
  • Do not call ANY damage functions from ANY Entity in ANY Damage events! This includes onGetHit(Entity, double, DamageType) and onEntityHit(Entity, DamageState, CancelState, DamageType) calls!!! Failing to do so will result in method looping and eventually OutOfMemotyError.
  • It is discouraged to use any World.createExplosion([args]) as those methods do not raise EntityExplodeEvent and will result in permanent map damage until complete reload. Instead use createExplosion(Location, float).
  • If player right-clicks while holding Material.COOKED_BEEF, he/she will be healed by 5 hearts.
  • Calling constructor of main plugin class will result in AssertionException or ExceptionInInitializerError.

CTF Game Handler handled events:

PlayerJoinEvent, PlayerQuitEvent, EntityDeathEvent, InventoryClickEvent, EntityDamageByEntityEvent, EntityExplodeEvent, PlayerInteractEntityEvent, PlayerInteractEvent, PlayerDropItemEvent, EntityChangeBlockEvent, PlayerPickupItemEvent, EntityDamageEvent, PlayerTeleportEvent, ProjectileHitEvent, ProjectileLaunchEvent, BlockBreakEvent, BlockPlaceEvent.

FAQ

  • Q: Why abstract methods are used and not annotation-driven event handler?
    A: Because annotation-driven handling means use of native code to invoke registered methods, which is slower. Also there can be multiple method registrations for one event, which will mean poorer performance.
  • Q: Is it possible to register Bukkit events in implementations?
    A: Yes. It is but not advised unless current CTFBattleClass api doesnt provide enough handles. Call registerBukkitHandler() and register events as would be done in normal Bukkit plugin.

API Setup Guide

Eclipse:

  1. Create new project, add references Bukkit server jar and this plugin jar.
  2. Create new class with the name of wanted battle class in any package (except 'ctf', 'defaultclassesand' and 'lib') then extend it to this class ( MyBattleClass extends CTFBattleClass).
  3. Eclipse will ask to add unimplemented methods or to make created class abstract, option to add unimplemented methods should be chosen.
  4. Generated methods will appear in the class body, ready for modification.
  5. File 'crcfg.yml' must be created in the project (outside src folder). It must contain 'CRclass' field and it's path must lead to main implementation class.

    crcfg.yml Example:
    CRclass: com.rito.MyBattleClass
    CRname: My Battle Class
    CRdesc: [Rito's first, battle class, implementation]


BattleClass Implementation Examples

Ninja - Can be compiled into <any name>.jar
crcfg.yml:
CRclass: Ninja
CRname: Ninja
CRdesc: [Ninja class outputs high, amount of damage in, close combat]


CRclass field denotes path to main file (Ninja.java is in default package, if it was in 'com.example' then CRclass would be 'com.example.Ninja'
CRname field denotes custom name for this class
CRdesc denotes user-friendly description of this class. Array is used to ensure that lore fits into screen when displayed on an item. Lore lines breaks are denoted by coma characters ','

Note that this implementation implements Bukkit Listener interface. This is only needed because Ninja class must listen to Bukkit PlayerItemHeldEvent, PlayerTeleportEvent and ProjectileHitEvent events. After event method is called by contract implementation must check that 'this player' is the same player involved into the event. An implementation may not need to implement Listener interface at all if it does not require more 'information' input than already provided by abstract methods.