Combat.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. package com.gmail.nossr50.util;
  2. import org.bukkit.Material;
  3. import org.bukkit.enchantments.Enchantment;
  4. import org.bukkit.entity.AnimalTamer;
  5. import org.bukkit.entity.Animals;
  6. import org.bukkit.entity.Arrow;
  7. import org.bukkit.entity.Entity;
  8. import org.bukkit.entity.EntityType;
  9. import org.bukkit.entity.IronGolem;
  10. import org.bukkit.entity.LivingEntity;
  11. import org.bukkit.entity.Player;
  12. import org.bukkit.entity.Tameable;
  13. import org.bukkit.entity.Wolf;
  14. import org.bukkit.event.entity.EntityDamageByEntityEvent;
  15. import org.bukkit.event.entity.EntityDamageEvent;
  16. import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
  17. import org.bukkit.event.player.PlayerAnimationEvent;
  18. import org.bukkit.inventory.ItemStack;
  19. import com.gmail.nossr50.mcMMO;
  20. import com.gmail.nossr50.config.Config;
  21. import com.gmail.nossr50.datatypes.AbilityType;
  22. import com.gmail.nossr50.datatypes.PlayerProfile;
  23. import com.gmail.nossr50.datatypes.SkillType;
  24. import com.gmail.nossr50.datatypes.ToolType;
  25. import com.gmail.nossr50.events.fake.FakeEntityDamageByEntityEvent;
  26. import com.gmail.nossr50.events.fake.FakeEntityDamageEvent;
  27. import com.gmail.nossr50.locale.LocaleLoader;
  28. import com.gmail.nossr50.party.PartyManager;
  29. import com.gmail.nossr50.runnables.BleedTimer;
  30. import com.gmail.nossr50.runnables.GainXp;
  31. import com.gmail.nossr50.skills.acrobatics.AcrobaticsManager;
  32. import com.gmail.nossr50.skills.archery.ArcheryManager;
  33. import com.gmail.nossr50.skills.combat.Axes;
  34. import com.gmail.nossr50.skills.combat.Swords;
  35. import com.gmail.nossr50.skills.combat.Unarmed;
  36. import com.gmail.nossr50.skills.taming.TamingManager;
  37. import com.gmail.nossr50.skills.unarmed.UnarmedManager;
  38. public class Combat {
  39. private static Config configInstance = Config.getInstance();
  40. private static Permissions permInstance = Permissions.getInstance();
  41. /**
  42. * Apply combat modifiers and process and XP gain.
  43. *
  44. * @param event The event to run the combat checks on.
  45. */
  46. public static void combatChecks(EntityDamageByEntityEvent event) {
  47. if (event.getDamage() == 0 || event.getEntity().isDead()) {
  48. return;
  49. }
  50. Entity damager = event.getDamager();
  51. LivingEntity target = (LivingEntity) event.getEntity();
  52. boolean targetIsPlayer = target instanceof Player;
  53. boolean targetIsTamedPet = (target instanceof Tameable) ? ((Tameable) target).isTamed() : false;
  54. if (damager instanceof Player) {
  55. Player attacker = (Player) event.getDamager();
  56. ItemStack itemInHand = attacker.getItemInHand();
  57. PlayerProfile PPa = Users.getProfile(attacker);
  58. combatAbilityChecks(attacker);
  59. if (ItemChecks.isSword(itemInHand) && permInstance.swords(attacker)) {
  60. if (!configInstance.getSwordsPVP()) {
  61. if (targetIsPlayer || targetIsTamedPet) {
  62. return;
  63. }
  64. }
  65. if (!configInstance.getSwordsPVE()) {
  66. if (!targetIsPlayer || !targetIsTamedPet) {
  67. return;
  68. }
  69. }
  70. if (permInstance.swordsBleed(attacker)) {
  71. Swords.bleedCheck(attacker, target);
  72. }
  73. if (PPa.getAbilityMode(AbilityType.SERRATED_STRIKES) && permInstance.serratedStrikes(attacker)) {
  74. applyAbilityAoE(attacker, target, event.getDamage() / 4, SkillType.SWORDS);
  75. BleedTimer.add(target, 5);
  76. }
  77. startGainXp(attacker, PPa, target, SkillType.SWORDS);
  78. }
  79. else if (ItemChecks.isAxe(itemInHand) && permInstance.axes(attacker)) {
  80. if (!configInstance.getAxesPVP()) {
  81. if (targetIsPlayer || targetIsTamedPet) {
  82. return;
  83. }
  84. }
  85. if (!configInstance.getAxesPVE()) {
  86. if (!targetIsPlayer || !targetIsTamedPet) {
  87. return;
  88. }
  89. }
  90. if (permInstance.axeBonus(attacker)) {
  91. Axes.axesBonus(attacker, event);
  92. }
  93. if (permInstance.criticalHit(attacker)) {
  94. Axes.axeCriticalCheck(attacker, event);
  95. }
  96. if (permInstance.impact(attacker)) {
  97. Axes.impact(attacker, target, event);
  98. }
  99. if (PPa.getAbilityMode(AbilityType.SKULL_SPLIITER) && permInstance.skullSplitter(attacker)) {
  100. applyAbilityAoE(attacker, target, event.getDamage() / 2, SkillType.AXES);
  101. }
  102. startGainXp(attacker, PPa, target, SkillType.AXES);
  103. }
  104. else if (itemInHand.getType().equals(Material.AIR) && permInstance.unarmed(attacker)) {
  105. if (!configInstance.getUnarmedPVP()) {
  106. if (targetIsPlayer || targetIsTamedPet) {
  107. return;
  108. }
  109. }
  110. if (!configInstance.getUnarmedPVE()) {
  111. if (!targetIsPlayer || !targetIsTamedPet) {
  112. return;
  113. }
  114. }
  115. UnarmedManager unarmedManager = new UnarmedManager(attacker);
  116. if (permInstance.unarmedBonus(attacker)) {
  117. Unarmed.unarmedBonus(PPa, event);
  118. }
  119. if (PPa.getAbilityMode(AbilityType.BERSERK) && permInstance.berserk(attacker)) {
  120. event.setDamage((int) (event.getDamage() * 1.5));
  121. }
  122. if (targetIsPlayer) {
  123. unarmedManager.disarmCheck((Player) target);
  124. }
  125. startGainXp(attacker, PPa, target, SkillType.UNARMED);
  126. }
  127. else if (itemInHand.getType() == Material.BONE && target instanceof Tameable) {
  128. TamingManager tamingManager = new TamingManager(attacker);
  129. tamingManager.beastLore(target);
  130. event.setCancelled(true);
  131. }
  132. }
  133. else if (damager instanceof Wolf) {
  134. Wolf wolf = (Wolf) damager;
  135. if (wolf.isTamed() && wolf.getOwner() instanceof Player) {
  136. Player master = (Player) wolf.getOwner();
  137. if (!configInstance.getTamingPVP()) {
  138. if (targetIsPlayer || targetIsTamedPet) {
  139. return;
  140. }
  141. }
  142. if (!configInstance.getTamingPVE()) {
  143. if (!targetIsPlayer || !targetIsTamedPet) {
  144. return;
  145. }
  146. }
  147. TamingManager tamingManager = new TamingManager(master);
  148. tamingManager.fastFoodService(wolf, event.getDamage());
  149. tamingManager.sharpenedClaws(event);
  150. tamingManager.gore(event);
  151. startGainXp(master, Users.getProfile(master), target, SkillType.TAMING);
  152. }
  153. }
  154. else if (damager instanceof Arrow) {
  155. LivingEntity shooter = ((Arrow) damager).getShooter();
  156. if (shooter.getType() != EntityType.PLAYER) {
  157. return;
  158. }
  159. if (targetIsPlayer || targetIsTamedPet) {
  160. if (!configInstance.getArcheryPVP()) {
  161. return;
  162. }
  163. }
  164. else if (!configInstance.getArcheryPVE()) {
  165. return;
  166. }
  167. archeryCheck((Player) shooter, target, event);
  168. }
  169. if (target instanceof Player) {
  170. AcrobaticsManager acroManager = new AcrobaticsManager((Player) target);
  171. if (configInstance.getSwordsPVP() && damager instanceof Player) {
  172. Swords.counterAttackChecks(damager, (Player) target, event.getDamage());
  173. }
  174. if (configInstance.getSwordsPVE() && !(damager instanceof Player)) {
  175. Swords.counterAttackChecks(damager, (Player) target, event.getDamage());
  176. }
  177. if (configInstance.getAcrobaticsPVP() && damager instanceof Player) {
  178. acroManager.dodgeCheck(event);
  179. }
  180. if (configInstance.getAcrobaticsPVE() && !(damager instanceof Player)) {
  181. acroManager.dodgeCheck(event);
  182. }
  183. }
  184. }
  185. /**
  186. * Process combat abilities based on weapon preparation modes.
  187. *
  188. * @param attacker The player attacking
  189. */
  190. public static void combatAbilityChecks(Player attacker) {
  191. PlayerProfile PPa = Users.getProfile(attacker);
  192. if (PPa.getToolPreparationMode(ToolType.AXE)) {
  193. Skills.abilityCheck(attacker, SkillType.AXES);
  194. }
  195. else if (PPa.getToolPreparationMode(ToolType.SWORD)) {
  196. Skills.abilityCheck(attacker, SkillType.SWORDS);
  197. }
  198. else if (PPa.getToolPreparationMode(ToolType.FISTS)) {
  199. Skills.abilityCheck(attacker, SkillType.UNARMED);
  200. }
  201. }
  202. /**
  203. * Process archery abilities.
  204. *
  205. * @param shooter The player shooting
  206. * @param target The defending entity
  207. * @param event The event to run the archery checks on.
  208. */
  209. public static void archeryCheck(Player shooter, LivingEntity target, EntityDamageByEntityEvent event) {
  210. if (target instanceof Player) {
  211. Player defender = (Player) target;
  212. if (defender.getItemInHand().getType().equals(Material.AIR)) {
  213. if (configInstance.getUnarmedPVP()) {
  214. Unarmed.deflectCheck(defender, event);
  215. }
  216. }
  217. }
  218. ArcheryManager archeryManager = new ArcheryManager(shooter);
  219. archeryManager.bonusDamage(event);
  220. if (target instanceof Player) {
  221. archeryManager.dazeCheck((Player) target, event);
  222. }
  223. if (!(shooter.getItemInHand().containsEnchantment(Enchantment.ARROW_INFINITE))) {
  224. archeryManager.trackArrows(target);
  225. }
  226. if (target != shooter) {
  227. PlayerProfile PP = Users.getProfile(shooter);
  228. startGainXp(shooter, PP, target, SkillType.ARCHERY);
  229. }
  230. }
  231. /**
  232. * Attempt to damage target for value dmg with reason CUSTOM
  233. *
  234. * @param target LivingEntity which to attempt to damage
  235. * @param dmg Amount of damage to attempt to do
  236. */
  237. public static void dealDamage(LivingEntity target, int dmg) {
  238. dealDamage(target, dmg, EntityDamageEvent.DamageCause.CUSTOM);
  239. }
  240. /**
  241. * Attempt to damage target for value dmg with reason cause
  242. *
  243. * @param target LivingEntity which to attempt to damage
  244. * @param dmg Amount of damage to attempt to do
  245. * @param cause DamageCause to pass to damage event
  246. */
  247. private static void dealDamage(LivingEntity target, int dmg, DamageCause cause) {
  248. if (configInstance.getEventCallbackEnabled()) {
  249. EntityDamageEvent ede = new FakeEntityDamageEvent(target, cause, dmg);
  250. mcMMO.p.getServer().getPluginManager().callEvent(ede);
  251. if (ede.isCancelled()) {
  252. return;
  253. }
  254. target.damage(ede.getDamage());
  255. }
  256. else {
  257. target.damage(dmg);
  258. }
  259. }
  260. /**
  261. * Attempt to damage target for value dmg with reason ENTITY_ATTACK with damager attacker
  262. *
  263. * @param target LivingEntity which to attempt to damage
  264. * @param dmg Amount of damage to attempt to do
  265. * @param attacker Player to pass to event as damager
  266. */
  267. private static void dealDamage(LivingEntity target, int dmg, Player attacker) {
  268. if (configInstance.getEventCallbackEnabled()) {
  269. EntityDamageEvent ede = new FakeEntityDamageByEntityEvent(attacker, target, EntityDamageEvent.DamageCause.ENTITY_ATTACK, dmg);
  270. mcMMO.p.getServer().getPluginManager().callEvent(ede);
  271. if (ede.isCancelled()) {
  272. return;
  273. }
  274. target.damage(ede.getDamage());
  275. }
  276. else {
  277. target.damage(dmg);
  278. }
  279. }
  280. /**
  281. * Apply Area-of-Effect ability actions.
  282. *
  283. * @param attacker The attacking player
  284. * @param target The defending entity
  285. * @param damage The initial damage amount
  286. * @param type The type of skill being used
  287. */
  288. private static void applyAbilityAoE(Player attacker, LivingEntity target, int damage, SkillType type) {
  289. ItemStack inHand = attacker.getItemInHand();
  290. if (ModChecks.isCustomTool(inHand) && !ModChecks.getToolFromItemStack(inHand).isAbilityEnabled()) {
  291. return;
  292. }
  293. int numberOfTargets = Misc.getTier(attacker.getItemInHand()); //The higher the weapon tier, the more targets you hit
  294. int damageAmount = damage;
  295. if (damageAmount < 1) {
  296. damageAmount = 1;
  297. }
  298. for (Entity entity : target.getNearbyEntities(2.5, 2.5, 2.5)) {
  299. if (!(entity instanceof LivingEntity)) {
  300. continue;
  301. }
  302. if (numberOfTargets <= 0) {
  303. break;
  304. }
  305. PlayerAnimationEvent armswing = new PlayerAnimationEvent(attacker);
  306. mcMMO.p.getServer().getPluginManager().callEvent(armswing);
  307. if (entity instanceof Player) {
  308. Player defender = (Player) entity;
  309. if (!target.getWorld().getPVP()) {
  310. continue;
  311. }
  312. if (defender.getName().equals(attacker.getName())) {
  313. continue;
  314. }
  315. if (PartyManager.getInstance().inSameParty(attacker, defender)) {
  316. continue;
  317. }
  318. PlayerProfile playerProfile = Users.getProfile((Player) entity);
  319. if (playerProfile.getGodMode()) {
  320. continue;
  321. }
  322. }
  323. else if (entity instanceof Tameable) {
  324. AnimalTamer tamer = ((Tameable) entity).getOwner();
  325. if (tamer instanceof Player) {
  326. if (tamer.equals(attacker) || PartyManager.getInstance().inSameParty(attacker, (Player) tamer)) {
  327. continue;
  328. }
  329. }
  330. }
  331. switch (type) {
  332. case SWORDS:
  333. if (entity instanceof Player) {
  334. ((Player) entity).sendMessage(LocaleLoader.getString("Swords.Combat.SS.Struck"));
  335. }
  336. BleedTimer.add((LivingEntity) entity, 5);
  337. break;
  338. case AXES:
  339. if (entity instanceof Player) {
  340. ((Player) entity).sendMessage(LocaleLoader.getString("Axes.Combat.Cleave.Struck"));
  341. }
  342. break;
  343. default:
  344. break;
  345. }
  346. dealDamage((LivingEntity) entity, damageAmount, attacker);
  347. numberOfTargets--;
  348. }
  349. }
  350. /**
  351. * Start the task that gives combat XP.
  352. *
  353. * @param attacker The attacking player
  354. * @param PP The player's PlayerProfile
  355. * @param target The defending entity
  356. * @param skillType The skill being used
  357. */
  358. public static void startGainXp(Player attacker, PlayerProfile PP, LivingEntity target, SkillType skillType) {
  359. double baseXP = 0;
  360. if (target instanceof Player) {
  361. if (!configInstance.getExperienceGainsPlayerVersusPlayerEnabled()) {
  362. return;
  363. }
  364. Player defender = (Player) target;
  365. if (System.currentTimeMillis() >= Users.getProfile(defender).getRespawnATS() + 5) {
  366. baseXP = 20 * configInstance.getPlayerVersusPlayerXP();
  367. }
  368. }
  369. else if (!target.hasMetadata("mcmmoFromMobSpawner")) {
  370. if (target instanceof Animals && !target.hasMetadata("mcmmoSummoned")) {
  371. baseXP = configInstance.getAnimalsXP();
  372. }
  373. else {
  374. EntityType type = target.getType();
  375. switch (type) {
  376. case BLAZE:
  377. baseXP = configInstance.getBlazeXP();
  378. break;
  379. case CAVE_SPIDER:
  380. baseXP = configInstance.getCaveSpiderXP();
  381. break;
  382. case CREEPER:
  383. baseXP = configInstance.getCreeperXP();
  384. break;
  385. case ENDER_DRAGON:
  386. baseXP = configInstance.getEnderDragonXP();
  387. break;
  388. case ENDERMAN:
  389. baseXP = configInstance.getEndermanXP();
  390. break;
  391. case GHAST:
  392. baseXP = configInstance.getGhastXP();
  393. break;
  394. case MAGMA_CUBE:
  395. baseXP = configInstance.getMagmaCubeXP();
  396. break;
  397. case IRON_GOLEM:
  398. if (!((IronGolem) target).isPlayerCreated()) {
  399. baseXP = configInstance.getIronGolemXP();
  400. }
  401. break;
  402. case PIG_ZOMBIE:
  403. baseXP = configInstance.getPigZombieXP();
  404. break;
  405. case SILVERFISH:
  406. baseXP = configInstance.getSilverfishXP();
  407. break;
  408. case SKELETON:
  409. baseXP = configInstance.getSkeletonXP();
  410. break;
  411. case SLIME:
  412. baseXP = configInstance.getSlimeXP();
  413. break;
  414. case SPIDER:
  415. baseXP = configInstance.getSpiderXP();
  416. break;
  417. case ZOMBIE:
  418. baseXP = configInstance.getZombieXP();
  419. break;
  420. default:
  421. break;
  422. }
  423. }
  424. baseXP *= 10;
  425. }
  426. if (baseXP != 0) {
  427. mcMMO.p.getServer().getScheduler().scheduleSyncDelayedTask(mcMMO.p, new GainXp(attacker, PP, skillType, baseXP, target), 0);
  428. }
  429. }
  430. }