-
-
Notifications
You must be signed in to change notification settings - Fork 9
Create a Special Mob
- Creating a new Special Mob Class
- Extended Mobs
- Add Mob logic.
- Utils for Special Mobs
- Registering your special mob
Creating a new Special Mob is fairly simple.
It requires only basic knowledge about Java and the Spigot API.
All special mobs are located in the package de.eldoria.bloodnight.specialmobs.mobs
.
Every mob type is grouped in its own package.
All special mobs extends the abstract class SpecialMob<T extends LivingEntity>
.
If you want to add a mob of an already present type use the matching subclass.
For Creeper
there is a class called AbstractCreeper
which can be used.
If the mob type is present your class would look like this:
public class SpecialCreeper extends AbstractCreeper {
public SpecialCreeper(Creeper creeper) {
super(creeper);
}
}
If the mob type is not present you first have to create a abstract class for this type in a new package with the name of the type.\
public abstract class AbstractMobType extends SpecialMob<NewMobType> {
public AbstractMobType(NewMobType creeper) {
super(creeper);
}
}
After this you just go on and extend the new special mob class which you created.
Sometimes you may want to use an extended mob like a spider with something on it. In this case use the ExtendedSpecialMobClass.
This class already implements the logic for attribute, name and damage synchronization.
public class ExtendedSpecialMob<T extends Mob, U extends Mob> extends SpecialMob<T>{
}
If you spawn mobs only use the SpecialMobUtil#spawnAndMount() method. This will handle tagging and mounting for you.
A special mob can react to different events, which are called when implemented.
If you want to subscribe to an event just override the method of the super class.
Following events are valid:
/**
* Called at a fixed amount of ticks while the blood night is active.
* Counting ticks is not a best practice, since the tick speed is not fixed and can be changed.
* Use {@link java.time.Instant} to measure time since the last action.
*/
public void tick() {
}
/**
* Called when a blood night ends and the special mob is going to be removed in the next step.
* The mob will be removed by the {@link #remove()} method. Therefore this method should not remove the mob.
*/
public void onEnd() {
}
/**
* Called when the special mob teleports.
*/
public void onTeleport(EntityTeleportEvent event) {
}
/**
* Called when the special mob launches a projectile.
*/
public void onProjectileShoot(ProjectileLaunchEvent event) {
}
/**
* Called when a projectile launched by the special mob hit something.
*/
public void onProjectileHit(ProjectileHitEvent event) {
}
/**
* Called when the special mob dies.
*
* @param event The death event of the death of the special mob.
*/
public void onDeath(EntityDeathEvent event) {
}
/**
* Called when the special mob kills another entity.
*
* @param event The death event of the killed entity.
*/
public void onKill(EntityDeathEvent event) {
}
/**
* Called when a special mob starts to explode.
*
* @param event event of the special mob starting to explode
*/
public void onExplosionPrimeEvent(ExplosionPrimeEvent event) {
}
/**
* Called when a special mob exploded.
*
* @param event event of the explosion of the special mob
*/
public void onExplosionEvent(EntityExplodeEvent event) {
}
/**
* Called when a special mob changes its target.
* This will only be called, when the new target is of type player or null.
* A special mob will never target something else then a player.
*
* @param event event containing the new target
*/
public void onTargetEvent(EntityTargetEvent event) {
}
/**
* Called when the special mob takes damage
* This is a less specific version of {@link #onDamageByEntity(EntityDamageByEntityEvent)}. Do not implement both.
*
* @param event damage event of the special mob taking damage
*/
public void onDamage(EntityDamageEvent event) {
}
/**
* Called when the entity takes damage from another entity
* This is a more specific version of {@link #onDamage(EntityDamageEvent)}. Do not implement both.
*
* @param event damage event of the special mob taking damage
*/
public void onDamageByEntity(EntityDamageByEntityEvent event) {
}
/**
* Called when the entity damages another entity
*
* @param event event of the special mob dealing damage
*/
public void onHit(EntityDamageByEntityEvent event) {
}
/**
* This event is called when a entity which is tagged as special mob extension receives damage. This will be most
* likely the passenger or the carrier of a special mob.
* This event should be used for damage synchronization.
* Best practise should be that the damage to the extension is forwarded to the base mob.
* Dont implement this if the special mob doesn't has an extension.
*
* @param event damage event of the extension taking damage,
*/
public void onExtensionDamage(EntityDamageEvent event) {
}
/**
* This event is called when a entity which is tagged as special mob extension is killed.
* This will be most likely the passenger or the carrier of a special mob.
* This event should be used to kill the remaining entity.
* Dont implement this if the mob doesn't has an extension.
*
* @param event damage event of the extension taking damage,
*/
public void onExtensionDeath(EntityDeathEvent event) {
}
The plugin has already some notable classes for easier effect creation.\
The class SpecialMobUtil
provides some useful methods to build effects and stuff.
Here is a collection of some useful methods. You may explore this class by yourself.
/**
* Adds a simple potion effect to a entitiy.
*
* @param entity entity to add potion effect
* @param type type of potion effect
* @param amplifier amplifier
* @param visible true if particles should be visible
*/
public static void addPotionEffect(LivingEntity entity, PotionEffectType type, int amplifier, boolean visible) {
}
/**
* Spawns particle around a entity.
*
* @param entity entity as center
* @param particle particle to spawn
* @param amount amount to spawn
*/
public static void spawnParticlesAround(Entity entity, Particle particle, int amount) {
}
/**
* Spawns particle around a location.
*
* @param location location as center
* @param particle particle to spawn
* @param amount amount to spawn
*/
public static void spawnParticlesAround(Location location, Particle particle, int amount) {
}
/**
* Spawns particle around a location.
*
* @param location location as center
* @param particle particle to spawn
* @param data data which may be required for spawning the particle
* @param amount amount to spawn
* @param <T> type of date
*/
public static <T> void spawnParticlesAround(Location location, Particle particle, T data, int amount) {
}
/**
* Launches a projectile on the current target of the entity.
*
* @param source source of the projectile.
* @param projectile projectile type
* @param speed projectile speed
* @param <T> type of projectile
*
* @return projectile or null if target is null
*/
public static <T extends Projectile> T launchProjectileOnTarget(Mob source, Class<T> projectile, double speed) {
}
/**
* Launches a projectile.
*
* @param source source of the projectile.
* @param target target of the projectile.
* @param projectile projectile type
* @param speed projectile speed
* @param <T> type of projectile
*
* @return projectile or null if target is null
*/
public static <T extends Projectile> T launchProjectileOnTarget(Mob source, Entity target, Class<T> projectile, double speed) {
}
/**
* Spawn and mount a entity as a passenger
*
* @param passengerType type of passenger
* @param carrier carrier where the passenger should be mounted on
* @param <T> type of carrier
*
* @return spawned passenger which is already mounted.
*/
public static <T extends Entity> T spawnAndMount(Entity carrier, EntityType passengerType) {
}
/**
* Spawn and mount a entity on a carrier
*
* @param carrierType type of carrier
* @param rider rider to mount
* @param <T> type of carrier
*
* @return spawned carrier with the rider mounted.
*/
public static <T extends Entity> T spawnAndMount(EntityType carrierType, Entity rider) {
}
/**
* Spawns a new entity and tags it as special mob.
*
* @param location location of the new entity
* @param entityType type of the entity
* @param <T> type of the entity
*
* @return spawned entity of type
*/
public static <T extends Entity> T spawnAndTagEntity(Location location, EntityType entityType) {
}
/**
* Marks a entity as a special mob extension
*
* @param entity entity to mark
* @param extended the entity which is extended
*/
public static void tagExtension(Entity entity, Entity extended) {
}
/**
* Checks if a entity is a extension of a special mob.
*
* @param entity entity to check
*
* @return true if the entity is a extension
*/
public static boolean isExtension(Entity entity) {
}
/**
* Get the UUID of the base mob. This will only return a UUID if {@link #isExtension(Entity)} returns true
*
* @param entity entity to check
*
* @return returns a uuid if the mob is a extension.
*/
public static Optional<UUID> getBaseUUID(Entity entity) {
}
/**
* Set the special mob type.
*
* @param entity entity to set
* @param type type to set
*/
public static void setSpecialMobType(Entity entity, String type) {
}
/**
* Get the Special Mob type
*
* @param entity entity to check
*
* @return optional string with the mob type or a empty optional
*/
public static Optional<String> getSpecialMobType(Entity entity) {
}
/**
* Tags an entity as special mob.
* This also sets {@link Entity#setPersistent(boolean)} to {@code false}
* and {@link LivingEntity#setRemoveWhenFarAway(boolean)} to {@code true}
*
* @param entity entity to tag
*/
public static void tagSpecialMob(Entity entity) {
}
/**
* Checks if a mob is a special mob
*
* @param entity entity to check
*
* @return true if the mob is a special mob
*/
public static boolean isSpecialMob(Entity entity) {
}
/**
* Handles the damage which was dealt to one entity to the extension or base.
*
* @param receiver receiver of the damage.
* @param other the other part of the mob.
* @param event the damage event
*/
public static void handleExtendedEntityDamage(LivingEntity receiver, LivingEntity other, EntityDamageEvent event) {
}
/**
* Builds a particle cloud and binds it to an entity.
* In the most cases {@link #spawnParticlesAround(Entity, Particle, int)} will result in a better result.
*
* @param target target to which the particle cloud should be bound.
*
* @return builder
*/
public static ParticleCloud.Builder buildParticleCloud(LivingEntity target) {
}
/**
* Build a particle cloud which is bound to a entity
*
* @param target entity which will be followed by the cloud
*
* @return builder
*/
public static PotionCloud.Builder buildPotionCloud(LivingEntity target) {
}
/**
* Build a particle cloud at a specific location.
*
* @param location location where the cloud should be created
*
* @return builder
*/
public static PotionCloud.Builder buildParticleCloud(Location location) {
}
When you implemented the logic for your mob only one step is missing.\
Go to SpecialMobRegistry
and initialize your mob in the static block by calling the registerMob() method.
This is simple and should be done in one line.
And that's it you created you own mob. Now just create a Pull Request and I will review your mob.
Blood Night
Features:
Features
Special Mobs
Configuration:
Getting Started
Configuration
Preconfigured Mobs
Commands & Permissions
Placeholders
Contributing:
Add a Special Mob
Hook into Blood Night