2020-01-21 10:42:42 -06:00
package net.seanomik.tamablefoxes ;
2020-01-26 01:05:18 -06:00
import net.minecraft.server.v1_15_R1.* ;
2020-01-26 17:57:21 -06:00
import net.seanomik.tamablefoxes.versions.version_1_15.command.CommandSpawnTamableFox ;
2020-01-26 01:05:18 -06:00
import net.seanomik.tamablefoxes.io.Config ;
import net.seanomik.tamablefoxes.io.LanguageConfig ;
2020-01-21 10:42:42 -06:00
import net.wesjd.anvilgui.AnvilGUI ;
import org.bukkit.* ;
2020-01-26 01:05:18 -06:00
import org.bukkit.Material ;
import org.bukkit.Particle ;
2020-01-21 10:42:42 -06:00
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity ;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer ;
import org.bukkit.entity.Entity ;
2020-01-24 10:21:13 -06:00
import org.bukkit.entity.EntityType ;
2020-01-21 10:42:42 -06:00
import org.bukkit.entity.Player ;
import org.bukkit.event.EventHandler ;
import org.bukkit.event.Listener ;
2020-01-26 01:05:18 -06:00
import org.bukkit.event.entity.EntityDeathEvent ;
2020-01-24 10:21:13 -06:00
import org.bukkit.event.entity.EntitySpawnEvent ;
2020-01-26 01:05:18 -06:00
import org.bukkit.event.player.PlayerBedEnterEvent ;
import org.bukkit.event.player.PlayerBedLeaveEvent ;
2020-01-24 10:21:13 -06:00
import org.bukkit.event.player.PlayerInteractEntityEvent ;
import org.bukkit.event.player.PlayerJoinEvent ;
2020-01-26 17:57:21 -06:00
import org.bukkit.event.world.ChunkLoadEvent ;
2020-01-24 10:21:13 -06:00
import org.bukkit.event.world.WorldSaveEvent ;
2020-01-21 10:42:42 -06:00
import org.bukkit.inventory.EquipmentSlot ;
import org.bukkit.inventory.ItemStack ;
import org.bukkit.inventory.meta.ItemMeta ;
import org.bukkit.plugin.java.JavaPlugin ;
2020-01-24 10:21:13 -06:00
import java.lang.reflect.Field ;
import java.lang.reflect.Modifier ;
import java.util.ArrayList ;
2020-01-21 10:42:42 -06:00
import java.util.List ;
import java.util.stream.Collectors ;
2020-01-26 17:57:21 -06:00
// @TODO:
2020-01-27 08:02:38 -06:00
/ * @CHANGELOG ( 1 . 5 . 2 ) :
* Removed debug messages
2020-01-26 17:57:21 -06:00
* /
2020-01-24 10:21:13 -06:00
public final class TamableFoxes extends JavaPlugin implements Listener {
private static TamableFoxes plugin ;
public List < EntityTamableFox > spawnedFoxes = new ArrayList < > ( ) ;
2020-01-21 10:42:42 -06:00
2020-01-26 01:05:18 -06:00
private boolean versionSupported = true ;
2020-01-21 10:42:42 -06:00
@Override
2020-01-24 10:21:13 -06:00
public void onLoad ( ) {
2020-01-26 01:05:18 -06:00
plugin = this ;
LanguageConfig . getConfig ( ) . saveDefault ( ) ;
2020-01-21 10:42:42 -06:00
String version = Bukkit . getServer ( ) . getClass ( ) . getPackage ( ) . getName ( ) ;
if ( ! version . equals ( " org.bukkit.craftbukkit.v1_15_R1 " ) ) {
2020-01-26 01:05:18 -06:00
Bukkit . getServer ( ) . getConsoleSender ( ) . sendMessage ( Utils . getPrefix ( ) + ChatColor . RED + LanguageConfig . getUnsupportedMCVersionRegister ( ) ) ;
versionSupported = false ;
2020-01-21 10:42:42 -06:00
return ;
}
2020-01-24 10:21:13 -06:00
try { // Replace the fox entity
Field field = EntityTypes . FOX . getClass ( ) . getDeclaredField ( " ba " ) ;
field . setAccessible ( true ) ;
2020-01-21 10:42:42 -06:00
2020-01-24 10:21:13 -06:00
// Remove the final modifier from the "ba" variable
Field fieldMutable = field . getClass ( ) . getDeclaredField ( " modifiers " ) ;
fieldMutable . setAccessible ( true ) ;
fieldMutable . set ( field , fieldMutable . getInt ( field ) & ~ Modifier . FINAL ) ;
fieldMutable . setAccessible ( false ) ;
2020-01-21 10:42:42 -06:00
2020-01-24 10:21:13 -06:00
field . set ( EntityTypes . FOX , ( EntityTypes . b < EntityFox > ) ( type , world ) - > new EntityTamableFox ( type , world ) ) ;
2020-01-21 10:42:42 -06:00
2020-01-24 10:21:13 -06:00
field . setAccessible ( false ) ;
2020-01-21 10:42:42 -06:00
2020-01-26 01:05:18 -06:00
getServer ( ) . getConsoleSender ( ) . sendMessage ( Utils . getPrefix ( ) + ChatColor . GREEN + LanguageConfig . getSuccessReplaced ( ) ) ;
2020-01-24 10:21:13 -06:00
} catch ( Exception e ) {
e . printStackTrace ( ) ;
2020-01-26 01:05:18 -06:00
getServer ( ) . getConsoleSender ( ) . sendMessage ( Utils . getPrefix ( ) + ChatColor . RED + LanguageConfig . getFailureReplace ( ) ) ;
2020-01-24 10:21:13 -06:00
}
2020-01-21 10:42:42 -06:00
}
@Override
2020-01-24 10:21:13 -06:00
public void onEnable ( ) {
2020-01-26 01:05:18 -06:00
if ( ! versionSupported ) {
Bukkit . getServer ( ) . getConsoleSender ( ) . sendMessage ( Utils . getPrefix ( ) + ChatColor . RED + LanguageConfig . getUnsupportedMCVersionDisable ( ) ) ;
2020-01-24 10:21:13 -06:00
getServer ( ) . getPluginManager ( ) . disablePlugin ( this ) ;
return ;
2020-01-21 10:42:42 -06:00
}
2020-01-24 10:21:13 -06:00
getServer ( ) . getPluginManager ( ) . registerEvents ( this , this ) ;
this . getCommand ( " spawntamablefox " ) . setExecutor ( new CommandSpawnTamableFox ( this ) ) ;
2020-01-21 10:42:42 -06:00
2020-01-24 10:21:13 -06:00
this . saveDefaultConfig ( ) ;
getConfig ( ) . options ( ) . copyDefaults ( true ) ;
saveConfig ( ) ;
2020-01-21 10:42:42 -06:00
}
2020-01-24 10:21:13 -06:00
@Override
public void onDisable ( ) {
2020-01-26 01:05:18 -06:00
getServer ( ) . getConsoleSender ( ) . sendMessage ( Utils . getPrefix ( ) + ChatColor . YELLOW + LanguageConfig . getSavingFoxMessage ( ) ) ;
2020-01-28 18:14:44 +00:00
spawnedFoxes . forEach ( EntityTamableFox : : saveNbt ) ;
2020-01-21 10:42:42 -06:00
}
2020-01-24 10:21:13 -06:00
@EventHandler
public void onWorldSaveEvent ( WorldSaveEvent event ) {
2020-01-28 18:14:44 +00:00
spawnedFoxes . forEach ( EntityTamableFox : : saveNbt ) ;
2020-01-24 10:21:13 -06:00
}
2020-01-21 10:42:42 -06:00
2020-01-26 17:57:21 -06:00
@EventHandler
public void onChunkLoad ( ChunkLoadEvent event ) {
Bukkit . getScheduler ( ) . runTaskLaterAsynchronously ( this , ( ) - > {
2020-01-27 23:46:29 +00:00
spawnedFoxes . addAll ( Utils . loadFoxesInChunk ( event . getChunk ( ) ) ) ;
2020-01-26 17:57:21 -06:00
} , 5L ) ;
}
2020-01-24 10:21:13 -06:00
@EventHandler
public void onPlayerJoin ( PlayerJoinEvent event ) {
Player player = event . getPlayer ( ) ;
2020-01-21 10:42:42 -06:00
2020-01-24 10:21:13 -06:00
for ( EntityTamableFox fox : getFoxesOf ( player ) ) {
fox . setOwner ( ( EntityLiving ) ( ( CraftEntity ) player ) . getHandle ( ) ) ;
2020-01-21 10:42:42 -06:00
}
}
@EventHandler
2020-01-24 10:21:13 -06:00
public void onEntitySpawn ( EntitySpawnEvent event ) {
Entity entity = event . getEntity ( ) ;
if ( Utils . isTamableFox ( entity ) ) {
EntityTamableFox tamableFox = ( EntityTamableFox ) ( ( CraftEntity ) entity ) . getHandle ( ) ;
2020-01-21 10:42:42 -06:00
2020-01-24 10:21:13 -06:00
spawnedFoxes . add ( tamableFox ) ;
}
2020-01-21 10:42:42 -06:00
}
@EventHandler
public void onPlayerInteractEntityEvent ( PlayerInteractEntityEvent event ) {
Entity entity = event . getRightClicked ( ) ;
Player player = event . getPlayer ( ) ;
2020-01-24 10:21:13 -06:00
if ( event . getHand ( ) ! = EquipmentSlot . HAND ) return ;
2020-01-21 10:42:42 -06:00
2020-01-24 10:21:13 -06:00
ItemStack itemHand = player . getInventory ( ) . getItemInMainHand ( ) ;
ItemMeta handMeta = itemHand . getItemMeta ( ) ;
2020-01-21 10:42:42 -06:00
2020-01-24 10:21:13 -06:00
// Checks if the entity is EntityTamableFox and that the player is allowed to tame foxes
if ( Utils . isTamableFox ( entity ) ) {
2020-01-21 10:42:42 -06:00
EntityTamableFox tamableFox = ( EntityTamableFox ) ( ( CraftEntity ) entity ) . getHandle ( ) ;
2020-01-28 18:14:44 +00:00
// Check if its tamed but ignore it if the player is holding sweet berries for breeding or nametag for renaming
if ( tamableFox . isTamed ( ) & & tamableFox . getOwner ( ) ! = null & & itemHand . getType ( ) ! = Material . SWEET_BERRIES & & itemHand . getType ( ) ! = Material . NAME_TAG ) {
2020-01-24 10:21:13 -06:00
if ( tamableFox . getOwner ( ) . getUniqueID ( ) = = player . getUniqueId ( ) ) {
2020-01-28 18:14:44 +00:00
event . setCancelled ( true ) ;
2020-01-21 10:42:42 -06:00
if ( player . isSneaking ( ) ) {
2020-01-24 10:21:13 -06:00
net . minecraft . server . v1_15_R1 . ItemStack foxMouth = tamableFox . getEquipment ( EnumItemSlot . MAINHAND ) ;
2020-01-28 18:14:44 +00:00
if ( ! foxMouth . isEmpty ( ) ) tamableFox . dropMouthItem ( ) ;
if ( itemHand . getType ( ) ! = Material . AIR ) {
2020-01-24 10:21:13 -06:00
tamableFox . setMouthItem ( itemHand ) ;
2020-01-28 18:14:44 +00:00
if ( itemHand . getAmount ( ) = = 1 ) player . getInventory ( ) . removeItem ( itemHand ) ;
else itemHand . setAmount ( itemHand . getAmount ( ) - 1 ) ;
2020-01-21 10:42:42 -06:00
}
} else {
tamableFox . toggleSitting ( ) ;
}
}
2020-01-24 10:21:13 -06:00
} else if ( itemHand . getType ( ) = = Material . CHICKEN & & Config . canPlayerTameFox ( player ) ) {
if ( Math . random ( ) < 0 . 33D ) { // tamed
2020-01-21 10:42:42 -06:00
tamableFox . setTamed ( true ) ;
tamableFox . setOwner ( ( ( CraftPlayer ) player ) . getHandle ( ) ) ;
2020-01-28 18:14:44 +00:00
2020-01-21 10:42:42 -06:00
player . getWorld ( ) . spawnParticle ( Particle . HEART , entity . getLocation ( ) , 6 , 0 . 5D , 0 . 5D , 0 . 5D ) ;
2020-01-28 18:14:44 +00:00
player . sendMessage ( ChatColor . RED + ChatColor . BOLD . toString ( ) + LanguageConfig . getTamedMessage ( ) ) ;
2020-01-24 10:21:13 -06:00
2020-01-28 18:14:44 +00:00
if ( Config . askForNameAfterTaming ( ) ) {
player . sendMessage ( ChatColor . RED + LanguageConfig . getTamingAskingName ( ) ) ;
new AnvilGUI . Builder ( )
. onComplete ( ( plr , text ) - > { // Called when the inventory output slot is clicked
if ( ! text . equals ( " " ) ) {
tamableFox . getBukkitEntity ( ) . setCustomName ( text ) ;
tamableFox . setCustomNameVisible ( true ) ;
plr . sendMessage ( Utils . getPrefix ( ) + ChatColor . GREEN + LanguageConfig . getTamingChosenPerfect ( text ) ) ;
tamableFox . saveNbt ( ) ;
}
return AnvilGUI . Response . close ( ) ;
} )
//.preventClose() // Prevents the inventory from being closed
. text ( " Fox name " ) // Sets the text the GUI should start with
. plugin ( this ) // Set the plugin instance
. open ( player ) ; // Opens the GUI for the player provided
}
2020-01-24 10:21:13 -06:00
} else { // Tame failed
2020-01-21 10:42:42 -06:00
player . getWorld ( ) . spawnParticle ( Particle . SMOKE_NORMAL , entity . getLocation ( ) , 10 , 0 . 3D , 0 . 3D , 0 . 3D , 0 . 15D ) ;
}
if ( ! player . getGameMode ( ) . equals ( GameMode . CREATIVE ) ) {
2020-01-28 18:14:44 +00:00
if ( itemHand . getAmount ( ) = = 1 ) player . getInventory ( ) . removeItem ( itemHand ) ;
else itemHand . setAmount ( itemHand . getAmount ( ) - 1 ) ;
2020-01-21 10:42:42 -06:00
}
event . setCancelled ( true ) ;
}
}
}
2020-01-26 01:05:18 -06:00
@EventHandler
public void onPlayerBedEnterEvent ( PlayerBedEnterEvent event ) {
Player player = event . getPlayer ( ) ;
List < EntityTamableFox > foxesOf = getFoxesOf ( player ) ;
for ( EntityTamableFox tamableFox : foxesOf ) {
if ( player . getWorld ( ) . getTime ( ) > 12541L & & player . getWorld ( ) . getTime ( ) < 23460L ) {
tamableFox . setSleeping ( true ) ;
}
}
}
@EventHandler
public void onPlayerBedLeaveEvent ( PlayerBedLeaveEvent event ) {
Player player = event . getPlayer ( ) ;
List < EntityTamableFox > foxesOf = getFoxesOf ( player ) ;
for ( EntityTamableFox tamableFox : foxesOf ) {
tamableFox . setSleeping ( false ) ;
if ( tamableFox . isSitting ( ) ) {
tamableFox . setSitting ( true ) ;
}
}
}
@EventHandler
public void onEntityDeathEvent ( EntityDeathEvent event ) {
Entity entity = event . getEntity ( ) ;
if ( ! Utils . isTamableFox ( entity ) ) return ; // Is the entity a tamable fox?
// Remove the fox from storage
spawnedFoxes . remove ( entity ) ;
// Notify the owner
EntityTamableFox tamableFox = ( EntityTamableFox ) ( ( CraftEntity ) entity ) . getHandle ( ) ;
if ( tamableFox . getOwner ( ) ! = null ) {
Player owner = ( ( EntityPlayer ) tamableFox . getOwner ( ) ) . getBukkitEntity ( ) ;
2020-01-28 18:14:44 +00:00
owner . sendMessage ( Utils . getPrefix ( ) + ChatColor . RED + ( tamableFox . hasCustomName ( ) ? tamableFox . getBukkitEntity ( ) . getCustomName ( ) : " Your fox " ) + " was killed! " ) ;
2020-01-26 01:05:18 -06:00
}
}
2020-01-24 10:21:13 -06:00
public EntityTamableFox spawnTamableFox ( Location loc , EntityFox . Type type ) {
EntityTamableFox tamableFox = ( EntityTamableFox ) ( ( CraftEntity ) loc . getWorld ( ) . spawnEntity ( loc , EntityType . FOX ) ) . getHandle ( ) ;
tamableFox . setFoxType ( type ) ;
2020-01-21 10:42:42 -06:00
2020-01-24 10:21:13 -06:00
return tamableFox ;
2020-01-21 10:42:42 -06:00
}
2020-01-24 10:21:13 -06:00
public List < EntityTamableFox > getFoxesOf ( Player player ) {
2020-01-26 01:05:18 -06:00
return spawnedFoxes . stream ( ) . filter ( fox - > fox . getOwner ( ) ! = null & & fox . getOwner ( ) . getUniqueID ( ) . equals ( player . getUniqueId ( ) ) ) . collect ( Collectors . toList ( ) ) ;
2020-01-21 10:42:42 -06:00
}
2020-01-24 10:21:13 -06:00
public static TamableFoxes getPlugin ( ) {
return plugin ;
2020-01-21 10:42:42 -06:00
}
}