· 8 years ago · Jun 10, 2018, 08:32 PM
1package com.blueskullgames.horserpg;
2
3import java.io.File;
4import java.sql.Connection;
5import java.sql.DriverManager;
6import java.sql.ResultSet;
7import java.sql.Statement;
8import java.util.*;
9import java.util.Map.Entry;
10
11import net.milkbowl.vault.economy.Economy;
12import net.milkbowl.vault.economy.EconomyResponse;
13
14import org.bukkit.Bukkit;
15import org.bukkit.ChatColor;
16import org.bukkit.Material;
17import org.bukkit.command.Command;
18import org.bukkit.command.CommandSender;
19import org.bukkit.configuration.file.FileConfiguration;
20import org.bukkit.entity.Damageable;
21import org.bukkit.entity.Entity;
22import org.bukkit.entity.Horse;
23import org.bukkit.entity.Horse.*;
24import org.bukkit.entity.Player;
25import org.bukkit.entity.Tameable;
26import org.bukkit.event.HandlerList;
27import org.bukkit.plugin.*;
28import org.bukkit.plugin.java.JavaPlugin;
29import org.bukkit.scheduler.BukkitRunnable;
30import org.bukkit.scheduler.BukkitTask;
31import org.bukkit.scoreboard.*;
32
33import com.blueskullgames.horserpg.configs.HorseConfigHandler;
34import com.blueskullgames.horserpg.configs.MessagesConfigHandler;
35import com.blueskullgames.horserpg.configs.HorseConfigHandler.Keys;
36import com.blueskullgames.horserpg.listeners.*;
37import com.blueskullgames.horserpg.tasks.*;
38import com.blueskullgames.horserpg.utils.*;
39
40@SuppressWarnings("deprecation")
41public class HorseRPG extends JavaPlugin {
42
43 public static final String H_HELP = "mcmmohorses.help";
44 public static final String H_ME = "mcmmohorses.me";
45 public static final String H_STATS = "mcmmohorses.stats";
46 public static final String H_SKILL = "mcmmohorses.skills.info";
47 public static final String H_CLAIM = "mcmmohorses.claim";
48 public static final String H_BUY = "mcmmohorses.buy";
49 public static final String H_SELL = "mcmmohorses.sell";
50 public static final String H_SHOP = "mcmmohorses.shop";
51 public static final String H_SUMMON = "mcmmohorses.summon";
52 public static final String H_BANISH = "mcmmohorses.banish";
53 public static final String H_DELETE = "mcmmohorses.kill";
54 public static final String H_PROTECT = "mcmmohorses.admin.protect";
55 public static final String H_UNPROTECT = "mcmmohorses.admin.unprotect";
56 public static final String H_ADDXP = "mcmmohorses.admin.addxp";
57 public static final String H_DELXP = "mcmmohorses.admin.delxp";
58 public static final String H_SET = "mcmmohorses.admin.set";
59 public static final String H_SET_NAME = "mcmmohorses.admin.set.name";
60 public static final String H_SET_COLOR = "mcmmohorses.admin.set.color";
61 public static final String H_SET_STYLE = "mcmmohorses.admin.set.style";
62 public static final String H_SET_TYPE = "mcmmohorses.admin.set.type";
63 public static final String H_CREATE = "mcmmohorses.admin.breed";
64 public static final String H_SAVE = "mcmmohorses.admin.save";
65 public static final String H_DB = "mcmmohorses.admin.db";
66 public static final String H_RELOAD = "mcmmohorses.admin.reload";
67 public static final String H_LEADERBOARD = "mcmmohorses.leaderboard";
68 public static final String H_BREED = "mcmmohorses.breed";
69
70 public static String BANISH_HORSE = "&aPlease banish your current horse first.";
71 public static String HORSE_BRED = "&aHorse successfully bred!";
72 public static String HORSES_SAVED = "&aAll horses saved to database.";
73 public static String INVALID_COLOR = "&aPlease specify a valid horse color.";
74 public static String INVALID_COMMAND = "&aInvalid command.";
75 public static String INVALID_NAME = "&aPlease specify a horse name.";
76 public static String INVALID_PAGE = "&aInvalid page number.";
77 public static String INVALID_STYLE = "&aPlease specify a valid horse style.";
78 public static String INVALID_VARIANT = "&aPlease specify a valid horse variant.";
79 public static String MAX_HORSES = "&aYou already claimed the max number of horses!";
80 public static String NO_ECONOMY = "&aEconomy features are disabled!";
81 public static String NO_HORSES = "&aYou don't have a horse yet!";
82 public static String NO_MORE_HORSES = "&aYou don't have any more horses!";
83 public static String NO_HORSE_SUMMONED = "&aYou don't have a horse summoned!";
84 public static String NO_PERMISSION = "&aYou are not allowed to use this command!";
85 public static String PAGE_DOES_NOT_EXIST = "&aPage does not exist.";
86 public static String PLAYER_ONLY = "&aThis command can only be run by a &bplayer.";
87
88 public static String NO_WILD_HORSES = "&aYou cannot interact with wild horses.";
89 public static String NO_BREED_HORSES = "&aYou cannot breed these two horses: ";
90 public static String ALLOW_BREEDING = "&aYou have set breeding for %0% to %1% ";
91
92 public static String NOT_ENOUGH_MONEY = "&aYou do not have enough money to buy this horse!";
93 public static String BOUGHT_HORSE = "&aYou have just bought the horse ";
94 public static String BOUGHT_HORSE_EXP1 = "&aTo summon your new horse, use the command /h summon <Your Horse>";
95
96
97
98 //new messages
99 public static String HORSE_NEEDS_TAME = "&aThis horse needs to tamed and saddled first!";
100 public static String PURCHASED_FOR_CLAIM = "&aHorse purchased for &e%amount%";
101 public static String NEXT_HORSE_COST = "&aNext horse costs: &e";
102 public static String CLAIM_NAME = "&b %name% &a claimed!";
103 public static String SKILL_INCREASED_BY = "&e %name% skill increased by %difference%. Total (%level%)" ;
104 public static String NOTENOUGHMONEY="&aYou don't have enough money!";
105 public static String NEED_TIME_TO_RECHARGE="&e%name%&c needs some time to recharge.";
106 public static String SKILL_REFRESH = "&a**Your &e%ability%&a is refreshed*";
107
108 public static String BANISH_LOADED_CHUNK = "&a The chunk your horse is in must be loaded before bansishement!";
109
110
111
112
113
114 public static BukkitTask saveTask, cooldownTask;
115 public static ConfigAccessor config;
116 public static Economy econ;
117 public static HashMap<Entity, RPGHorse> hSpawnedHorses;
118 public static HashMap<Player, RPGHorse> pCurrentHorse;
119 public static HashMap<Player, RPGHorse> offers;
120 public static HashMap<String, TreeSet<RPGHorse>> ownedHorses;
121 public static HashSet<RPGHorse> horses;
122 public static HorseRPG instance;
123 public static LinkedHashMap<String, String> help;
124 public static LinkedHashMap<String, String> setHelp;
125
126 public static MessagesConfigHandler messages;
127
128 public static HorseConfigHandler h_config;
129 public static List<String> playersWithScoreboards = new ArrayList<>();
130 public static boolean nobanishment = false;
131 public static boolean banishondisable = true;
132 public static boolean banishonquit = true;
133 public static boolean disableBreeding = false;
134
135 public static boolean freeHorse;
136 public static boolean permanentDeath;
137 public static int deathTimer;
138 public static int banishTimer;
139 public static int sprintCooldown;
140 public static int infuriateCooldown;
141
142 public static HashMap<String, Integer> groups;
143
144 public static boolean useEconomy;
145 public static int claimCost;
146 public static int claimCostMultiplier;
147 public static int summonCost;
148 public static int banishCost;
149
150 public static boolean forceClaimOnTaim = false;
151
152 public static HashMap<Variant, Double> costForHorse = new HashMap<>();
153 public static ShopManager shop;// = new ShopManager();
154
155 /**
156 * Messages a sender
157 *
158 * @param sender
159 * is the sender to message
160 * @param message
161 * is the message to send
162 */
163 public static void msg(CommandSender sender, String message, String... args) {
164 String tempmess = message;
165 for (int i = 0; i < args.length; i++) {
166 tempmess = tempmess.replaceAll("%" + i + "%", args[i]);
167 }
168 sender.sendMessage(ChatColor.translateAlternateColorCodes('&', tempmess));
169 }
170
171 /**
172 * Checks if the sender can execute the command
173 *
174 * @param sender
175 * is the sender to check
176 * @param permission
177 * is the permission node required
178 * @param playerOnly
179 * is true if the command is player only
180 * @return true if the sender is not allowed to execute the command
181 */
182 public static boolean notAllowed(CommandSender sender, String permission, boolean playerOnly) {
183 if (!sender.hasPermission(permission)) {
184 msg(sender, NO_PERMISSION);
185 return true;
186 }
187 if (playerOnly && !(sender instanceof Player)) {
188 msg(sender, PLAYER_ONLY);
189 return true;
190 }
191 return false;
192 }
193
194 /**
195 * Returns the sender's horse THAT IS NOT CURRENTLY SPAWNED
196 *
197 * @param p
198 * @param args
199 * @param offset
200 * @return
201 */
202 public static RPGHorse getHorseNotSpawned(Player p, String[] args, int offset) {
203 if (args.length <= offset) {
204 if (ownedHorses.containsKey(p.getName()) && ownedHorses.get(p.getName()).size() > 0) {
205 for (RPGHorse h : ownedHorses.get(p.getName())) {
206 if (!hSpawnedHorses.containsKey(h.horse)) {
207 return h;
208 }
209 }
210 }
211 return null;
212 }
213
214 String hName = args[offset];
215 for (int i = offset + 1; i < args.length; i++)
216 hName += " " + args[i];
217 hName = hName.replaceAll("_", " ");
218
219 if (ownedHorses.containsKey(p.getName()))
220 for (RPGHorse h : ownedHorses.get(p.getName()))
221 if (h.name.equalsIgnoreCase(hName))
222 return h;
223
224 msg(p, "&b" + hName + "&a does not exist.");
225 return null;
226 }
227
228 /**
229 * Returns the sender's associated horse
230 *
231 * @param p
232 * is the command sender
233 * @param args
234 * are the command arguments
235 * @param offset
236 * is the argument index offset of the horse name
237 */
238 public static RPGHorse currentHorse(Player p, String[] args, int offset) {
239 if (args.length <= offset) {
240 if (pCurrentHorse.containsKey(p)) {
241 return pCurrentHorse.get(p);
242 } else if (ownedHorses.containsKey(p.getName()) && ownedHorses.get(p.getName()).size() > 0)
243 return ownedHorses.get(p.getName()).first();
244
245 return null;
246 }
247
248 String hName = args[offset];
249 for (int i = offset + 1; i < args.length; i++)
250 hName += " " + args[i];
251 hName = hName.replaceAll("_", " ");
252 if (ownedHorses.containsKey(p.getName()))
253 for (RPGHorse h : ownedHorses.get(p.getName()))
254 if (h.name.equalsIgnoreCase(hName))
255 return h;
256
257 msg(p, "&b" + hName + "&a does not exist.");
258 return null;
259 }
260
261 /**
262 * Gets the max horses a sender can own
263 *
264 * @param sender
265 * is the sender to check
266 * @return the max horses the sender can own
267 */
268 public static int maxHorses(CommandSender sender) {
269 int max = 0;
270 for (Entry<String, Integer> group : groups.entrySet()) {
271 if (sender.hasPermission(group.getKey())) {
272 if (group.getValue() == -1)
273 return -1;
274 max = group.getValue();
275 }
276 }
277 return max;
278 }
279
280 /**
281 * Displays the help message
282 *
283 * @param sender
284 * is the sender to message
285 * @param args
286 * are the command arguments
287 */
288 public static void showHelp(CommandSender sender, String[] args) {
289 if (notAllowed(sender, H_HELP, false))
290 return;
291 int page = 1;
292 if (args.length >= 2) {
293 try {
294 page = Integer.parseInt(args[1]);
295 } catch (NumberFormatException ex) {
296 msg(sender, INVALID_PAGE);
297 return;
298 }
299 }
300 ArrayList<String> customHelp = new ArrayList<String>();
301 for (Entry<String, String> entry : help.entrySet())
302 if (sender.hasPermission(entry.getKey()))
303 customHelp.add(entry.getValue());
304
305 int maxPages = customHelp.size() / 8 + (customHelp.size() % 8 > 0 ? 1 : 0);
306 if (page <= 0 || maxPages < page) {
307 msg(sender, PAGE_DOES_NOT_EXIST);
308 return;
309 }
310
311 page *= 8;
312 for (int i = page - 8; i < page; i++) {
313 if (i % 8 == 0) {
314 sender.sendMessage("");
315 msg(sender, "&aHelp Page " + (page / 8) + ":");
316 }
317 if (i < customHelp.size())
318 msg(sender, customHelp.get(i));
319 }
320 }
321
322 /**
323 * Displays the player's stats
324 *
325 * @param sender
326 * is the sender to message
327 */
328 public static void showMe(CommandSender sender) {
329 if (notAllowed(sender, H_ME, true))
330 return;
331 Player p = (Player) sender;
332
333 TreeSet<RPGHorse> myHorses = ownedHorses.get(p.getName());
334 if (myHorses == null || myHorses.size() <= 0) {
335 msg(sender, NO_HORSES);
336 return;
337 }
338
339 String horseNames = myHorses.toString();
340 msg(sender, "&aOwned: &7" + myHorses.size() + " / " + (maxHorses(p) == -1 ? "Unlimited" : maxHorses(p)));
341 msg(sender, "&aHorses:&7 " + horseNames.substring(1, horseNames.length() - 1));
342 }
343
344 /**
345 * Displays the player's horse stats
346 *
347 * @param sender
348 * is the sender to update
349 */
350 public static void showHorse(CommandSender sender, String[] args) {
351 if (notAllowed(sender, H_STATS, true))
352 return;
353 System.out.println("==DEBUG FOR THOSE WHO GET LAG SPIKES");
354 long time = System.currentTimeMillis();
355
356 Player p = (Player) sender;
357 if (playersWithScoreboards.contains(p.getName())) {
358 p.sendMessage(ChatColor.GREEN + "Already showing the horse's stats.");
359 return;
360 }
361
362 RPGHorse h = currentHorse(p, args, 1);
363 if (h == null) {
364 msg(p, NO_HORSES);
365 return;
366 }
367 System.out.println("#1= " + (System.currentTimeMillis() - time));
368
369 ScoreboardManager manager = Bukkit.getScoreboardManager();
370 Scoreboard board = manager.getNewScoreboard();
371
372 System.out.println("#2= " + (System.currentTimeMillis() - time));
373 Objective obj = board.registerNewObjective("horsestats", "dummy");
374 obj.setDisplaySlot(DisplaySlot.SIDEBAR);
375 obj.setDisplayName(ChatColor.YELLOW + "\"" + h.name + "\" Stats");
376 System.out.println("#3= " + (System.currentTimeMillis() - time));
377 try {
378 obj.getScore((ChatColor.GREEN + "Swiftness") + ChatColor.WHITE + " " + h.swiftness.level).setScore(8);
379 obj.getScore((ChatColor.DARK_GRAY + "Sprint: ") + ChatColor.GRAY + "= " + ((int) (h.swiftness.amplitude))
380 + (ChatColor.DARK_GRAY + "Time: ") + ChatColor.GRAY + "= " + ((int) (h.swiftness.duration / 20))
381 + "s").setScore(7);
382 obj.getScore((ChatColor.GREEN + "Agility") + ChatColor.WHITE + " " + h.agility.level).setScore(6);
383 obj.getScore((ChatColor.DARK_GRAY + "Dodge:") + ChatColor.GRAY + "= "
384 + ((int) (h.agility.dodgeChance * 100)) + "%" + (ChatColor.DARK_GRAY + "Roll:") + ChatColor.GRAY
385 + "= " + ((int) (h.agility.rollChance * 100)) + "%").setScore(5);
386 obj.getScore((ChatColor.GREEN + "Vitality") + ChatColor.WHITE + " " + h.vitality.level).setScore(4);
387 obj.getScore((ChatColor.DARK_GRAY + "Base") + ChatColor.GRAY + "= "
388 + ((((Damageable) h.horse).getMaxHealth() - h.vitality.healthBonus)) / 2
389 + (ChatColor.DARK_GRAY + " Bonus") + ChatColor.GRAY + "= " + ((int) (h.vitality.healthBonus / 2)))
390 .setScore(3);
391 obj.getScore((ChatColor.GREEN + "Wrath") + ChatColor.WHITE + " " + h.wrath.level).setScore(2);
392 obj.getScore((ChatColor.DARK_GRAY + "Infuriate: ") + ChatColor.GRAY + "= "
393 + ((int) (h.wrath.infuriateChance * 100)) + "%").setScore(1);
394 obj.getScore((ChatColor.GOLD + "Power Level") + ChatColor.WHITE + " " + h.powerLevel).setScore(0);
395
396 obj.getScore((ChatColor.GOLD + "Sex") + ChatColor.WHITE + " " + (h.isMale ? "Male" : "Female")
397 + (h.variant == Variant.DONKEY || h.variant == Variant.MULE ? "(Gelding)" : "")).setScore(-1);
398
399 } catch (Exception e) {
400 obj.getScore(Bukkit.getOfflinePlayer(ChatColor.GREEN + "Swiftness")).setScore(h.swiftness.level);
401 obj.getScore(Bukkit.getOfflinePlayer(ChatColor.GREEN + "Agility")).setScore(h.agility.level);
402 obj.getScore(Bukkit.getOfflinePlayer(ChatColor.GREEN + "Vitality")).setScore(h.vitality.level);
403 obj.getScore(Bukkit.getOfflinePlayer(ChatColor.GREEN + "Wrath")).setScore(h.wrath.level);
404 obj.getScore(Bukkit.getOfflinePlayer(ChatColor.GOLD + "Power Level")).setScore(h.powerLevel);
405
406 obj.getScore(Bukkit.getOfflinePlayer((ChatColor.DARK_GRAY + "Sprint: ") + ChatColor.GRAY + "= "
407 + ((int) (h.swiftness.amplitude)) + (ChatColor.DARK_GRAY + "Time: ") + ChatColor.GRAY + "= "
408 + ((int) (h.swiftness.duration / 20)) + "s")).setScore(7);
409
410 obj.getScore(Bukkit.getOfflinePlayer((ChatColor.DARK_GRAY + "Dodge:") + ChatColor.GRAY + "= "
411 + ((int) (h.agility.dodgeChance * 100)) + "%" + (ChatColor.DARK_GRAY + "Roll:") + ChatColor.GRAY
412 + "= " + ((int) (h.agility.rollChance * 100)) + "%")).setScore(5);
413
414 obj.getScore(Bukkit.getOfflinePlayer((ChatColor.DARK_GRAY + "Base") + ChatColor.GRAY + "= "
415 + (h.horse == null ? "?" : +((((Damageable) h.horse).getMaxHealth() - h.vitality.healthBonus) / 2))
416 + ChatColor.DARK_GRAY + " Bonus" + ChatColor.GRAY + "= " + ((int) (h.vitality.healthBonus / 2))))
417 .setScore(3);
418
419 obj.getScore(Bukkit.getOfflinePlayer((ChatColor.DARK_GRAY + "Infuriate: ") + ChatColor.GRAY + "= "
420 + ((int) (h.wrath.infuriateChance * 100)) + "%")).setScore(1);
421
422 }
423 System.out.println("#4= " + (System.currentTimeMillis() - time));
424 Scoreboard oldsb = p.getScoreboard();
425 p.setScoreboard(board);
426 playersWithScoreboards.add(p.getName());
427
428 Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(instance, new ScoreboardTask(p, oldsb), 200);
429 System.out.println("#5= " + (System.currentTimeMillis() - time));
430 }
431
432 /**
433 * Displays the skill statistics message
434 *
435 * @param sender
436 * is the sender to message
437 * @param skill
438 * is the skill to show
439 * @param args
440 * are the command arguments
441 */
442 public static void showSkill(CommandSender sender, String skill, String[] args) {
443 if (notAllowed(sender, H_SKILL, true))
444 return;
445 Player p = (Player) sender;
446 RPGHorse h = currentHorse(p, args, 1);
447 if (h == null)
448 return;
449
450 switch (skill) {
451 case "swiftness":
452 h.swiftness.stats(sender);
453 break;
454 case "agility":
455 h.agility.stats(sender);
456 break;
457 case "vitality":
458 h.vitality.stats(sender);
459 break;
460 case "wrath":
461 h.wrath.stats(sender);
462 break;
463 }
464 }
465
466 /**
467 * Attempts to claim a horse
468 *
469 * @param sender
470 * is the sender to message
471 */
472 public static void claimHorse(CommandSender sender) {
473 if (notAllowed(sender, H_CLAIM, true))
474 return;
475 Player p = (Player) sender;
476
477 int senderHorses = ownedHorses.containsKey(p.getName()) ? ownedHorses.get(p.getName()).size() : 0;
478
479 if (maxHorses(p) != -1 && senderHorses >= maxHorses(p)) {
480 msg(p, MAX_HORSES);
481 return;
482 }
483 /*
484 * if (pCurrentHorse.containsKey(p)) { msg(p, BANISH_HORSE); return; }
485 */
486
487 boolean aHorse = false;
488 try {
489 aHorse = p.getVehicle() instanceof org.bukkit.entity.AbstractHorse;
490 } catch (Error | Exception e) {
491 aHorse = p.getVehicle() instanceof Horse;
492 }
493
494 if (!aHorse) {
495 msg(p, "&aYou must be riding your horse to claim it!");
496 return;
497 }
498
499 Entity horse = p.getVehicle();
500 if (hSpawnedHorses.containsKey(horse)) {
501 if (hSpawnedHorses.get(horse).owner.equals(sender.getName())) {
502 msg(p, "&aYou already own this horse!");
503 } else {
504 msg(p, "&aThis horse is already owned!");
505 }
506 return;
507 }
508 boolean kl = false;
509 try {
510 kl = !((Tameable) horse).isTamed() || ((Horse) horse).getInventory().getSaddle() == null;
511 } catch (Error | Exception e) {
512 kl = !((Tameable) horse).isTamed()
513 ||( !((org.bukkit.entity.AbstractHorse) horse).getInventory().contains(Material.SADDLE)&& !((org.bukkit.entity.AbstractHorse) horse).getInventory().contains(Material.CARPET));
514 }
515 if (kl) {
516 msg(p, HORSE_NEEDS_TAME);
517 return;
518 }
519
520 if (useEconomy && claimCost > 0) {
521 double currentCost = Math.pow(claimCostMultiplier, senderHorses) * claimCost;
522 EconomyResponse r;
523 try {
524 r = econ.withdrawPlayer(p, currentCost);
525 } catch (Exception e) {
526 r = econ.withdrawPlayer(p.getName(), currentCost);
527 }
528 if (r.transactionSuccess()) {
529 msg(p, PURCHASED_FOR_CLAIM.replaceAll("%amount%", ""+econ.format(currentCost)));
530 msg(p, NEXT_HORSE_COST.replaceAll("%amount%",
531 econ.format(Math.pow(claimCostMultiplier, senderHorses + 1) * claimCost)));
532 } else {
533 msg(p, NOTENOUGHMONEY);
534 msg(p, "&aYou need: &e" + econ.format(currentCost));
535 return;
536 }
537 }
538
539 RPGHorse h;
540 try {
541 h = new RPGHorse(p, (Horse) horse);
542 } catch (Error | Exception e) {
543 h = new RPGHorse(p, (org.bukkit.entity.AbstractHorse) horse);
544 }
545 h.horse = horse;
546 h.setName(h.name);
547
548 pCurrentHorse.put(p, h);
549 hSpawnedHorses.put(horse, h);
550 if (!ownedHorses.containsKey(p.getName()))
551 ownedHorses.put(p.getName(), new TreeSet<RPGHorse>());
552 ownedHorses.get(p.getName()).add(h);
553 horses.add(h);
554
555 msg(p, CLAIM_NAME.replaceAll("%name%",h.name));
556 }
557
558 /**
559 * Accepts or declines a horse offer
560 *
561 * @param sender
562 * is the sender to message
563 */
564 public static void buyHorse(CommandSender sender, boolean buy) {
565 if (notAllowed(sender, H_BUY, true))
566 return;
567 if (!useEconomy) {
568 msg(sender, NO_ECONOMY);
569 return;
570 }
571 Player p = (Player) sender;
572
573 if (!offers.containsKey(p)) {
574 msg(p, "&aYou don't have an offer pending.");
575 return;
576 }
577 if (!buy) {
578 offers.remove(p);
579 msg(p, "&aOffer declined.");
580 return;
581 }
582 if (pCurrentHorse.containsKey(p)) {
583 msg(p, BANISH_HORSE);
584 return;
585 }
586
587 RPGHorse h = offers.get(p);
588 EconomyResponse er1;
589 try {
590 er1 = econ.withdrawPlayer(p, h.price);
591 } catch (Exception e) {
592 er1 = econ.withdrawPlayer(p.getName(), h.price);
593 }
594 if (!er1.transactionSuccess()) {
595 msg(p, "&c" + er1.errorMessage);
596 return;
597 }
598 EconomyResponse er2;
599 try {
600 er2 = econ.depositPlayer(Bukkit.getOfflinePlayer(h.owner), h.price);
601 } catch (Exception e) {
602 er2 = econ.depositPlayer(h.owner, h.price);
603 }
604 if (!er2.transactionSuccess()) {
605 econ.depositPlayer(p.getName(), h.price);
606 return;
607 }
608
609 for (Player seller : instance.getServer().getOnlinePlayers()) {
610 if (seller.getName().equalsIgnoreCase(h.owner)) {
611 pCurrentHorse.remove(seller);
612 msg(seller, "&b" + h.name + "&a sold to &b" + p.getName() + "&a for &b" + econ.format(h.price));
613 break;
614 }
615 }
616 h.banish();
617 msg(p, "&b" + h.name + "&a bought from &b" + h.owner + "&a for &b" + econ.format(h.price));
618 h.owner = p.getName();
619 offers.remove(p);
620 }
621
622 /**
623 * Attempts to sell your horse
624 *
625 * @param sender
626 * is the sender to message
627 * @param args
628 * are the command arguments
629 */
630 public static void sellHorse(CommandSender sender, String[] args) {
631 if (notAllowed(sender, H_SELL, true))
632 return;
633 if (!useEconomy) {
634 msg(sender, NO_ECONOMY);
635 return;
636 }
637 Player p = (Player) sender;
638 if (!pCurrentHorse.containsKey(p)) {
639 msg(p, "&aPlease summon the horse first.");
640 return;
641 }
642
643 double cost = 0;
644 try {
645 cost = Double.parseDouble(args[1]);
646 } catch (Exception ex) {
647 msg(p, "&aInvalid horse price.");
648 return;
649 }
650
651 if (args.length < 3) {
652 msg(p, "&aPlease specify the potential buyer.");
653 return;
654 }
655
656 String buyerName = args[2];
657 for (int i = 3; i < args.length; i++)
658 buyerName += " " + args[i];
659
660 Player buyer = null;
661 for (Player player : instance.getServer().getOnlinePlayers()) {
662 if (player.getName().equalsIgnoreCase(buyerName)) {
663 buyer = player;
664 break;
665 }
666 }
667 if (buyer == null) {
668 msg(p, "&aCould not find &b" + buyerName + "&a online.");
669 return;
670 }
671
672 RPGHorse h = pCurrentHorse.get(p);
673 h.price = cost;
674 offers.put(buyer, h);
675 Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(instance, new OfferTask(p), 1200);
676
677 msg(p, "&aOffering &b" + h.name + "&a at &b" + econ.format(cost) + "&a for &b60 seconds.");
678 msg(buyer, "&aType &b/h buy&a within &b60s&a to buy &b" + h.name + "&a for &b" + econ.format(cost));
679 msg(buyer, "&aType &b/h decline&a to decline the offer.");
680 }
681
682 /**
683 * Summons the specified horse
684 *
685 * @param sender
686 * is the sender to message
687 * @param args
688 * are the command arguments
689 */
690 public static void summonHorse(CommandSender sender, String[] args) {
691 if (notAllowed(sender, H_SUMMON, true))
692 return;
693 Player p = (Player) sender;
694
695 /**
696 * if (pCurrentHorse.containsKey(p)) { msg(p, "&b" + pCurrentHorse.get(p).name +
697 * "&a is already summoned."); return; }
698 */
699
700 RPGHorse h = getHorseNotSpawned(p, args, 1);
701 if (h == null && args.length == 1) {
702 if (freeHorse) {
703 msg(p, "&aHere's one for free...");
704 h = new RPGHorse(p);
705 if (!ownedHorses.containsKey(p.getName()))
706 ownedHorses.put(p.getName(), new TreeSet<RPGHorse>());
707 ownedHorses.get(p.getName()).add(h);
708 horses.add(h);
709 } else {
710 if (ownedHorses.containsKey(p.getName())) {
711 if (ownedHorses.get(p.getName()).size() >= 0) {
712 msg(p, NO_MORE_HORSES);
713 } else {
714 msg(p, NO_HORSES);
715 }
716 } else {
717 msg(p, NO_HORSES);
718 }
719 }
720 }
721 if (h != null) {
722 if (hSpawnedHorses.containsKey(h.horse)) {
723 msg(p, "&e" + h.name + "&a has already been summoned.");
724 return;
725 }
726 if (h.isBanished || h.isDead) {
727 HorseRPG.msg(p, NEED_TIME_TO_RECHARGE.replaceAll("%name%",h.name));
728 } else {
729 if (useEconomy && summonCost > 0) {
730 boolean b = false;
731 try {
732 b = econ.withdrawPlayer(p, summonCost).transactionSuccess();
733 } catch (Exception e) {
734 b = econ.withdrawPlayer(p.getName(), summonCost).transactionSuccess();
735 }
736 if (b)
737 msg(p, "&aHorse summoned for &e" + econ.format(summonCost));
738 else {
739 msg(p, "&aYou need &e" + econ.format(summonCost) + "&a to summon a horse.");
740 return;
741 }
742 }
743 h.summon(p);
744 pCurrentHorse.put(p, h);
745 }
746 }
747 }
748
749 /**
750 * Banishes the player's horse
751 *
752 * @param sender
753 * is the sender to message
754 */
755 public static void banishHorse(CommandSender sender) {
756 if (notAllowed(sender, H_BANISH, true))
757 return;
758 Player p = (Player) sender;
759
760 if (!pCurrentHorse.containsKey(p)) {
761 msg(sender, NO_HORSE_SUMMONED);
762 return;
763 }
764 RPGHorse horse = pCurrentHorse.get(p);
765 if(!horse.horse.getLocation().getChunk().isLoaded()) {
766 msg(sender,BANISH_LOADED_CHUNK);
767 return;
768 }
769
770
771
772 if (useEconomy && banishCost > 0) {
773 boolean b = false;
774 try {
775 b = econ.withdrawPlayer(p, banishCost).transactionSuccess();
776 } catch (Exception e) {
777 b = econ.withdrawPlayer(p.getName(), banishCost).transactionSuccess();
778 }
779
780 if (b)
781 msg(p, "&aHorse banished for &e" + econ.format(banishCost));
782 else {
783 msg(p, "&aYou need &e" + econ.format(summonCost) + "&a to banish your horse.");
784 return;
785 }
786 }
787 pCurrentHorse.remove(p);
788 horse.banish();
789 for (RPGHorse others : ownedHorses.get(p.getName())) {
790 if (hSpawnedHorses.containsKey(others.horse)) {
791 pCurrentHorse.put(p, others);
792 break;
793 }
794 }
795 msg(p, "&a" + horse.name + " banished.");
796 }
797
798 /**
799 * Makes a horse invincible
800 *
801 * @param sender
802 * is the sender to message
803 * @param args
804 * are the command arguments
805 */
806 public static void protectHorse(CommandSender sender, String[] args, boolean useGodMode) {
807 if (useGodMode && notAllowed(sender, H_PROTECT, true))
808 return;
809 if (!useGodMode && notAllowed(sender, H_UNPROTECT, true))
810 return;
811 Player p = (Player) sender;
812 RPGHorse h = currentHorse(p, args, 1);
813 if (h == null)
814 return;
815 h.godmode = useGodMode;
816 msg(p, useGodMode ? "&aHorse protected." : "&aHorse unprotected.");
817 }
818
819 /**
820 * Adds/removes xp from a horse
821 *
822 * @param sender
823 * is the sender to message
824 * @param args
825 * are the command arguments
826 */
827 public static void addHorseXP(CommandSender sender, String[] args) {
828 boolean addXP = args[0].equalsIgnoreCase("addxp");
829 if (addXP && notAllowed(sender, H_ADDXP, true))
830 return;
831 if (!addXP && notAllowed(sender, H_DELXP, true))
832 return;
833 Player p = (Player) sender;
834
835 if (args.length < 2) {
836 msg(p, "&aPlease specify a valid skill.");
837 return;
838 }
839 if (args.length < 3) {
840 msg(p, "&aPlease specify an xp amount.");
841 return;
842 }
843 RPGHorse h = currentHorse(p, args, 3);
844 if (h == null)
845 return;
846
847 int xp = 0;
848 try {
849 xp = Integer.parseInt(args[2]);
850 } catch (NumberFormatException ex) {
851 msg(p, "&aPlease specify an xp amount.");
852 return;
853 }
854
855 String op = "&aAdded &b";
856 if (!addXP) {
857 xp *= -1;
858 op = "&aRemoved &b";
859 }
860
861 switch (args[1]) {
862 case "swiftness":
863 h.swiftness.addXP(xp, p);
864 break;
865 case "agility":
866 h.agility.addXP(xp, p);
867 break;
868 case "vitality":
869 h.vitality.addXP(xp, p);
870 break;
871 case "wrath":
872 h.wrath.addXP(xp, p);
873 break;
874 default:
875 msg(p, "&aPlease specify a valid skill.");
876 return;
877 }
878 msg(p, op + xp + "&a from &b" + h.name);
879 }
880
881 /**
882 * Displays the set help message
883 *
884 * @param sender
885 * is the sender to message
886 */
887 public static void showSetHelp(CommandSender sender) {
888 if (notAllowed(sender, H_SET, false))
889 return;
890 msg(sender, "");
891 msg(sender, "&aSet Help:");
892 for (Entry<String, String> entry : setHelp.entrySet())
893 if (sender.hasPermission(entry.getKey()))
894 msg(sender, entry.getValue());
895 }
896
897 /**
898 * Changes the currently spawned horse's name
899 *
900 * @param sender
901 * is the sender to message
902 * @param args
903 * are the command arguments
904 */
905 public static void setHorseName(CommandSender sender, String[] args) {
906 if (notAllowed(sender, H_SET_NAME, true))
907 return;
908 Player p = (Player) sender;
909 if (args.length <= 2) {
910 msg(p, INVALID_NAME);
911 return;
912 }
913
914 RPGHorse h = pCurrentHorse.get(p);
915 if (h == null) {
916 msg(p, NO_HORSE_SUMMONED);
917 return;
918 }
919
920 if (args[2].equalsIgnoreCase("random"))
921 h.setName(RPGHorse.randomName(p));
922 else {
923 String hName = args[2];
924 for (int i = 3; i < args.length; i++)
925 hName += " " + args[i];
926 hName = hName.replaceAll("_", " ");
927 h.setName(hName);
928 }
929 }
930
931 /**
932 * Changes the current spawned horse's color
933 *
934 * @param sender
935 * is the sender to message
936 * @param args
937 * are the command arguments
938 */
939 public static void setHorseColor(CommandSender sender, String[] args) {
940 if (notAllowed(sender, H_SET_NAME, true))
941 return;
942 Player p = (Player) sender;
943 if (args.length <= 2) {
944 msg(p, INVALID_COLOR);
945 return;
946 }
947
948 RPGHorse h = pCurrentHorse.get(p);
949 if (h == null) {
950 msg(p, NO_HORSE_SUMMONED);
951 return;
952 }
953
954 if (args[2].equalsIgnoreCase("random"))
955 h.setColor(RPGHorse.randomColor());
956 else {
957 try {
958 h.setColor(Color.valueOf(args[2]));
959 } catch (Exception ex) {
960 msg(p, INVALID_COLOR);
961 StringBuilder sb = new StringBuilder();
962 sb.append("Valid colors: ");
963 for (Color c : Color.values()) {
964 sb.append(c.toString() + ", ");
965 }
966 msg(p, sb.toString());
967 }
968 }
969 }
970
971 /**
972 * Changes the currently spawned horse's style
973 *
974 * @param sender
975 * is the sender to message
976 * @param args
977 * are the command arguments
978 */
979 public static void setHorseStyle(CommandSender sender, String[] args) {
980 if (notAllowed(sender, H_SET_NAME, true))
981 return;
982 Player p = (Player) sender;
983 if (args.length <= 2) {
984 msg(p, INVALID_STYLE);
985 return;
986 }
987
988 RPGHorse h = pCurrentHorse.get(p);
989 if (h == null) {
990 msg(p, NO_HORSE_SUMMONED);
991 return;
992 }
993
994 if (args[2].equalsIgnoreCase("random"))
995 h.setStyle(RPGHorse.randomStyle());
996 else {
997 try {
998 h.setStyle(Style.valueOf(args[2]));
999 } catch (Exception ex) {
1000 msg(p, INVALID_STYLE);
1001 StringBuilder sb = new StringBuilder();
1002 sb.append("Valid styles: ");
1003 for (Style c : Style.values()) {
1004 sb.append(c.toString() + ", ");
1005 }
1006 msg(p, sb.toString());
1007 }
1008 }
1009 }
1010
1011 /**
1012 * Changes the currently spawned horse's variant
1013 *
1014 * @param sender
1015 * is the sender to message
1016 * @param args
1017 * are the command arguments
1018 */
1019 public static void setHorseVariant(CommandSender sender, String[] args) {
1020 if (notAllowed(sender, H_SET_TYPE, true))
1021 return;
1022 Player p = (Player) sender;
1023
1024 if (args.length <= 2) {
1025 msg(p, INVALID_VARIANT);
1026 return;
1027 }
1028
1029 RPGHorse h = pCurrentHorse.get(p);
1030 if (h == null) {
1031 msg(p, NO_HORSE_SUMMONED);
1032 return;
1033 }
1034
1035 switch (args[2].toLowerCase()) {
1036 case "donkey":
1037 h.setVariant(Variant.DONKEY);
1038 break;
1039 case "horse":
1040 h.setVariant(Variant.HORSE);
1041 break;
1042 case "mule":
1043 h.setVariant(Variant.MULE);
1044 break;
1045 case "skele":
1046 h.setVariant(Variant.SKELETON_HORSE);
1047 break;
1048 case "zombie":
1049 h.setVariant(Variant.UNDEAD_HORSE);
1050 break;
1051 case "rand":
1052 h.setVariant(RPGHorse.randomVariant());
1053 break;
1054 default:
1055 msg(p, INVALID_VARIANT);
1056 }
1057 }
1058
1059 /**
1060 * Allows the horse to be breed with by other players
1061 *
1062 * @param sender
1063 * is the sender to message
1064 * @param args
1065 * are the command arguments
1066 */
1067 private void allowBreeding(CommandSender sender, String[] args) {
1068 if (notAllowed(sender, H_BREED, true))
1069 return;
1070 Player p = (Player) sender;
1071 String name = p.getName();
1072
1073 if (!ownedHorses.containsKey(name))
1074 ownedHorses.put(name, new TreeSet<RPGHorse>());
1075 if (maxHorses(p) != -1 && ownedHorses.get(p.getName()).size() >= maxHorses(p)) {
1076 msg(p, MAX_HORSES);
1077 return;
1078 }
1079
1080 RPGHorse h = currentHorse(p, args, 1);
1081 if (h == null) {
1082 msg(p, NO_HORSE_SUMMONED);
1083 return;
1084 }
1085 h.allowBreeding = !h.allowBreeding;
1086 msg(p, ALLOW_BREEDING, h.name, h.allowBreeding + "");
1087 }
1088
1089 /**
1090 * Creates a new horse
1091 *
1092 * @param sender
1093 * is the sender to message
1094 * @param args
1095 * are the command arguments
1096 */
1097 public static void createHorse(CommandSender sender, String[] args, boolean gift) {
1098 if (notAllowed(sender, H_CREATE, true))
1099 return;
1100 Player p = (Player) sender;
1101 int offset = 0;
1102 if (gift) {
1103 if (args.length >= 2) {
1104 p = Bukkit.getPlayer(args[1]);
1105 offset++;
1106 }
1107 }
1108 if (p == null) {
1109 sender.sendMessage("[MCMMO] Player is not online");
1110 return;
1111 }
1112 String name = p.getName();
1113
1114 if (!ownedHorses.containsKey(name))
1115 ownedHorses.put(name, new TreeSet<RPGHorse>());
1116 if (maxHorses(p) != -1 && ownedHorses.get(p.getName()).size() >= maxHorses(p)) {
1117 msg(p, MAX_HORSES);
1118 return;
1119 }
1120
1121 RPGHorse h = new RPGHorse(p);
1122 ownedHorses.get(name).add(h);
1123 horses.add(h);
1124
1125 if (args.length >= 2 + offset) {
1126 String hName = args[1];
1127 for (int i = 2 + offset; i < args.length; i++)
1128 hName += " " + args[i];
1129 h.setName(hName);
1130 }
1131 if (!pCurrentHorse.containsKey(p)) {
1132 h.summon(p);
1133 pCurrentHorse.put(p, h);
1134 }
1135 msg(p, HORSE_BRED);
1136 }
1137
1138 /**
1139 * Deletes the specified horse
1140 *
1141 * @param sender
1142 * is the sender to message
1143 */
1144 public static void deleteHorse(CommandSender sender, String[] args) {
1145 if (notAllowed(sender, H_DELETE, true))
1146 return;
1147 Player p = (Player) sender;
1148
1149 if (args.length <= 1) {
1150 msg(p, INVALID_NAME);
1151 return;
1152 }
1153
1154 RPGHorse h = currentHorse(p, args, 1);
1155 if (h == null)
1156 return;
1157
1158 pCurrentHorse.remove(p);
1159 h.banish();
1160 ownedHorses.get(p.getName()).remove(h);
1161 horses.remove(h);
1162 // Test if this removes horses.
1163 h_config.removeHorse(h);
1164
1165 msg(p, "&b" + h.name + "&a won't be bothering you anymore.");
1166 }
1167
1168 /**
1169 * Reloads the horse database
1170 *
1171 * @param sender
1172 * is the sender to message
1173 */
1174 public void loadDatabase(CommandSender sender) {
1175 if (notAllowed(sender, H_DB, false))
1176 return;
1177
1178 for (RPGHorse h : pCurrentHorse.values())
1179 h.banish();
1180
1181 ownedHorses.clear();
1182 pCurrentHorse.clear();
1183 hSpawnedHorses.clear();
1184 horses.clear();
1185
1186 initHorses();
1187
1188 msg(sender, "&aHorse database reloaded.");
1189
1190 }
1191
1192 /**
1193 * Reloads the plugin
1194 *
1195 * @param sender
1196 * is the sender to message
1197 */
1198 public void reloadPlugin(CommandSender sender) {
1199 if (notAllowed(sender, H_RELOAD, false))
1200 return;
1201 HorseRPG.h_config = new HorseConfigHandler(new File(getDataFolder(), "horsedata.yml"));
1202 onDisable();
1203 onEnable();
1204 msg(sender, "&bmcMMO Horses&a reloaded.");
1205 }
1206
1207 @Override
1208 public void onEnable() {
1209 instance = this;
1210 HorseRPG.h_config = new HorseConfigHandler(new File(getDataFolder(), "horsedata.yml"));
1211
1212 initVariables();
1213 initMessages();
1214 initConfig();
1215 initHelp();
1216 // This is just a work around. This makes sure that we can
1217 // transfer db horses to the file
1218 Object o = h_config.getGlobalVariable(Keys.G_dbtransfermode.toString());
1219 if (o == null || (int) o < 1) {
1220 h_config.setGlobalVar(Keys.G_dbtransfermode.toString(), 1);
1221 }
1222 initHorses();
1223
1224 if (((int) h_config.getGlobalVariable(Keys.G_dbtransfermode.toString())) < 2) {
1225 h_config.setGlobalVar(Keys.G_dbtransfermode.toString(), 2);
1226 }
1227
1228 new BukkitRunnable() {
1229 @Override
1230 public void run() {
1231 for (RPGHorse h : hSpawnedHorses.values()) {
1232 h_config.saveHorse(h, false);
1233 }
1234 h_config.save();
1235 }
1236 }.runTaskTimer(this, 20 * 60 * 15, 20 * 60 * 15);
1237
1238 cooldownTask = new CooldownTask().runTaskTimer(this, 0, 20);
1239
1240 if (useEconomy && !setupEconomy()) {
1241 getLogger().severe("Plugin disabled due to Vault dependency!");
1242 getLogger().severe("Set 'enable-economy' to false in config to disable dependency.");
1243 getServer().getPluginManager().disablePlugin(this);
1244 return;
1245 }
1246
1247 PluginManager pm = getServer().getPluginManager();
1248 pm.registerEvents(new HorseListener(), this);
1249 pm.registerEvents(new PlayerListener(), this);
1250 pm.registerEvents(shop = new ShopManager(), this);
1251 try {
1252 if (forceClaimOnTaim)
1253 pm.registerEvents(new TameToClaimListener(), this);
1254 } catch (Error | Exception e5) {
1255 e5.printStackTrace();
1256 }
1257
1258 if (!getConfig().contains("auto-update")) {
1259 getConfig().set("auto-update", true);
1260 saveConfig();
1261 }
1262
1263 // new Updater(instance, 61609, getConfig().getBoolean("auto-update"));
1264 GithubUpdater.autoUpdate(this, "ZombieStriker", "mcMMOHorses", "mcMMOHorses.jar");
1265
1266 // Download the API dependancy
1267 if (Bukkit.getPluginManager().getPlugin("PluginConstructorAPI") == null) {
1268 // new `encyDownloader(this, 276723);
1269 GithubDependDownloader.autoUpdate(this,
1270 new File(getDataFolder().getParentFile(), "PluginConstructorAPI.jar"), "ZombieStriker",
1271 "PluginConstructorAPI", "PluginConstructorAPI.jar");
1272 }
1273
1274 Metrics metrics = new Metrics(this);
1275 // Optional: Add custom charts
1276 metrics.addCustomChart(new Metrics.SimplePie("horsecount", new java.util.concurrent.Callable<String>() {
1277 @Override
1278 public String call() throws Exception {
1279 return horses.size() + "";
1280 }
1281 }));
1282 }
1283
1284 /**
1285 * Attempts to set up the economy
1286 *
1287 * @return true if economy is set up successfully
1288 */
1289 private boolean setupEconomy() {
1290 if (getServer().getPluginManager().getPlugin("Vault") == null)
1291 return false;
1292 RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class);
1293 if (rsp == null)
1294 return false;
1295 econ = rsp.getProvider();
1296 return econ != null;
1297 }
1298
1299 /**
1300 * Initializes the variables
1301 */
1302 private void initVariables() {
1303 config = new ConfigAccessor(this, "config.yml");
1304 config.saveDefaultConfig();
1305
1306 if (!config.getConfig().contains("enable-economy"))
1307 config.overwriteConfig();
1308
1309 offers = new HashMap<Player, RPGHorse>();
1310 ownedHorses = new HashMap<String, TreeSet<RPGHorse>>();
1311 pCurrentHorse = new HashMap<Player, RPGHorse>();
1312 hSpawnedHorses = new HashMap<Entity, RPGHorse>();
1313 horses = new HashSet<RPGHorse>();
1314 }
1315
1316 private void initMessages() {
1317 messages = new MessagesConfigHandler(new File(getDataFolder(), "messages.yml"));
1318
1319 BANISH_HORSE = messages.a("Banish_horse", BANISH_HORSE);
1320 HORSE_BRED = messages.a("Horse_bred", HORSE_BRED);
1321 HORSES_SAVED = messages.a("Horses_saved", HORSES_SAVED);
1322 INVALID_COLOR = messages.a("Invalid_color", INVALID_COLOR);
1323 INVALID_COMMAND = messages.a("Invalid_command", INVALID_COMMAND);
1324 INVALID_NAME = messages.a("Invalid_name", INVALID_NAME);
1325 INVALID_PAGE = messages.a("Invalid_page", INVALID_PAGE);
1326 INVALID_STYLE = messages.a("Invalid_style", INVALID_STYLE);
1327 INVALID_VARIANT = messages.a("Invalid_variant", INVALID_VARIANT);
1328 MAX_HORSES = messages.a("Max_horses", MAX_HORSES);
1329 NO_ECONOMY = messages.a("NoEconomy", NO_ECONOMY);
1330 NO_HORSES = messages.a("No_horses", NO_HORSES);
1331 NO_MORE_HORSES = messages.a("No_more_horses", NO_MORE_HORSES);
1332 NO_HORSE_SUMMONED = messages.a("No_horses_summoned", NO_HORSE_SUMMONED);
1333 NO_PERMISSION = messages.a("No_Permission", NO_PERMISSION);
1334 PAGE_DOES_NOT_EXIST = messages.a("Page_does_not_exist", PAGE_DOES_NOT_EXIST);
1335 PLAYER_ONLY = messages.a("Player_only", PLAYER_ONLY);
1336
1337 NO_WILD_HORSES = messages.a("No_wild_horses", NO_WILD_HORSES);
1338 NO_BREED_HORSES = messages.a("No_breeding_horses", NO_BREED_HORSES);
1339 ALLOW_BREEDING = messages.a("Allow_breeding", ALLOW_BREEDING);
1340
1341 NOT_ENOUGH_MONEY = messages.a("Not_enough_money", NOT_ENOUGH_MONEY);
1342 BOUGHT_HORSE = messages.a("Bought_horse", BOUGHT_HORSE);
1343 BOUGHT_HORSE_EXP1 = messages.a("Bought_horse_exp1", BOUGHT_HORSE_EXP1);
1344
1345 HORSE_NEEDS_TAME= messages.a("Horse_needs_tame", HORSE_NEEDS_TAME);
1346 PURCHASED_FOR_CLAIM = messages.a("PurchasedHorse", PURCHASED_FOR_CLAIM);
1347 NEXT_HORSE_COST= messages.a("Next_cost", NEXT_HORSE_COST);
1348 CLAIM_NAME = messages.a("Claimed_name",CLAIM_NAME );
1349 SKILL_INCREASED_BY= messages.a("Skill_Increased_By",SKILL_INCREASED_BY );
1350 NOTENOUGHMONEY= messages.a("Not_enough_money",NOTENOUGHMONEY );
1351 NEED_TIME_TO_RECHARGE= messages.a("Need_Time_To_Recharge", NEED_TIME_TO_RECHARGE);
1352 SKILL_REFRESH= messages.a("Skill_Refreshed", SKILL_REFRESH);
1353
1354 BANISH_LOADED_CHUNK= messages.a("Banished_In_Unloaded_Chunk", BANISH_LOADED_CHUNK);
1355
1356
1357 ShopManager.title=messages.a("Shop Title",ShopManager.title);
1358 }
1359
1360 /**
1361 * Initializes config.yml
1362 */
1363 private void initConfig() {
1364 try {
1365 FileConfiguration fc = config.getConfig();
1366 int saveInterval = fc.getInt("save-interval");
1367 saveTask = new SaveTask().runTaskTimer(this, saveInterval, saveInterval);
1368
1369 freeHorse = fc.getBoolean("free-horse");
1370 permanentDeath = fc.getBoolean("permanent-death");
1371 deathTimer = fc.getInt("death-timer");
1372 banishTimer = fc.getInt("banish-timer");
1373 sprintCooldown = fc.getInt("sprint-cooldown");
1374 infuriateCooldown = fc.getInt("infuriate-cooldown");
1375
1376 groups = new HashMap<String, Integer>();
1377 Map<String, Object> groupsRaw = fc.getConfigurationSection("groups").getValues(false);
1378 for (Entry<String, Object> entry : groupsRaw.entrySet())
1379 groups.put("mcmmohorses.groups." + entry.getKey(), (int) entry.getValue());
1380
1381 useEconomy = fc.getBoolean("enable-economy");
1382 claimCost = fc.getInt("claim-cost");
1383 claimCostMultiplier = fc.getInt("claim-cost-multiplier");
1384 summonCost = fc.getInt("summon-cost");
1385 banishCost = fc.getInt("banish-cost");
1386
1387 if (!h_config.containsGlobalVariable(Keys.G_nobanish.toString())) {
1388 h_config.setGlobalVar(Keys.G_nobanish.toString(), false);
1389 }
1390
1391 if (!h_config.containsGlobalVariable(Keys.G_banishOnDisable.toString())) {
1392 h_config.setGlobalVar(Keys.G_banishOnDisable.toString(), true);
1393 }
1394
1395 if (!h_config.containsGlobalVariable(Keys.G_DisableBreeding.toString())) {
1396 h_config.setGlobalVar(Keys.G_DisableBreeding.toString(), false);
1397 }
1398
1399 if (!h_config.containsGlobalVariable(Keys.G_banishonquit.toString())) {
1400 h_config.setGlobalVar(Keys.G_banishonquit.toString(), true);
1401 }
1402 if (!h_config.containsGlobalVariable(Keys.G_ClameOnTame.toString())) {
1403 h_config.setGlobalVar(Keys.G_ClameOnTame.toString(), false);
1404 }
1405
1406 for (Variant v : Variant.values()) {
1407 if (!h_config.containsGlobalVariable(Keys.G_horseCost.toString() + "." + v.name())) {
1408 h_config.setGlobalVar(Keys.G_horseCost.toString() + "." + v.name(), 100.0);
1409 }
1410 costForHorse.put(v, (Double) h_config.getGlobalVariable(Keys.G_horseCost.toString() + "." + v.name()));
1411 }
1412
1413 nobanishment = (boolean) h_config.getGlobalVariable(Keys.G_nobanish.toString());
1414 banishondisable = (boolean) h_config.getGlobalVariable(Keys.G_banishOnDisable.toString());
1415 banishonquit = (boolean) h_config.getGlobalVariable(Keys.G_banishonquit.toString());
1416 disableBreeding = (boolean) h_config.getGlobalVariable(Keys.G_DisableBreeding.toString());
1417
1418 forceClaimOnTaim = (boolean) h_config.getGlobalVariable(Keys.G_ClameOnTame.toString());
1419 } catch (Exception e) {
1420 getLogger().info("Error loading 'config.yml' file!");
1421 e.printStackTrace();
1422 }
1423 }
1424
1425 /**
1426 * Initializes help messages
1427 */
1428 private void initHelp() {
1429 help = new LinkedHashMap<String, String>();
1430 setHelp = new LinkedHashMap<String, String>();
1431
1432 help.put(H_HELP, "&b/h help &7[page] &a- Displays horse commands.");
1433 help.put(H_ME, "&b/h me &a- Displays your info.");
1434 help.put(H_CLAIM, "&b/h claim &a- Claims the horse you are riding.");
1435 help.put(H_STATS, "&b/h stats &7[horse] &a- Displays your horse info.");
1436 help.put(H_SUMMON, "&b/h summon &a- Spawns your horse.");
1437 help.put(H_BANISH, "&b/h banish &a- Despawns your horse.");
1438 help.put(H_DELETE, "&b/h kill &e<name> &a- Removes an owned horse for good.");
1439 if (useEconomy) {
1440 help.put(H_BUY, "&b/h buy &a- Buys a horse offered to you.");
1441 help.put(H_SELL, "&b/h sell &e<money> <player> &a- Sells the summoned horse.");
1442 help.put(H_SHOP, "&b/h shop &a- Opens the shop GUI to buy horses.");
1443 }
1444
1445 help.put(H_CREATE, "&b/h breed &7[name] &a- Breeds a horse.");
1446 help.put(H_ADDXP, "&b/h addxp &e<skill> <xp> &7[name] &a- Adds xp to horse.");
1447 help.put(H_DELXP, "&b/h delxp &e<skill> <xp> &7[name] &a- Removes xp from horse.");
1448 help.put(H_PROTECT, "&b/h protect &a- Protects your horse from damage.");
1449 help.put(H_UNPROTECT, "&b/h unprotect &a- Unprotects your horse.");
1450 help.put(H_SET, "&b/h set &a- Displays a list of set commands.");
1451 help.put(H_SAVE, "&b/h save &a- Saves all horse data.");
1452 help.put(H_DB, "&b/h db &a- Reloads the horse database.");
1453 help.put(H_RELOAD, "&b/h reload &a- Reloads the configuration files.");
1454
1455 setHelp.put(H_SET_NAME, "&b/h set name &a<name|random>");
1456 setHelp.put(H_SET_COLOR, "&b/h set color &a<color|random>");
1457 setHelp.put(H_SET_STYLE, "&b/h set style &a<style|random>");
1458 setHelp.put(H_SET_TYPE, "&b/h set type &a<donkey|horse|mule|skele|zombie|rand>");
1459
1460 }
1461
1462 /**
1463 * Initializes horses.db
1464 */
1465 private void initHorses() {
1466 if (((int) h_config.getGlobalVariable(Keys.G_dbtransfermode.toString())) == 2) {
1467 if (h_config.anyOwners()) {
1468 for (String owner : h_config.getOwners()) {
1469 for (String name : h_config.getHorses(owner)) {
1470 RPGHorse h = h_config.getHorse(owner, name);
1471 if (!ownedHorses.containsKey(owner))
1472 ownedHorses.put(owner, new TreeSet<RPGHorse>());
1473
1474 ownedHorses.get(owner).add(h);
1475 horses.add(h);
1476 }
1477 }
1478 }
1479 } else {
1480 try {
1481 Class.forName("org.sqlite.JDBC");
1482 Connection connection = DriverManager.getConnection("jdbc:sqlite:horses.db");
1483 Statement statement = connection.createStatement();
1484 statement.setQueryTimeout(30);
1485
1486 statement.executeUpdate("create table if not exists horses ( name string, " + "owner string, "
1487 + "color string, " + "style string, " + "variant string, " + "protected integer, "
1488 + "swiftnessXP integer, " + "agilityXP integer, " + "vitalityXP integer, "
1489 + "wrathXP integer, sex integer)");
1490
1491 ResultSet rs = statement.executeQuery("select * from horses");
1492
1493 while (rs.next()) {
1494 String owner = rs.getString("owner");
1495 Color color = Color.valueOf(rs.getString("color"));
1496 Style style = Style.valueOf(rs.getString("style"));
1497 Variant variant = Variant.valueOf(rs.getString("variant"));
1498
1499 RPGHorse h = new RPGHorse(rs.getString("name"), owner, color, style, variant,
1500 rs.getInt("godmode") == 1, rs.getInt("swiftnessXP"), rs.getInt("agilityXP"),
1501 rs.getInt("vitalityXP"), rs.getInt("wrathXP"), null, 2.25, 2.25, rs.getInt("sex") == 0);
1502 // TODO:Tempfix. Since I don't want users to use the sql, just set the dfefault
1503 // value to 2.25
1504
1505 if (!ownedHorses.containsKey(owner))
1506 ownedHorses.put(owner, new TreeSet<RPGHorse>());
1507
1508 ownedHorses.get(owner).add(h);
1509 horses.add(h);
1510 }
1511 connection.close();
1512
1513 } catch (Exception e) {
1514 getLogger().info("Error loading 'horses.db' file!");
1515 System.out.println(e.getMessage());
1516 }
1517 }
1518 }
1519
1520 /**
1521 * Saves all horses in the sql database
1522 *
1523 * @param sender
1524 * is the sender to message
1525 */
1526 public static void saveHorses(CommandSender sender) {
1527 if (sender != null && !notAllowed(sender, H_SAVE, false))
1528 return;
1529 Connection connect = null;
1530 try {
1531 if (((int) h_config.getGlobalVariable(Keys.G_dbtransfermode.toString())) == 2) {
1532
1533 for (TreeSet<RPGHorse> horseSet : ownedHorses.values()) {
1534 for (RPGHorse h : horseSet) {
1535 h_config.saveHorse(h, false);
1536 }
1537 }
1538 h_config.save();
1539
1540 } else {
1541 connect = DriverManager.getConnection("jdbc:sqlite:horses.db");
1542 Statement statement = connect.createStatement();
1543 statement.setQueryTimeout(30);
1544
1545 statement.executeUpdate("drop table if exists horses");
1546 statement.executeUpdate("create table horses ( name string, " + "owner string, " + "color string, "
1547 + "style string, " + "variant string, " + "godmode integer, " + "swiftnessXP integer, "
1548 + "agilityXP integer, " + "vitalityXP integer, " + "wrathXP integer, sex integer)");
1549
1550 for (TreeSet<RPGHorse> horseSet : ownedHorses.values()) {
1551 for (RPGHorse h : horseSet)
1552 statement.executeUpdate("insert into horses values('" + h.name + "', '" + h.owner + "', '"
1553 + h.color + "', '" + h.style + "', '" + h.variant + "', " + (h.godmode ? 1 : 0) + ", "
1554 + h.swiftness.xp + ", " + h.agility.xp + ", " + h.vitality.xp + ", " + h.wrath.xp + ", "
1555 + (h.isMale ? 0 : 1) + ")");
1556 }
1557 }
1558 if (sender != null)
1559 msg(sender, HORSES_SAVED);
1560 if (instance != null)
1561 instance.getLogger().info(HORSES_SAVED);
1562 } catch (Exception e) {
1563 System.err.println(e);
1564 } finally {
1565 try {
1566 if (connect != null)
1567 connect.close();
1568 } catch (Exception e) {
1569 System.err.println(e);
1570 }
1571 }
1572 }
1573
1574 @Override
1575 public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
1576 List<String> r = new ArrayList<>();
1577 if (args.length == 1) {
1578 a(r, "help", args[0]);
1579 a(r, "me", args[0]);
1580 a(r, "claim", args[0]);
1581 a(r, "stats", args[0]);
1582 a(r, "summon", args[0]);
1583 a(r, "banish", args[0]);
1584 a(r, "kill", args[0]);
1585 a(r, "buy", args[0]);
1586 a(r, "sell", args[0]);
1587 a(r, "shop", args[0]);
1588
1589 // TODO: REENABLE BREEDING
1590 // a(r, "allowbreeding", args[0]);
1591 a(r, "addxp", args[0]);
1592 a(r, "delxo", args[0]);
1593 a(r, "protect", args[0]);
1594 a(r, "unprotect", args[0]);
1595 a(r, "set", args[0]);
1596 a(r, "save", args[0]);
1597 a(r, "db", args[0]);
1598 a(r, "leaderboard", args[0]);
1599 a(r, "reload", args[0]);
1600 a(r, "gift", args[0]);
1601 } else {
1602 if (args[0].equalsIgnoreCase("stats") || args[0].equalsIgnoreCase("breed")
1603 || args[0].equalsIgnoreCase("summon") || args[0].equalsIgnoreCase("allowbreeding")
1604 || args[0].equalsIgnoreCase("kill")) {
1605 for (RPGHorse h : ownedHorses.get(sender.getName())) {
1606 a(r, h.name, args[1]);
1607 }
1608 }
1609 if (args[0].equalsIgnoreCase("addxp") || args[0].equalsIgnoreCase("delxp")) {
1610 if (args.length == 2) {
1611 a(r, "agility", args[1]);
1612 a(r, "swiftness", args[1]);
1613 a(r, "vitality", args[1]);
1614 a(r, "wrath", args[1]);
1615 }
1616 if (args.length == 3) {
1617 a(r, "1", args[2]);
1618 }
1619 if (args.length == 4) {
1620 for (RPGHorse h : ownedHorses.get(sender.getName())) {
1621 a(r, h.name, args[3]);
1622 }
1623 }
1624
1625 }
1626 }
1627 return r;
1628 }
1629
1630 public void a(List<String> l, String s, String arg) {
1631 if (s.toLowerCase().startsWith(arg.toLowerCase()))
1632 l.add(s.replaceAll(" ", "_"));
1633 }
1634
1635 @Override
1636 public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
1637 if (args.length == 0) {
1638 showHelp(sender, args);
1639 return true;
1640 }
1641
1642 String hCmd = args[0].toLowerCase();
1643 String subcmd = "";
1644 if (args.length >= 2)
1645 subcmd = args[1].toLowerCase();
1646
1647 switch (hCmd) {
1648 case "help":
1649 showHelp(sender, args);
1650 return true;
1651 case "me":
1652 showMe(sender);
1653 return true;
1654 case "info":
1655 case "stats":
1656 case "horse":
1657 showHorse(sender, args);
1658 return true;
1659 case "shop":
1660 shop.openInventory(sender);
1661 return true;
1662 case "swiftness":
1663 case "agility":
1664 case "vitality":
1665 case "wrath":
1666 showSkill(sender, hCmd, args);
1667 return true;
1668 case "claim":
1669 claimHorse(sender);
1670 return true;
1671 case "buy":
1672 case "accept":
1673 buyHorse(sender, true);
1674 return true;
1675 case "deny":
1676 case "decline":
1677 buyHorse(sender, false);
1678 return true;
1679 case "sell":
1680 sellHorse(sender, args);
1681 return true;
1682 case "leaderboard":
1683 showLeaderBoard(sender, args);
1684 return true;
1685 case "spawn":
1686 case "s":
1687 case "summon":
1688 summonHorse(sender, args);
1689 return true;
1690 case "b":
1691 case "banish":
1692 banishHorse(sender);
1693 return true;
1694 case "addxp":
1695 case "delxp":
1696 addHorseXP(sender, args);
1697 return true;
1698 case "lock":
1699 case "protect":
1700 protectHorse(sender, args, true);
1701 return true;
1702 case "unlock":
1703 case "unprotect":
1704 protectHorse(sender, args, false);
1705 return true;
1706 case "save":
1707 saveHorses(sender);
1708 return true;
1709 case "gift":
1710 case "create":
1711 createHorse(sender, args, hCmd.equals("gift"));
1712 return true;
1713 case "allowbreeding":
1714 allowBreeding(sender, args);
1715 return true;
1716 case "delete":
1717 case "kill":
1718 case "remove":
1719 deleteHorse(sender, args);
1720 return true;
1721 case "set":
1722 switch (subcmd) {
1723 case "name":
1724 setHorseName(sender, args);
1725 return true;
1726 case "type":
1727 setHorseVariant(sender, args);
1728 return true;
1729 case "color":
1730 setHorseColor(sender, args);
1731 return true;
1732 case "style":
1733 setHorseStyle(sender, args);
1734 return true;
1735 default:
1736 showSetHelp(sender);
1737 return true;
1738 }
1739 case "db":
1740 case "data":
1741 case "database":
1742 loadDatabase(sender);
1743 return true;
1744 case "reload":
1745 reloadPlugin(sender);
1746 return true;
1747 default:
1748 msg(sender, INVALID_COMMAND);
1749 return true;
1750 }
1751 }
1752
1753 @Override
1754 public void onDisable() {
1755 // Force save all spawned horses.
1756 for (RPGHorse h : hSpawnedHorses.values())
1757 h_config.saveHorse(h, false);
1758 h_config.save();
1759
1760 if (banishondisable)
1761 for (Entity horse : hSpawnedHorses.keySet()) {
1762 hSpawnedHorses.remove(horse).banish();
1763 }
1764
1765 HandlerList.unregisterAll(this);
1766 saveHorses(null);
1767 saveTask.cancel();
1768 cooldownTask.cancel();
1769 }
1770
1771 /**
1772 * Displays the player's horse stats
1773 *
1774 * @param sender
1775 * is the sender to update
1776 */
1777 public static void showLeaderBoard(CommandSender sender, String[] args) {
1778 if (notAllowed(sender, H_LEADERBOARD, true))
1779 return;
1780
1781 Player p = (Player) sender;
1782 if (playersWithScoreboards.contains(p.getName())) {
1783 p.sendMessage(ChatColor.GREEN + "Already showing a scoreboard-menu.");
1784 return;
1785 }
1786
1787 NavigableMap<RPGHorse, Integer> map = new TreeMap<RPGHorse, Integer>(Collections.reverseOrder());
1788 for (TreeSet<RPGHorse> hor : ownedHorses.values()) {
1789 for (RPGHorse h : hor) {
1790 map.put(h, Integer.MAX_VALUE - h.agility.xp - h.wrath.xp - h.vitality.xp - h.swiftness.xp);
1791 }
1792 }
1793
1794 ScoreboardManager manager = Bukkit.getScoreboardManager();
1795 Scoreboard board = manager.getNewScoreboard();
1796
1797 Objective obj = board.registerNewObjective("leaderboard", "dummy");
1798 obj.setDisplaySlot(DisplaySlot.SIDEBAR);
1799 obj.setDisplayName(ChatColor.YELLOW + "Leaderboard");
1800 sender.sendMessage(ChatColor.YELLOW + "Leaderboard");
1801
1802 int index = 0;
1803 for (RPGHorse h : map.descendingKeySet()) {
1804 String k = ChatColor.GREEN + "#" + index + " " + h.name.substring(0, Math.min(h.name.length(), 16));
1805 String plaeyerName = h.owner.substring(0, Math.min(29 - k.length(), h.owner.length()));
1806 k = k + ChatColor.WHITE + " " + plaeyerName;
1807 try {
1808 obj.getScore(k).setScore(20 - index);
1809 } catch (Exception e) {
1810 obj.getScore(Bukkit.getOfflinePlayer(k)).setScore(20 - index);
1811 }
1812 sender.sendMessage(k + " = " + (h.agility.level + h.wrath.level + h.vitality.level + h.swiftness.level));
1813 index++;
1814 if (index >= 20)
1815 break;
1816 }
1817
1818 Scoreboard oldsb = p.getScoreboard();
1819 p.setScoreboard(board);
1820 playersWithScoreboards.add(p.getName());
1821
1822 Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(instance, new ScoreboardTask(p, oldsb), 200);
1823 }
1824
1825}