mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-22 05:06:45 +01:00
Numerous COTW tweaks
This commit is contained in:
parent
a66940b2b8
commit
53d6065185
@ -1,3 +1,46 @@
|
||||
Version 2.1.92
|
||||
Call Of The Wild (COTW) no longer cares if entities of the same type are nearby when attempting to summon a new entity
|
||||
By default players are no longer allowed to breed COTW summoned animals with other animals, you can turn this off (see the notes)
|
||||
Changed the sound effect for COTW (Fireworks -> Pop)
|
||||
Fixed a bug where COTW summon limit was global instead of per player
|
||||
The default summon limit for COTW is now per player instead of global which is how it is intended to be, for wolves this defaults to 2, for other entities it defaults to 1
|
||||
There is now a small 150ms window in which you cannot summon an entity via COTW to prevent accidentally summoning extra entities
|
||||
The setting named Summon_Max_Amount in config.yml has been renamed to Per_Player_Limit
|
||||
COTW entities now send the player a message when they die, time out, or get removed through other means
|
||||
If the COTW summon has a lifespan, players are now informed about this lifespan when the entity is first summoned
|
||||
COTW summons now have their name prefixed with some colored text to to make it easier to identify them.
|
||||
COTW summons now despawn if their owner logs out
|
||||
If a player tries to breed animals with a COTW animal and the server settings prevent this, they are informed via a message that it is not allowed
|
||||
Added new setting to experience.yml 'ExploitFix.COTWBreeding' - Prevents breeding with COTW summoned entities when set to true, defaults to true
|
||||
Removed the 'mcmmo.ability.taming.callofthewild.renamepets' permission node as it is seen as unnecessary
|
||||
|
||||
Removed locale strings
|
||||
Taming.Summon.Fail.Ocelot
|
||||
Taming.Summon.Fail.Wolf
|
||||
Taming.Summon.Fail.Horse
|
||||
Added new locale strings
|
||||
Taming.Summon.COTW.BreedingDisallowed
|
||||
Taming.Summon.COTW.Success
|
||||
Taming.Summon.COTW.Limit
|
||||
Taming.Summon.COTW.TimeExpired
|
||||
Tweaked locale string
|
||||
Taming.Summon.Name.Format
|
||||
|
||||
NOTES:
|
||||
I plan to rework Call of The Wild (COTW) significantly in the upcoming content patch, until then I have made several tweaks to it.
|
||||
|
||||
COTW Summoning Requirement Changes
|
||||
It is intentional that you are not supposed to be able to COTW summon something that you already have tamed, but mcMMO was not checking this properly.
|
||||
So previous to this patch, if you tried to summon a wolf and wolves were nearby, it would fail. This is not intentional behaviour and was a bug.
|
||||
The correct behaviour is that if you try to summon a wolf and you already have wolves, it should fail.
|
||||
I was fixing this bug when it occurred to me, why do we even care if nearby tamed wolves owned by you exist if you are trying to summon a temporary one?
|
||||
As a result of this train of thought, I have removed this restriction on COTW and several other tweaks have been made as a result of this line of thinking.
|
||||
There was also an issue involving how many COTW entities could be out at once, for some reason the limit was applied globally and defaulted to 10, so if 10 players had COTW entities out no one else would be able to summon anything. I have fixed this.
|
||||
You can set the lifespan to 0 in the config to make it so that COTW entities last until a server restart or the player logs out.
|
||||
|
||||
COTW Breeding Change
|
||||
It was never intentional for COTW summoned entities to be breedable, by default they will not be. You can change this by setting 'ExploitFix.COTWBreeding' to false in experience.yml
|
||||
|
||||
Version 2.1.91
|
||||
mcMMO is now more compatible with plugins that spawn arrows in unexpected ways, this fixes some NPE in mcMMO when using certain plugins
|
||||
Fixed a bug where Unarmed was using the same CD timer for every player in the server (thanks slop_me)
|
||||
|
2
pom.xml
2
pom.xml
@ -2,7 +2,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.gmail.nossr50.mcMMO</groupId>
|
||||
<artifactId>mcMMO</artifactId>
|
||||
<version>2.1.91</version>
|
||||
<version>2.1.92-SNAPSHOT</version>
|
||||
<name>mcMMO</name>
|
||||
<url>https://github.com/mcMMO-Dev/mcMMO</url>
|
||||
<scm>
|
||||
|
@ -198,41 +198,41 @@ public class Config extends AutoUpdateConfigLoader {
|
||||
reason.add("Cannot use the same item for Repair and Salvage anvils!");
|
||||
}
|
||||
|
||||
if (getTamingCOTWMaterial(EntityType.WOLF) == null) {
|
||||
reason.add("Skills.Taming.Call_Of_The_Wild.Wolf.Item_Material is invalid!!");
|
||||
}
|
||||
|
||||
if (getTamingCOTWMaterial(EntityType.OCELOT) == null) {
|
||||
reason.add("Skills.Taming.Call_Of_The_Wild.Ocelot.Item_Material is invalid!!");
|
||||
}
|
||||
|
||||
if (getTamingCOTWMaterial(EntityType.HORSE) == null) {
|
||||
reason.add("Skills.Taming.Call_Of_The_Wild.Horse.Item_Material is invalid!!");
|
||||
}
|
||||
|
||||
if (getTamingCOTWCost(EntityType.WOLF) <= 0) {
|
||||
reason.add("Skills.Taming.Call_Of_The_Wild.Wolf.Item_Amount should be greater than 0!");
|
||||
}
|
||||
|
||||
if (getTamingCOTWCost(EntityType.OCELOT) <= 0) {
|
||||
reason.add("Skills.Taming.Call_Of_The_Wild.Ocelot.Item_Amount should be greater than 0!");
|
||||
}
|
||||
|
||||
if (getTamingCOTWCost(EntityType.HORSE) <= 0) {
|
||||
reason.add("Skills.Taming.Call_Of_The_Wild.Horse.Item_Amount should be greater than 0!");
|
||||
}
|
||||
|
||||
if (getTamingCOTWAmount(EntityType.WOLF) <= 0) {
|
||||
reason.add("Skills.Taming.Call_Of_The_Wild.Wolf.Summon_Amount should be greater than 0!");
|
||||
}
|
||||
|
||||
if (getTamingCOTWAmount(EntityType.OCELOT) <= 0) {
|
||||
reason.add("Skills.Taming.Call_Of_The_Wild.Ocelot.Summon_Amount should be greater than 0!");
|
||||
}
|
||||
|
||||
if (getTamingCOTWAmount(EntityType.HORSE) <= 0) {
|
||||
reason.add("Skills.Taming.Call_Of_The_Wild.Horse.Summon_Amount should be greater than 0!");
|
||||
}
|
||||
// if (getTamingCOTWMaterial(EntityType.WOLF) == null) {
|
||||
// reason.add("Skills.Taming.Call_Of_The_Wild.Wolf.Item_Material is invalid!!");
|
||||
// }
|
||||
//
|
||||
// if (getTamingCOTWMaterial(EntityType.OCELOT) == null) {
|
||||
// reason.add("Skills.Taming.Call_Of_The_Wild.Ocelot.Item_Material is invalid!!");
|
||||
// }
|
||||
//
|
||||
// if (getTamingCOTWMaterial(EntityType.HORSE) == null) {
|
||||
// reason.add("Skills.Taming.Call_Of_The_Wild.Horse.Item_Material is invalid!!");
|
||||
// }
|
||||
//
|
||||
// if (getTamingCOTWCost(EntityType.WOLF) <= 0) {
|
||||
// reason.add("Skills.Taming.Call_Of_The_Wild.Wolf.Item_Amount should be greater than 0!");
|
||||
// }
|
||||
//
|
||||
// if (getTamingCOTWCost(EntityType.OCELOT) <= 0) {
|
||||
// reason.add("Skills.Taming.Call_Of_The_Wild.Ocelot.Item_Amount should be greater than 0!");
|
||||
// }
|
||||
//
|
||||
// if (getTamingCOTWCost(EntityType.HORSE) <= 0) {
|
||||
// reason.add("Skills.Taming.Call_Of_The_Wild.Horse.Item_Amount should be greater than 0!");
|
||||
// }
|
||||
//
|
||||
// if (getTamingCOTWAmount(EntityType.WOLF) <= 0) {
|
||||
// reason.add("Skills.Taming.Call_Of_The_Wild.Wolf.Summon_Amount should be greater than 0!");
|
||||
// }
|
||||
//
|
||||
// if (getTamingCOTWAmount(EntityType.OCELOT) <= 0) {
|
||||
// reason.add("Skills.Taming.Call_Of_The_Wild.Ocelot.Summon_Amount should be greater than 0!");
|
||||
// }
|
||||
//
|
||||
// if (getTamingCOTWAmount(EntityType.HORSE) <= 0) {
|
||||
// reason.add("Skills.Taming.Call_Of_The_Wild.Horse.Summon_Amount should be greater than 0!");
|
||||
// }
|
||||
|
||||
return noErrorsInConfig(reason);
|
||||
}
|
||||
@ -529,12 +529,17 @@ public class Config extends AutoUpdateConfigLoader {
|
||||
public int getSwordsGate() { return config.getInt("Skills.Swords.Ability_Activation_Level_Gate", 10); }
|
||||
|
||||
/* Taming */
|
||||
public Material getTamingCOTWMaterial(EntityType type) { return Material.matchMaterial(config.getString("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type) + ".Item_Material")); }
|
||||
public int getTamingCOTWCost(EntityType type) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type) + ".Item_Amount"); }
|
||||
public int getTamingCOTWAmount(EntityType type) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type) + ".Summon_Amount"); }
|
||||
public int getTamingCOTWLength(EntityType type) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type)+ ".Summon_Length"); }
|
||||
public int getTamingCOTWMaxAmount(EntityType type) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type)+ ".Summon_Max_Amount"); }
|
||||
public double getTamingCOTWRange() { return config.getDouble("Skills.Taming.Call_Of_The_Wild.Range", 40.0D); }
|
||||
// public Material getTamingCOTWMaterial(EntityType type) { return Material.matchMaterial(config.getString("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type) + ".Item_Material")); }
|
||||
// public int getTamingCOTWCost(EntityType type) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type) + ".Item_Amount"); }
|
||||
// public int getTamingCOTWAmount(EntityType type) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type) + ".Summon_Amount"); }
|
||||
// public int getTamingCOTWLength(EntityType type) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type)+ ".Summon_Length"); }
|
||||
// public int getTamingCOTWMaxAmount(EntityType type) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type)+ ".Summon_Max_Amount"); }
|
||||
|
||||
public Material getTamingCOTWMaterial(String cotwEntity) { return Material.matchMaterial(config.getString("Skills.Taming.Call_Of_The_Wild." + cotwEntity + ".Item_Material")); }
|
||||
public int getTamingCOTWCost(String cotwEntity) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + cotwEntity + ".Item_Amount"); }
|
||||
public int getTamingCOTWAmount(String cotwEntity) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + cotwEntity + ".Summon_Amount"); }
|
||||
public int getTamingCOTWLength(String cotwEntity) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + cotwEntity+ ".Summon_Length"); }
|
||||
public int getTamingCOTWMaxAmount(String cotwEntity) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + cotwEntity+ ".Per_Player_Limit", 1); }
|
||||
|
||||
/* Woodcutting */
|
||||
public boolean getWoodcuttingDoubleDropsEnabled(BlockData material) { return config.getBoolean("Bonus_Drops.Woodcutting." + StringUtils.getFriendlyConfigBlockDataString(material)); }
|
||||
|
@ -147,6 +147,7 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
|
||||
public boolean isEndermanEndermiteFarmingPrevented() { return config.getBoolean("ExploitFix.EndermanEndermiteFarms", true); }
|
||||
public boolean isPistonExploitPrevented() { return config.getBoolean("ExploitFix.Pistons", false); }
|
||||
public boolean allowUnsafeEnchantments() { return config.getBoolean("ExploitFix.UnsafeEnchantments", false); }
|
||||
public boolean isCOTWBreedingPrevented() { return config.getBoolean("ExploitFix.COTWBreeding", true); }
|
||||
|
||||
public boolean isFishingExploitingPrevented() { return config.getBoolean("ExploitFix.Fishing", true); }
|
||||
public boolean isAcrobaticsExploitingPrevented() { return config.getBoolean("ExploitFix.Acrobatics", true); }
|
||||
|
@ -1026,8 +1026,8 @@ public class McMMOPlayer {
|
||||
*/
|
||||
public void logout(boolean syncSave) {
|
||||
Player thisPlayer = getPlayer();
|
||||
resetAbilityMode();
|
||||
BleedTimerTask.bleedOut(thisPlayer);
|
||||
BleedTimerTask.bleedOut(getPlayer());
|
||||
cleanup();
|
||||
|
||||
if (syncSave) {
|
||||
getProfile().save(true);
|
||||
@ -1047,4 +1047,15 @@ public class McMMOPlayer {
|
||||
//Remove user from cache
|
||||
mcMMO.getDatabaseManager().cleanupUser(thisPlayer.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup various things related to this player
|
||||
* Such as temporary summons..
|
||||
* Turning off abilities...
|
||||
* Etc...
|
||||
*/
|
||||
public void cleanup() {
|
||||
resetAbilityMode();
|
||||
getTamingManager().cleanupAllSummons();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
package com.gmail.nossr50.datatypes.skills.subskills.taming;
|
||||
|
||||
import com.gmail.nossr50.util.StringUtils;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
public enum CallOfTheWildType {
|
||||
WOLF,
|
||||
CAT,
|
||||
HORSE;
|
||||
|
||||
//TODO: This is a hacky fix to make the COTW code in 2.1 more bearable, this will be removed upon the rework planned for COTW
|
||||
public String getConfigEntityTypeEntry() {
|
||||
|
||||
switch(this) {
|
||||
case CAT:
|
||||
return StringUtils.getPrettyEntityTypeString(EntityType.OCELOT); //Even though cats will be summoned in 1.14, we specify Ocelot here. This will be gone in 2.2
|
||||
case WOLF:
|
||||
return StringUtils.getPrettyEntityTypeString(EntityType.WOLF);
|
||||
case HORSE:
|
||||
return StringUtils.getPrettyEntityTypeString(EntityType.HORSE);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package com.gmail.nossr50.datatypes.skills.subskills.taming;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
/**
|
||||
* Data Container for properties used in summoning an entity via COTW
|
||||
*/
|
||||
public class TamingSummon {
|
||||
|
||||
private Material itemType;
|
||||
private int itemAmountRequired;
|
||||
private int entitiesSummoned;
|
||||
private int summonLifespan;
|
||||
private int summonCap;
|
||||
private CallOfTheWildType callOfTheWildType;
|
||||
private EntityType entityType;
|
||||
|
||||
public TamingSummon(CallOfTheWildType callOfTheWildType, Material itemType, int itemAmountRequired, int entitiesSummoned, int summonLifespan, int summonCap) {
|
||||
this.callOfTheWildType = callOfTheWildType;
|
||||
this.itemType = itemType;
|
||||
this.itemAmountRequired = Math.max(itemAmountRequired, 1);
|
||||
this.entitiesSummoned = Math.max(entitiesSummoned, 1);
|
||||
this.summonLifespan = summonLifespan;
|
||||
this.summonCap = Math.max(summonCap, 1);
|
||||
|
||||
initEntityType();
|
||||
}
|
||||
|
||||
private void initEntityType() {
|
||||
switch(callOfTheWildType) {
|
||||
case WOLF:
|
||||
entityType = EntityType.WOLF;
|
||||
break;
|
||||
case HORSE:
|
||||
entityType = EntityType.HORSE;
|
||||
break;
|
||||
case CAT:
|
||||
if(shouldSpawnCatInsteadOfOcelot()) {
|
||||
//Server is on 1.14 or above
|
||||
entityType = EntityType.CAT;
|
||||
} else {
|
||||
//Server is not on 1.14 or above
|
||||
entityType = EntityType.OCELOT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldSpawnCatInsteadOfOcelot() {
|
||||
try {
|
||||
Class<?> clazz = Class.forName("org.bukkit.entity.Panda");
|
||||
//Panda exists which means this is at least 1.14, so we should spawn a cat instead of ocelot
|
||||
return true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
/*e.printStackTrace();*/
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public EntityType getEntityType() {
|
||||
return entityType;
|
||||
}
|
||||
|
||||
public Material getItemType() {
|
||||
return itemType;
|
||||
}
|
||||
|
||||
public int getItemAmountRequired() {
|
||||
return itemAmountRequired;
|
||||
}
|
||||
|
||||
public int getEntitiesSummoned() {
|
||||
return entitiesSummoned;
|
||||
}
|
||||
|
||||
public int getSummonLifespan() {
|
||||
return summonLifespan;
|
||||
}
|
||||
|
||||
public int getSummonCap() {
|
||||
return summonCap;
|
||||
}
|
||||
|
||||
public CallOfTheWildType getCallOfTheWildType() {
|
||||
return callOfTheWildType;
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ import com.gmail.nossr50.skills.unarmed.UnarmedManager;
|
||||
import com.gmail.nossr50.util.BlockUtils;
|
||||
import com.gmail.nossr50.util.Misc;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.player.NotificationManager;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.random.RandomChanceUtil;
|
||||
import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
@ -733,6 +734,20 @@ public class EntityListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)
|
||||
public void onEntityBreed(EntityBreedEvent event) {
|
||||
if(ExperienceConfig.getInstance().isCOTWBreedingPrevented()) {
|
||||
if(event.getFather().hasMetadata(mcMMO.COTW_TEMPORARY_SUMMON) || event.getMother().hasMetadata(mcMMO.COTW_TEMPORARY_SUMMON)) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
if(event.getBreeder() instanceof Player) {
|
||||
Player player = (Player) event.getBreeder();
|
||||
NotificationManager.sendPlayerInformationChatOnly(player, "Taming.Summon.COTW.BreedingDisallowed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle ExplosionPrime events that involve modifying the event.
|
||||
*
|
||||
|
@ -11,6 +11,7 @@ import com.gmail.nossr50.datatypes.party.Party;
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.subskills.taming.CallOfTheWildType;
|
||||
import com.gmail.nossr50.events.fake.FakePlayerAnimationEvent;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
@ -827,13 +828,13 @@ public class PlayerListener implements Listener {
|
||||
Material type = heldItem.getType();
|
||||
TamingManager tamingManager = mcMMOPlayer.getTamingManager();
|
||||
|
||||
if (type == Config.getInstance().getTamingCOTWMaterial(EntityType.WOLF)) {
|
||||
if (type == Config.getInstance().getTamingCOTWMaterial(CallOfTheWildType.WOLF.getConfigEntityTypeEntry())) {
|
||||
tamingManager.summonWolf();
|
||||
}
|
||||
else if (type == Config.getInstance().getTamingCOTWMaterial(EntityType.OCELOT)) {
|
||||
else if (type == Config.getInstance().getTamingCOTWMaterial(CallOfTheWildType.CAT.getConfigEntityTypeEntry())) {
|
||||
tamingManager.summonOcelot();
|
||||
}
|
||||
else if (type == Config.getInstance().getTamingCOTWMaterial(EntityType.HORSE)) {
|
||||
else if (type == Config.getInstance().getTamingCOTWMaterial(CallOfTheWildType.HORSE.getConfigEntityTypeEntry())) {
|
||||
tamingManager.summonHorse();
|
||||
}
|
||||
|
||||
|
@ -108,6 +108,7 @@ public class mcMMO extends JavaPlugin {
|
||||
/* Metadata Values */
|
||||
public static final String FISH_HOOK_REF_METAKEY = "mcMMO: Fish Hook Tracker";
|
||||
public static final String CUSTOM_DAMAGE_METAKEY = "mcMMO: Custom Damage";
|
||||
public static final String COTW_TEMPORARY_SUMMON = "mcMMO: COTW Entity";
|
||||
public final static String entityMetadataKey = "mcMMO: Spawned Entity";
|
||||
public final static String blockMetadataKey = "mcMMO: Piston Tracking";
|
||||
public final static String furnaceMetadataKey = "mcMMO: Tracked Furnace";
|
||||
|
@ -8,7 +8,8 @@ import com.gmail.nossr50.datatypes.interactions.NotificationType;
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
|
||||
import com.gmail.nossr50.datatypes.skills.SubSkillType;
|
||||
import com.gmail.nossr50.events.fake.FakeEntityTameEvent;
|
||||
import com.gmail.nossr50.datatypes.skills.subskills.taming.CallOfTheWildType;
|
||||
import com.gmail.nossr50.datatypes.skills.subskills.taming.TamingSummon;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.runnables.skills.BleedTimerTask;
|
||||
@ -22,7 +23,10 @@ import com.gmail.nossr50.util.random.RandomChanceUtil;
|
||||
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
|
||||
import com.gmail.nossr50.util.skills.RankUtils;
|
||||
import com.gmail.nossr50.util.skills.SkillActivationType;
|
||||
import com.gmail.nossr50.util.sounds.SoundManager;
|
||||
import com.gmail.nossr50.util.sounds.SoundType;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.*;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -32,11 +36,66 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
public class TamingManager extends SkillManager {
|
||||
//TODO: Temporary static cache, will be changed in 2.2
|
||||
private static HashMap<Material, CallOfTheWildType> summoningItems;
|
||||
private static HashMap<CallOfTheWildType, TamingSummon> cotwSummonDataProperties;
|
||||
private long lastSummonTimeStamp;
|
||||
|
||||
private HashMap<CallOfTheWildType, List<TrackedTamingEntity>> playerSummonedEntities;
|
||||
|
||||
public TamingManager(McMMOPlayer mcMMOPlayer) {
|
||||
super(mcMMOPlayer, PrimarySkillType.TAMING);
|
||||
init();
|
||||
}
|
||||
|
||||
private static HashMap<EntityType, List<TrackedTamingEntity>> summonedEntities = new HashMap<EntityType, List<TrackedTamingEntity>>();
|
||||
//TODO: Hacky stuff for 2.1, will be cleaned up in 2.2
|
||||
private void init() {
|
||||
//prevents accidentally summoning too many things when holding down left click
|
||||
lastSummonTimeStamp = 0L;
|
||||
|
||||
//Init per-player tracking of summoned entities
|
||||
initPerPlayerSummonTracking();
|
||||
|
||||
//Hacky stuff used as a band-aid
|
||||
initStaticCaches();
|
||||
}
|
||||
|
||||
private void initPerPlayerSummonTracking() {
|
||||
playerSummonedEntities = new HashMap<>();
|
||||
|
||||
for(CallOfTheWildType callOfTheWildType : CallOfTheWildType.values()) {
|
||||
playerSummonedEntities.put(callOfTheWildType, new ArrayList<TrackedTamingEntity>());
|
||||
}
|
||||
}
|
||||
|
||||
private void initStaticCaches() {
|
||||
//TODO: Temporary static cache, will be changed in 2.2
|
||||
//This is shared between instances of TamingManager
|
||||
if(summoningItems == null) {
|
||||
summoningItems = new HashMap<>();
|
||||
|
||||
summoningItems.put(Config.getInstance().getTamingCOTWMaterial(CallOfTheWildType.CAT.getConfigEntityTypeEntry()), CallOfTheWildType.CAT);
|
||||
summoningItems.put(Config.getInstance().getTamingCOTWMaterial(CallOfTheWildType.WOLF.getConfigEntityTypeEntry()), CallOfTheWildType.WOLF);
|
||||
summoningItems.put(Config.getInstance().getTamingCOTWMaterial(CallOfTheWildType.HORSE.getConfigEntityTypeEntry()), CallOfTheWildType.HORSE);
|
||||
}
|
||||
|
||||
//TODO: Temporary static cache, will be changed in 2.2
|
||||
//This is shared between instances of TamingManager
|
||||
if(cotwSummonDataProperties == null) {
|
||||
cotwSummonDataProperties = new HashMap<>();
|
||||
|
||||
for(CallOfTheWildType callOfTheWildType : CallOfTheWildType.values()) {
|
||||
Material itemSummonMaterial = Config.getInstance().getTamingCOTWMaterial(callOfTheWildType.getConfigEntityTypeEntry());
|
||||
int itemAmountRequired = Config.getInstance().getTamingCOTWAmount(callOfTheWildType.getConfigEntityTypeEntry());
|
||||
int entitiesSummonedPerCOTW = Config.getInstance().getTamingCOTWAmount(callOfTheWildType.getConfigEntityTypeEntry());
|
||||
int summonLifespanSeconds = Config.getInstance().getTamingCOTWLength(callOfTheWildType.getConfigEntityTypeEntry());
|
||||
int perPlayerMaxAmount = Config.getInstance().getTamingCOTWMaxAmount(callOfTheWildType.getConfigEntityTypeEntry());
|
||||
|
||||
TamingSummon tamingSummon = new TamingSummon(callOfTheWildType, itemSummonMaterial, itemAmountRequired, entitiesSummonedPerCOTW, summonLifespanSeconds, perPlayerMaxAmount);
|
||||
cotwSummonDataProperties.put(callOfTheWildType, tamingSummon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canUseThickFur() {
|
||||
return RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.TAMING_THICK_FUR)
|
||||
@ -98,7 +157,6 @@ public class TamingManager extends SkillManager {
|
||||
* @param damage The damage being absorbed by the wolf
|
||||
*/
|
||||
public void fastFoodService(Wolf wolf, double damage) {
|
||||
//static chance (3rd param)
|
||||
if (!RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_STATIC_CHANCE, SubSkillType.TAMING_FAST_FOOD_SERVICE, getPlayer())) {
|
||||
return;
|
||||
}
|
||||
@ -150,7 +208,7 @@ public class TamingManager extends SkillManager {
|
||||
return;
|
||||
}
|
||||
|
||||
callOfTheWild(EntityType.OCELOT, Config.getInstance().getTamingCOTWCost(EntityType.OCELOT));
|
||||
processCallOfTheWild();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,7 +222,7 @@ public class TamingManager extends SkillManager {
|
||||
return;
|
||||
}
|
||||
|
||||
callOfTheWild(EntityType.WOLF, Config.getInstance().getTamingCOTWCost(EntityType.WOLF));
|
||||
processCallOfTheWild();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -178,7 +236,7 @@ public class TamingManager extends SkillManager {
|
||||
return;
|
||||
}
|
||||
|
||||
callOfTheWild(EntityType.HORSE, Config.getInstance().getTamingCOTWCost(EntityType.HORSE));
|
||||
processCallOfTheWild();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -257,151 +315,243 @@ public class TamingManager extends SkillManager {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void processCallOfTheWild() {
|
||||
//Prevent summoning too many things accidentally if a player holds down the button
|
||||
if(lastSummonTimeStamp + 150 > System.currentTimeMillis()) {
|
||||
return;
|
||||
} else {
|
||||
lastSummonTimeStamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
Player player = getPlayer();
|
||||
ItemStack itemInMainHand = player.getInventory().getItemInMainHand();
|
||||
|
||||
//Check if the item the player is currently holding is a COTW item
|
||||
if(isCOTWItem(itemInMainHand)) {
|
||||
//Get the summoning type
|
||||
CallOfTheWildType callOfTheWildType = summoningItems.get(itemInMainHand.getType());
|
||||
TamingSummon tamingSummon = cotwSummonDataProperties.get(callOfTheWildType);
|
||||
|
||||
|
||||
//Check to see if players have the correct amount of the item required to summon
|
||||
if(itemInMainHand.getAmount() >= tamingSummon.getItemAmountRequired()) {
|
||||
//Initial Spawn location
|
||||
Location spawnLocation = Misc.getLocationOffset(player.getLocation(), 1);
|
||||
|
||||
//COTW can summon multiple entities per usage
|
||||
for (int i = 0; i < tamingSummon.getEntitiesSummoned(); i++) {
|
||||
|
||||
if (getAmountCurrentlySummoned(callOfTheWildType) >= tamingSummon.getSummonCap()) {
|
||||
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Taming.Summon.COTW.Limit", String.valueOf(tamingSummon.getSummonCap()));
|
||||
break;
|
||||
}
|
||||
|
||||
spawnLocation = Misc.getLocationOffset(spawnLocation, 1);
|
||||
spawnCOTWEntity(callOfTheWildType, spawnLocation, tamingSummon.getEntityType());
|
||||
}
|
||||
|
||||
//Remove the items used to summon
|
||||
int itemAmountAfterPayingCost = itemInMainHand.getAmount() - tamingSummon.getItemAmountRequired();
|
||||
itemInMainHand.setAmount(itemAmountAfterPayingCost);
|
||||
player.updateInventory();
|
||||
|
||||
//Inform the player about what they have just done
|
||||
if (tamingSummon.getSummonLifespan() > 0) {
|
||||
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Taming.Summon.COTW.Success",
|
||||
StringUtils.getCapitalized(callOfTheWildType.toString()), String.valueOf(tamingSummon.getSummonLifespan()));
|
||||
} else {
|
||||
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Taming.Summon.Complete");
|
||||
}
|
||||
|
||||
//Send Sound
|
||||
SoundManager.sendSound(player, player.getLocation(), SoundType.ABILITY_ACTIVATED_GENERIC);
|
||||
|
||||
} else {
|
||||
//Player did not have enough of the item in their main hand
|
||||
int difference = tamingSummon.getItemAmountRequired() - itemInMainHand.getAmount();
|
||||
NotificationManager.sendPlayerInformation(player, NotificationType.REQUIREMENTS_NOT_MET, "Item.NotEnough", String.valueOf(difference), StringUtils.getPrettyItemString(itemInMainHand.getType()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void spawnCOTWEntity(CallOfTheWildType callOfTheWildType, Location spawnLocation, EntityType entityType) {
|
||||
switch(callOfTheWildType) {
|
||||
case CAT:
|
||||
//Entity type is needed for cats because in 1.13 and below we spawn ocelots, in 1.14 and above we spawn cats
|
||||
spawnCat(spawnLocation, entityType);
|
||||
break;
|
||||
case HORSE:
|
||||
spawnHorse(spawnLocation);
|
||||
break;
|
||||
case WOLF:
|
||||
spawnWolf(spawnLocation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void spawnWolf(Location spawnLocation) {
|
||||
LivingEntity callOfWildEntity = (LivingEntity) getPlayer().getWorld().spawnEntity(spawnLocation, EntityType.WOLF);
|
||||
|
||||
//This is used to prevent XP gains for damaging this entity
|
||||
applyMetaDataToCOTWEntity(callOfWildEntity);
|
||||
|
||||
setBaseCOTWEntityProperties(callOfWildEntity);
|
||||
|
||||
addToTracker(callOfWildEntity, CallOfTheWildType.WOLF);
|
||||
|
||||
//Setup wolf stats
|
||||
callOfWildEntity.setMaxHealth(20.0);
|
||||
callOfWildEntity.setHealth(callOfWildEntity.getMaxHealth());
|
||||
|
||||
callOfWildEntity.setCustomName(LocaleLoader.getString("Taming.Summon.Name.Format", getPlayer().getName(), StringUtils.getPrettyEntityTypeString(EntityType.WOLF)));
|
||||
}
|
||||
|
||||
private void spawnCat(Location spawnLocation, EntityType entityType) {
|
||||
LivingEntity callOfWildEntity = (LivingEntity) getPlayer().getWorld().spawnEntity(spawnLocation, entityType);
|
||||
|
||||
//This is used to prevent XP gains for damaging this entity
|
||||
applyMetaDataToCOTWEntity(callOfWildEntity);
|
||||
|
||||
setBaseCOTWEntityProperties(callOfWildEntity);
|
||||
|
||||
addToTracker(callOfWildEntity, CallOfTheWildType.CAT);
|
||||
|
||||
//Randomize the cat
|
||||
if(callOfWildEntity instanceof Ocelot) {
|
||||
int numberOfTypes = Ocelot.Type.values().length;
|
||||
((Ocelot) callOfWildEntity).setCatType(Ocelot.Type.values()[Misc.getRandom().nextInt(numberOfTypes)]);
|
||||
} else if(callOfWildEntity instanceof Cat) {
|
||||
int numberOfTypes = Cat.Type.values().length;
|
||||
((Cat) callOfWildEntity).setCatType(Cat.Type.values()[Misc.getRandom().nextInt(numberOfTypes)]);
|
||||
}
|
||||
|
||||
callOfWildEntity.setCustomName(LocaleLoader.getString("Taming.Summon.Name.Format", getPlayer().getName(), StringUtils.getPrettyEntityTypeString(entityType)));
|
||||
|
||||
//Particle effect
|
||||
ParticleEffectUtils.playCallOfTheWildEffect(callOfWildEntity);
|
||||
}
|
||||
|
||||
private void spawnHorse(Location spawnLocation) {
|
||||
LivingEntity callOfWildEntity = (LivingEntity) getPlayer().getWorld().spawnEntity(spawnLocation, EntityType.HORSE);
|
||||
applyMetaDataToCOTWEntity(callOfWildEntity);
|
||||
|
||||
setBaseCOTWEntityProperties(callOfWildEntity);
|
||||
|
||||
addToTracker(callOfWildEntity, CallOfTheWildType.HORSE);
|
||||
|
||||
//Randomize Horse
|
||||
Horse horse = (Horse) callOfWildEntity;
|
||||
|
||||
callOfWildEntity.setMaxHealth(15.0 + (Misc.getRandom().nextDouble() * 15));
|
||||
callOfWildEntity.setHealth(callOfWildEntity.getMaxHealth());
|
||||
horse.setColor(Horse.Color.values()[Misc.getRandom().nextInt(Horse.Color.values().length)]);
|
||||
horse.setStyle(Horse.Style.values()[Misc.getRandom().nextInt(Horse.Style.values().length)]);
|
||||
horse.setJumpStrength(Math.max(AdvancedConfig.getInstance().getMinHorseJumpStrength(), Math.min(Math.min(Misc.getRandom().nextDouble(), Misc.getRandom().nextDouble()) * 2, AdvancedConfig.getInstance().getMaxHorseJumpStrength())));
|
||||
//TODO: setSpeed, once available
|
||||
|
||||
callOfWildEntity.setCustomName(LocaleLoader.getString("Taming.Summon.Name.Format", getPlayer().getName(), StringUtils.getPrettyEntityTypeString(EntityType.HORSE)));
|
||||
|
||||
//Particle effect
|
||||
ParticleEffectUtils.playCallOfTheWildEffect(callOfWildEntity);
|
||||
}
|
||||
|
||||
private void setBaseCOTWEntityProperties(LivingEntity callOfWildEntity) {
|
||||
((Tameable) callOfWildEntity).setOwner(getPlayer());
|
||||
callOfWildEntity.setRemoveWhenFarAway(false);
|
||||
}
|
||||
|
||||
private void applyMetaDataToCOTWEntity(LivingEntity callOfWildEntity) {
|
||||
//This is used to prevent XP gains for damaging this entity
|
||||
callOfWildEntity.setMetadata(mcMMO.entityMetadataKey, mcMMO.metadataValue);
|
||||
|
||||
//This helps identify the entity as being summoned by COTW
|
||||
callOfWildEntity.setMetadata(mcMMO.COTW_TEMPORARY_SUMMON, mcMMO.metadataValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the Call of the Wild ability.
|
||||
*
|
||||
* @param type The type of entity to summon.
|
||||
* @param summonAmount The amount of material needed to summon the entity
|
||||
* Whether or not the itemstack is used for COTW
|
||||
* @param itemStack target ItemStack
|
||||
* @return true if it is used for any COTW
|
||||
*/
|
||||
private void callOfTheWild(EntityType type, int summonAmount) {
|
||||
Player player = getPlayer();
|
||||
|
||||
ItemStack heldItem = player.getInventory().getItemInMainHand();
|
||||
int heldItemAmount = heldItem.getAmount();
|
||||
Location location = player.getLocation();
|
||||
|
||||
if (heldItemAmount < summonAmount) {
|
||||
int moreAmount = summonAmount - heldItemAmount;
|
||||
NotificationManager.sendPlayerInformation(player, NotificationType.REQUIREMENTS_NOT_MET, "Item.NotEnough", String.valueOf(moreAmount), StringUtils.getPrettyItemString(heldItem.getType()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rangeCheck(type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int amount = Config.getInstance().getTamingCOTWAmount(type);
|
||||
int tamingCOTWLength = Config.getInstance().getTamingCOTWLength(type);
|
||||
|
||||
for (int i = 0; i < amount; i++) {
|
||||
if (!summonAmountCheck(type)) {
|
||||
return;
|
||||
}
|
||||
|
||||
location = Misc.getLocationOffset(location, 1);
|
||||
LivingEntity callOfWildEntity = (LivingEntity) player.getWorld().spawnEntity(location, type);
|
||||
|
||||
FakeEntityTameEvent event = new FakeEntityTameEvent(callOfWildEntity, player);
|
||||
mcMMO.p.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
if (event.isCancelled()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
callOfWildEntity.setMetadata(mcMMO.entityMetadataKey, mcMMO.metadataValue);
|
||||
((Tameable) callOfWildEntity).setOwner(player);
|
||||
callOfWildEntity.setRemoveWhenFarAway(false);
|
||||
|
||||
addToTracker(callOfWildEntity);
|
||||
|
||||
switch (type) {
|
||||
case OCELOT:
|
||||
((Ocelot) callOfWildEntity).setCatType(Ocelot.Type.values()[1 + Misc.getRandom().nextInt(3)]);
|
||||
break;
|
||||
|
||||
case WOLF:
|
||||
callOfWildEntity.setMaxHealth(20.0);
|
||||
callOfWildEntity.setHealth(callOfWildEntity.getMaxHealth());
|
||||
break;
|
||||
|
||||
case HORSE:
|
||||
Horse horse = (Horse) callOfWildEntity;
|
||||
|
||||
callOfWildEntity.setMaxHealth(15.0 + (Misc.getRandom().nextDouble() * 15));
|
||||
callOfWildEntity.setHealth(callOfWildEntity.getMaxHealth());
|
||||
horse.setColor(Horse.Color.values()[Misc.getRandom().nextInt(Horse.Color.values().length)]);
|
||||
horse.setStyle(Horse.Style.values()[Misc.getRandom().nextInt(Horse.Style.values().length)]);
|
||||
horse.setJumpStrength(Math.max(AdvancedConfig.getInstance().getMinHorseJumpStrength(), Math.min(Math.min(Misc.getRandom().nextDouble(), Misc.getRandom().nextDouble()) * 2, AdvancedConfig.getInstance().getMaxHorseJumpStrength())));
|
||||
//TODO: setSpeed, once available
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (Permissions.renamePets(player)) {
|
||||
callOfWildEntity.setCustomName(LocaleLoader.getString("Taming.Summon.Name.Format", player.getName(), StringUtils.getPrettyEntityTypeString(type)));
|
||||
}
|
||||
|
||||
ParticleEffectUtils.playCallOfTheWildEffect(callOfWildEntity);
|
||||
}
|
||||
|
||||
ItemStack leftovers = new ItemStack(heldItem);
|
||||
leftovers.setAmount(heldItemAmount - summonAmount);
|
||||
player.getInventory().setItemInMainHand(heldItemAmount == summonAmount ? null : leftovers);
|
||||
|
||||
String lifeSpan = "";
|
||||
if (tamingCOTWLength > 0) {
|
||||
lifeSpan = LocaleLoader.getString("Taming.Summon.Lifespan", tamingCOTWLength);
|
||||
}
|
||||
|
||||
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE, "Taming.Summon.Complete", lifeSpan);
|
||||
player.playSound(location, Sound.ENTITY_FIREWORK_ROCKET_BLAST_FAR, 1F, 0.5F);
|
||||
public boolean isCOTWItem(ItemStack itemStack) {
|
||||
return summoningItems.containsKey(itemStack.getType());
|
||||
}
|
||||
|
||||
private boolean rangeCheck(EntityType type) {
|
||||
double range = Config.getInstance().getTamingCOTWRange();
|
||||
Player player = getPlayer();
|
||||
//TODO: The way this tracker was written is garbo, I should just rewrite it, I'll save that for a future update
|
||||
private int getAmountCurrentlySummoned(CallOfTheWildType callOfTheWildType) {
|
||||
//The tracker is unreliable so validate its contents first
|
||||
recalibrateTracker();
|
||||
|
||||
if (range == 0) {
|
||||
return true;
|
||||
return playerSummonedEntities.get(callOfTheWildType).size();
|
||||
}
|
||||
|
||||
//TODO: The way this tracker was written is garbo, I should just rewrite it, I'll save that for a future update
|
||||
private void addToTracker(LivingEntity livingEntity, CallOfTheWildType callOfTheWildType) {
|
||||
TrackedTamingEntity trackedEntity = new TrackedTamingEntity(livingEntity, callOfTheWildType, this);
|
||||
|
||||
playerSummonedEntities.get(callOfTheWildType).add(trackedEntity);
|
||||
}
|
||||
|
||||
//TODO: The way this tracker was written is garbo, I should just rewrite it, I'll save that for a future update
|
||||
public List<TrackedTamingEntity> getTrackedEntities(CallOfTheWildType callOfTheWildType) {
|
||||
return playerSummonedEntities.get(callOfTheWildType);
|
||||
}
|
||||
|
||||
//TODO: The way this tracker was written is garbo, I should just rewrite it, I'll save that for a future update
|
||||
public void removeFromTracker(TrackedTamingEntity trackedEntity) {
|
||||
if(playerSummonedEntities.get(trackedEntity.getCallOfTheWildType()).contains(trackedEntity))
|
||||
playerSummonedEntities.get(trackedEntity.getCallOfTheWildType()).remove(trackedEntity);
|
||||
|
||||
NotificationManager.sendPlayerInformationChatOnly(getPlayer(), "Taming.Summon.COTW.TimeExpired", StringUtils.getPrettyEntityTypeString(trackedEntity.getLivingEntity().getType()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds a new tracked list by determining which tracked things are still valid
|
||||
*/
|
||||
//TODO: The way this tracker was written is garbo, I should just rewrite it, I'll save that for a future update
|
||||
private void recalibrateTracker() {
|
||||
for(CallOfTheWildType callOfTheWildType : CallOfTheWildType.values()) {
|
||||
ArrayList<TrackedTamingEntity> validEntities = getValidTrackedEntities(callOfTheWildType);
|
||||
playerSummonedEntities.put(callOfTheWildType, validEntities); //Replace the old list with the new list
|
||||
}
|
||||
}
|
||||
|
||||
for (Entity entity : player.getNearbyEntities(range, range, range)) {
|
||||
if (entity.getType() == type) {
|
||||
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, Taming.getCallOfTheWildFailureMessage(type));
|
||||
return false;
|
||||
//TODO: The way this tracker was written is garbo, I should just rewrite it, I'll save that for a future update
|
||||
private ArrayList<TrackedTamingEntity> getValidTrackedEntities(CallOfTheWildType callOfTheWildType) {
|
||||
ArrayList<TrackedTamingEntity> validTrackedEntities = new ArrayList<>();
|
||||
|
||||
for(TrackedTamingEntity trackedTamingEntity : getTrackedEntities(callOfTheWildType)) {
|
||||
LivingEntity livingEntity = trackedTamingEntity.getLivingEntity();
|
||||
|
||||
//Remove from existence
|
||||
if(livingEntity != null && livingEntity.isValid()) {
|
||||
validTrackedEntities.add(trackedTamingEntity);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return validTrackedEntities;
|
||||
}
|
||||
|
||||
private boolean summonAmountCheck(EntityType entityType) {
|
||||
Player player = getPlayer();
|
||||
/**
|
||||
* Remove all tracked entities from existence if they currently exist
|
||||
* Clear the tracked entity lists afterwards
|
||||
*/
|
||||
//TODO: The way this tracker was written is garbo, I should just rewrite it, I'll save that for a future update
|
||||
public void cleanupAllSummons() {
|
||||
for(List<TrackedTamingEntity> trackedTamingEntities : playerSummonedEntities.values()) {
|
||||
for(TrackedTamingEntity trackedTamingEntity : trackedTamingEntities) {
|
||||
LivingEntity livingEntity = trackedTamingEntity.getLivingEntity();
|
||||
|
||||
int maxAmountSummons = Config.getInstance().getTamingCOTWMaxAmount(entityType);
|
||||
//Remove from existence
|
||||
if(livingEntity != null && livingEntity.isValid()) {
|
||||
livingEntity.remove();
|
||||
}
|
||||
}
|
||||
|
||||
if (maxAmountSummons <= 0) {
|
||||
return true;
|
||||
//Clear the list
|
||||
trackedTamingEntities.clear();
|
||||
}
|
||||
|
||||
List<TrackedTamingEntity> trackedEntities = getTrackedEntities(entityType);
|
||||
int summonAmount = trackedEntities == null ? 0 : trackedEntities.size();
|
||||
|
||||
if (summonAmount >= maxAmountSummons) {
|
||||
NotificationManager.sendPlayerInformation(player, NotificationType.SUBSKILL_MESSAGE_FAILED, "Taming.Summon.Fail.TooMany", String.valueOf(maxAmountSummons));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static void addToTracker(LivingEntity livingEntity) {
|
||||
TrackedTamingEntity trackedEntity = new TrackedTamingEntity(livingEntity);
|
||||
|
||||
if (!summonedEntities.containsKey(livingEntity.getType())) {
|
||||
summonedEntities.put(livingEntity.getType(), new ArrayList<TrackedTamingEntity>());
|
||||
}
|
||||
|
||||
summonedEntities.get(livingEntity.getType()).add(trackedEntity);
|
||||
}
|
||||
|
||||
protected static List<TrackedTamingEntity> getTrackedEntities(EntityType entityType) {
|
||||
return summonedEntities.get(entityType);
|
||||
}
|
||||
|
||||
protected static void removeFromTracker(TrackedTamingEntity trackedEntity) {
|
||||
summonedEntities.get(trackedEntity.getLivingEntity().getType()).remove(trackedEntity);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.gmail.nossr50.skills.taming;
|
||||
|
||||
import com.gmail.nossr50.config.Config;
|
||||
import com.gmail.nossr50.datatypes.skills.subskills.taming.CallOfTheWildType;
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.util.Misc;
|
||||
import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
@ -15,14 +16,18 @@ import java.util.UUID;
|
||||
|
||||
public class TrackedTamingEntity extends BukkitRunnable {
|
||||
private LivingEntity livingEntity;
|
||||
private final CallOfTheWildType callOfTheWildType;
|
||||
private UUID id;
|
||||
private int length;
|
||||
private final TamingManager tamingManagerRef;
|
||||
|
||||
protected TrackedTamingEntity(LivingEntity livingEntity) {
|
||||
protected TrackedTamingEntity(LivingEntity livingEntity, CallOfTheWildType callOfTheWildType, TamingManager tamingManagerRef) {
|
||||
this.tamingManagerRef = tamingManagerRef;
|
||||
this.callOfTheWildType = callOfTheWildType;
|
||||
this.livingEntity = livingEntity;
|
||||
this.id = livingEntity.getUniqueId();
|
||||
|
||||
int tamingCOTWLength = Config.getInstance().getTamingCOTWLength(livingEntity.getType());
|
||||
int tamingCOTWLength = Config.getInstance().getTamingCOTWLength(callOfTheWildType.getConfigEntityTypeEntry());
|
||||
|
||||
if (tamingCOTWLength > 0) {
|
||||
this.length = tamingCOTWLength * Misc.TICK_CONVERSION_FACTOR;
|
||||
@ -36,18 +41,25 @@ public class TrackedTamingEntity extends BukkitRunnable {
|
||||
Location location = livingEntity.getLocation();
|
||||
location.getWorld().playSound(location, Sound.BLOCK_FIRE_EXTINGUISH, 0.8F, 0.8F);
|
||||
ParticleEffectUtils.playCallOfTheWildEffect(livingEntity);
|
||||
CombatUtils.dealDamage(livingEntity, livingEntity.getMaxHealth(), DamageCause.SUICIDE, livingEntity);
|
||||
|
||||
if(tamingManagerRef != null)
|
||||
tamingManagerRef.removeFromTracker(this);
|
||||
|
||||
livingEntity.remove();
|
||||
}
|
||||
|
||||
TamingManager.removeFromTracker(this);
|
||||
this.cancel();
|
||||
}
|
||||
|
||||
protected LivingEntity getLivingEntity() {
|
||||
public CallOfTheWildType getCallOfTheWildType() {
|
||||
return callOfTheWildType;
|
||||
}
|
||||
|
||||
public LivingEntity getLivingEntity() {
|
||||
return livingEntity;
|
||||
}
|
||||
|
||||
protected UUID getID() {
|
||||
public UUID getID() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +192,6 @@ public final class Permissions {
|
||||
|
||||
/* TAMING */
|
||||
public static boolean callOfTheWild(Permissible permissible, EntityType type) { return permissible.hasPermission("mcmmo.ability.taming.callofthewild." + type.toString().toLowerCase()); }
|
||||
public static boolean renamePets(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.taming.callofthewild.renamepets"); }
|
||||
|
||||
/* UNARMED */
|
||||
public static boolean berserk(Permissible permissible) { return permissible.hasPermission("mcmmo.ability.unarmed.berserk"); }
|
||||
|
@ -46,8 +46,9 @@ public final class UserManager {
|
||||
McMMOPlayer mcMMOPlayer = getPlayer(player);
|
||||
player.removeMetadata(mcMMO.playerDataKey, mcMMO.p);
|
||||
|
||||
if(playerDataSet != null && playerDataSet.contains(mcMMOPlayer))
|
||||
if(playerDataSet != null && playerDataSet.contains(mcMMOPlayer)) {
|
||||
playerDataSet.remove(mcMMOPlayer); //Clear sync save tracking
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -391,23 +391,19 @@ Skills:
|
||||
Item_Amount: 10
|
||||
Summon_Amount: 1
|
||||
Summon_Length: 240
|
||||
Summon_Max_Amount: 10
|
||||
Per_Player_Limit: 2
|
||||
Ocelot:
|
||||
Item_Material: COD
|
||||
Item_Amount: 10
|
||||
Summon_Amount: 1
|
||||
Summon_Length: 240
|
||||
Summon_Max_Amount: 10
|
||||
Per_Player_Limit: 1
|
||||
Horse:
|
||||
Item_Material: APPLE
|
||||
Item_Amount: 10
|
||||
Summon_Amount: 1
|
||||
Summon_Length: 240
|
||||
Summon_Max_Amount: 10
|
||||
|
||||
# Range to check for nearby pets when using Call Of The Wild, 0 will disable the check
|
||||
Range: 40.0
|
||||
|
||||
Per_Player_Limit: 1
|
||||
Unarmed:
|
||||
Enabled_For_PVP: true
|
||||
Enabled_For_PVE: true
|
||||
|
@ -25,6 +25,7 @@
|
||||
EarlyGameBoost:
|
||||
Enabled: true
|
||||
ExploitFix:
|
||||
COTWBreeding: true
|
||||
UnsafeEnchantments: false
|
||||
# Prevent many exploits related to fishing
|
||||
Fishing: true
|
||||
|
@ -481,12 +481,13 @@ Taming.Listener.Wolf=[[DARK_GRAY]]Your wolf scurries back to you...
|
||||
Taming.Listener=Taming:
|
||||
Taming.SkillName=TAMING
|
||||
Taming.Summon.Complete=[[GREEN]]Summoning complete
|
||||
Taming.Summon.COTW.Success=[[GREEN]](Call Of The Wild) [[GRAY]]You have summoned a [[GOLD]]{0}[[GRAY]] and it has a duration of [[GOLD]]{1}[[GRAY]] seconds.
|
||||
Taming.Summon.Lifespan= (Lifespan: {0}s)
|
||||
Taming.Summon.Fail.Ocelot=[[RED]]You have too many ocelots nearby to summon any more.
|
||||
Taming.Summon.Fail.Wolf=[[RED]]You have too many wolves nearby to summon any more.
|
||||
Taming.Summon.Fail.Horse=[[RED]]You have too many horses nearby to summon any more.
|
||||
Taming.Summon.Fail.TooMany=[[RED]]You have reached the maximum limit of pets to summon. [[YELLOW]]({0})
|
||||
Taming.Summon.Name.Format={0}'s {1}
|
||||
Taming.Summon.COTW.Limit=[[RED]]You can only summon up to {0} for this type of animal. Try again later.
|
||||
Taming.Summon.COTW.TimeExpired=[[GREEN]](Call Of The Wild) [[GRAY]]Time is up, your temporary summon [[GOLD]]{0}[[GRAY]] departs.
|
||||
Taming.Summon.COTW.BreedingDisallowed=[[GREEN]](Call Of The Wild) [[RED]]You cannot breed a summoned animal.
|
||||
Taming.Summon.Name.Format=[[GOLD]](COTW) [[WHITE]]{0}'s {1}
|
||||
#UNARMED
|
||||
Unarmed.Ability.Bonus.0=Iron Arm Style
|
||||
Unarmed.Ability.Bonus.1=+{0} DMG Upgrade
|
||||
|
Loading…
Reference in New Issue
Block a user