From e7e974c6190b22d72b03ca7689936c9c2053359e Mon Sep 17 00:00:00 2001 From: Eredrim Date: Mon, 20 Apr 2020 19:44:21 +0200 Subject: [PATCH 01/43] v1.15 - update maven dependency and pass to java 8 --- lang/lang_ru.yml | 828 +++++++++--------- pom.xml | 18 +- .../slipcor/pvparena/commands/PAA_Set.java | 15 +- src/net/slipcor/pvparena/core/ColorUtils.java | 31 +- src/net/slipcor/pvparena/core/Config.java | 39 +- .../pvparena/goals/GoalBlockDestroy.java | 5 +- .../pvparena/goals/GoalCheckPoints.java | 5 +- .../pvparena/goals/GoalDomination.java | 5 +- src/net/slipcor/pvparena/goals/GoalFlags.java | 5 +- .../slipcor/pvparena/goals/GoalInfect.java | 4 +- .../pvparena/goals/GoalLiberation.java | 4 +- .../pvparena/goals/GoalPhysicalFlags.java | 5 +- .../pvparena/goals/GoalPlayerLives.java | 4 +- src/net/slipcor/pvparena/goals/GoalTank.java | 4 +- .../slipcor/pvparena/goals/GoalTeamLives.java | 4 +- 15 files changed, 488 insertions(+), 488 deletions(-) diff --git a/lang/lang_ru.yml b/lang/lang_ru.yml index c46510f6d..1d3f3cc12 100644 --- a/lang/lang_ru.yml +++ b/lang/lang_ru.yml @@ -1,526 +1,526 @@ nulang: announce: - arena: ! /pa %1% ! + arena: Игра началась! Введите /pa %1% чтобы присоединиться! arena: create: - done: '%1%' ! + done: Арена '%1%' создана! disable: - done: ! + done: Арена выключена! edit: - disabled: ' : %1%' - enabled: ' : %1%' + disabled: 'Режим редактирование выключен: %1%' + enabled: 'Режим редактирования включён: %1%' enable: - done: ! - arenalist: ' : &a%1%&r' - regionshapeunknown: ' ''%1%'' . : http://goo.gl/IfLOh' + done: Арена включена! + arenalist: 'Список карт: &a%1%&r' + regionshapeunknown: 'Тип региона ''%1%'' неизвестен. проконсультируйтесь на: http://goo.gl/IfLOh' reload: - done: ! + done: Арена перезагружена! remove: - done: ' : &e%1%&r' - startingin: - . %1%! + done: 'Арена удалена: &e%1%&r' + startingin: Достаточное кол-во игроков готово. Начало через %1%! start: - done: ! + done: Игра принудительно начата! stop: - done: ! + done: Игра принудительно выключена! autosetup: - automanual: &a%1%&r &a%2%&r? - automatic: - manual: - modeselected: '&a%1%&r !' - welcome: ' PVP Arena! + automanual: Хотите ли вы воспользоваться мастером установки для &a%1%&r или &a%2%&r? + automatic: автоматически + manual: инструкция + modeselected: '&a%1%&r тип игры выбран!' + welcome: 'Добро пожаловать в мастер установки PVP Arena! - . !' + Пожалуйста введите ответы в чат. Никаких комманд не нужно!' blacklist: added: Added &a%1%&r to &e%2%&r blacklist! - allcleared: ! - cleared: ׸ &e%1%&r ! - help: ': blacklist clear | blacklist [type] [clear|add|remove] [id]' - removed: &a%1%&r &e%2%&r ! - show: '׸ &e%1%&r:' + allcleared: Все чёрные списки очищены! + cleared: Чёрный лист &e%1%&r очищен! + help: 'Используйте: blacklist clear | blacklist [type] [clear|add|remove] [id]' + removed: Удаление &a%1%&r из &e%2%&r чёрного списка! + show: 'Чёрный лист &e%1%&r:' check: - done: ! ! + done: Проверка завершена! Ошибок нет! class: preview: You are now previewing the class %1% - removed: ' : %1%' - saved: ' : %1%' - selected: &e%1%&e + removed: 'Класс удалён: %1%' + saved: 'Класс сохранён: %1%' + selected: Вы выбрали класс &e%1%&e deathcause: - BLOCK_EXPLOSION: - CONTACT: - CUSTOM: - DROWNING: - ENTITY_EXPLOSION: - FALL: - FIRE_TICK: - FIRE: - LAVA: - LIGHTNING: - MAGIC: - POISON: - PROJECTILE: - STARVATION: + BLOCK_EXPLOSION: взрыва + CONTACT: кактуса + CUSTOM: Херобрина + DROWNING: вода + ENTITY_EXPLOSION: взрыва + FALL: гравитации + FIRE_TICK: огня + FIRE: огня + LAVA: лавы + LIGHTNING: молнии + MAGIC: магических сил + POISON: зелья + PROJECTILE: того чего он не видел + STARVATION: голода SUFFOCATION: lack of air - SUICIDE: - VOID: - CREEPER: - SKELETON: - SPIDER: - GIANT: - ZOMBIE: - SLIME: - GHAST: - PIG_ZOMBIE: - - ENDERMAN: - CAVE_SPIDER: - SILVERFISH: - BLAZE: - MAGMA_CUBE: - ENDER_DRAGON: - - WITHER: - WITCH: - WOLF: - IRON_GOLEM: - SPLASH_POTION: + SUICIDE: себя + VOID: пустоты + CREEPER: крипера + SKELETON: скелета + SPIDER: паука + GIANT: гиганта + ZOMBIE: зомби + SLIME: слизня + GHAST: гаста + PIG_ZOMBIE: свино-зомби + ENDERMAN: эндермена + CAVE_SPIDER: пещерного паука + SILVERFISH: чешуйницы + BLAZE: блейза + MAGMA_CUBE: огненного слизня + ENDER_DRAGON: эндер-дракона + WITHER: визера + WITCH: ведьмы + WOLF: волка + IRON_GOLEM: железного голема + SPLASH_POTION: взрывного зелья error: arena: - alreadyplaying: &a%1%&r - arenaexists: ! - arenanotexists: ' : %1%' - arenaconfig: ' : %1%' - argumenttype: '&c :&r &e%1%&r &a%2%&r' - argument: '&c :&r %1% - : &a%2%&r' + alreadyplaying: Вы уже присоеденены к &a%1%&r + arenaexists: Арена с таким именем уже существует! + arenanotexists: 'Арены с таким именем не существует: %1%' + arenaconfig: 'Ошибка при загрузке конфигурации арены: %1%' + argumenttype: '&cНеверный аргумент:&r &e%1%&r нет нужного &a%2%&r' + argument: '&cАргумент неверен:&r %1% - возможные аргументы: &a%2%&r' autosetup: - running: ' ! : %1%' + running: 'Здесь уже запущен мастер установки! Игрок: %1%' blacklist: - disallowed: %1% ! ! - unknownsubcommand: ' . : &a%1%&r' - unknowntype: ' . : &e%1%&r' + disallowed: Вы не можете %1% это! В чёрном списке! + unknownsubcommand: 'Неизвестная подкоманда. Возможные команды: &a%1%&r' + unknowntype: 'Неизвестный тип. Возможные типы: &e%1%&r' class: - full: &a%1%&r ! - notenoughexp: - , &a%1%&r! - notfound: ' : &a%1%&r' - cmdblocked: '&c : %1%' - invalidcmd: (%1%) - unknowncmd: - arenadisabled: , ! - error: '&c: %1%' - fightinprogress: ! + full: Класс &a%1%&r переполнен! + notenoughexp: У вас нет достаточного кол-ва опыта, чтобы выбрать &a%1%&r! + notfound: 'Класс не найден: &a%1%&r' + cmdblocked: '&cКомманда заблокирована: %1%' + invalidcmd: Неверная команда (%1%) + unknowncmd: Неизвестная команда + arenadisabled: Игра выключена, пожалуйста попробуйте позже! + error: '&cОшибка: %1%' + fightinprogress: Игра уже идёт! goal: - legacyunknown: ' &a%1%&r ! : &a/pa - [_] goal [_]' - goalnotfound: ' &a%1%&r . : &a%2%&r' - install: &a%1%&r - invalid_argument_count: '&c - &r (%1% %2%)!' - invalidstattype: ' : %1%' - valuenotfound: ' : &a%1%&r!' - invfull: . ! - arenafull: ! - joinrange: , ! - notjoinregion: ! , ! - teamfull: %1% ! - insidevehicle: , ! - errorloungefree: ! "FreeForAll". '[_]lounge' + legacyunknown: 'Наследник цели &a%1%&r неизвестен! Возможно вы хотели добавить цель: &a/pa + [Название_арены] goal [название_цели]' + goalnotfound: 'Цель &a%1%&r неизвестна. Возможные цели: &a%2%&r' + install: Ошибка при установке &a%1%&r + invalid_argument_count: '&cНеверное кол-во аргументов&r (%1% вместо %2%)!' + invalidstattype: 'Неверный тип статистики: %1%' + valuenotfound: 'Неверное значание: &a%1%&r!' + invfull: Ваш инвентарь переполнен. Вы не получили все награды! + arenafull: Арена переполнена! + joinrange: Вы слишком далеко, чтобы присоединиться к арене! + notjoinregion: Вы не находитесь в регионе присоединения! Идите сюда, чтобы присоединиться! + teamfull: команда %1% переполнена! + insidevehicle: Вы не можете присоединиться, пока вы на транспорте! + errorloungefree: Ошибка! Тип арены не "FreeForAll". Используйте '[название_команды]lounge' log: - matnotfound: ' : %1%' - missingspawn: ' : &f%1%' - noarenas: ! - valueneg: ' : &c%1%&r' - nofight: . - nogoal: ! &a/pa [_] [ ] - classperms: &a%1%&r - permjoin: ! - noperm: '&c %1%' - noplayerfound: ! - notinarena: ! - notnumeric: '&c :&r %1%' + matnotfound: 'Неверный материал: %1%' + missingspawn: 'Точка спавна потерена: &f%1%' + noarenas: Арены не найдены! + valueneg: 'Отрицательные значения: &c%1%&r' + nofight: Ни одна из игр не запущена. + nogoal: Вы не добавили цели на арену! &a/pa [Название_арены] цель [название цели] + classperms: У вас нет прав для исользования класса &a%1%&r + permjoin: У вас нет прав для игры на этой арене! + noperm: '&cНет прав для %1%' + noplayerfound: Игрок не найден! + notinarena: Вы не находитесь на арене! + notnumeric: '&cАргумент не является числом:&r %1%' notsameworld: Not in the same world as the arena (%1%)! - noteamfound: ! - onlyplayers: '&c !' - playernotfound: '&c : &f%1%&c!' - positives: ' : &b%1%&r' - potioneffecttypenotfound: ' : &e%1%&r' + noteamfound: Команда не найдена! + onlyplayers: '&cЭто команда может быть использована только игроками!' + playernotfound: '&cИгрок не найден: &f%1%&c!' + positives: 'Положительные значения: &b%1%&r' + potioneffecttypenotfound: 'Эффект зелья не найден: &e%1%&r' ready: - notready0: ! - notready1: ! - notready2: ! - notready3: ! - notready4: ! - notready5: ! - noclass: ! - error: ! %1% + notready0: Последний игрок не готов! + notready1: Вы один на арене! + notready2: Ваша команда одна на арене! + notready3: Команда потеряла игрока! + notready4: Арена потеряла игрока! + notready5: Один игрок не выбрал класс! + noclass: Вы не выбрали класс! + error: Игра не готова! %1% region: - beingcreated: ' : %1%' - flagnotfound: ' &a%1%&r ! : %2%' - notfound: &a%1%&r ! - protectionnotfound: &a%1%&r ! - typenotfound: ' &a%1%&r ! : %2%' - youselect: ! - youselect2: , ! - youselectexit: ! - regionnotbeingcreated: ! - regionnotremoved: . - select2: 2 . + beingcreated: 'Регион уже создан: %1%' + flagnotfound: 'Флаг региона &a%1%&r неизвестен! Возможные значения: %2%' + notfound: Регион &a%1%&r не найден! + protectionnotfound: Защищённый регион &a%1%&r неизвестен! + typenotfound: 'Тип региона &a%1%&r Неизвестен! Возможные значения: %2%' + youselect: Вы уже выбрали регион для этой арены! + youselect2: Введите команду заного, чтобы выйти из режима создания регионов! + youselectexit: Режим создания регионов выключен! + regionnotbeingcreated: Регион не был создан! + regionnotremoved: Регион не был удалён. + select2: Выбирете 2 точки перед сохранением. spawn: - unknown: ' : &a%1%&r' - spawnfree: ! "FreeForAll". 'spawnX' X ! - statsfile: ! - teamnotfound: ' : &a%1%&r' - uninstall: &a%1%&r - unknownmodule: ' : %1%' + unknown: 'Неизвестная точка возрождения: &a%1%&r' + spawnfree: Ошибка! Тип арены "FreeForAll". Используйте 'spawnX' где X цифра или буква! + statsfile: Ошибка при считовании! + teamnotfound: 'Команда не найдена: &a%1%&r' + uninstall: Ошибка при удалении &a%1%&r + unknownmodule: 'Модуль не найден: %1%' whitelist: disallowed: You may not %1% this! (not whitelisted) - unknownsubcommand: ' . : &a%1%&r' - unknowntype: ' . : &e%1%&r' + unknownsubcommand: 'Неизвестная подкоманда. Возможные команды: &a%1%&r' + unknowntype: 'Неизвестный вид. Доступные виды: &e%1%&r' nopermto: - madmin: - create: - disable: - edit: - enable: - nopermjoin: - reload: - remove: - set: - setup: - teleport: - user: PVP Arena + madmin: администрировать + create: создать арену + disable: выключить + edit: редактировать арену + enable: включить + nopermjoin: присоединиться к арене + reload: перезапуск + remove: удалить арену + set: выбрать файл конфигурации + setup: настроить арену + teleport: телепортация на точку возраждения арены + user: использовать PVP Arena fight: - begins: ! - draw: ! ! - killedbyremaining: '%1% %2%! %3% .' - killedbyremainingfrags: '%1% %2%! %3% .' - killedbyremainingteam: '%1% %2%! %3% %4%.' - killedbyremainingteamfrags: '%1% %2%! %3% + begins: Пускай бой начнётся! + draw: Этот матч закончился ничьей! Победителей нет! + killedbyremaining: '%1% был убит %2%! %3% жизней осталось.' + killedbyremainingfrags: '%1% был убит %2%! %3% убийств осталось.' + killedbyremainingteam: '%1% был убит %2%! %3% жизней осталось для %4%.' + killedbyremainingteamfrags: '%1% был убит %2%! %3% убийств осталось до %4%.' - killedby: '%1% %2%!' - playerleft: '%1% !' - forcestop: . + killedby: '%1% был убит %2%!' + playerleft: '%1% вышел из боя!' + forcestop: Вы принудительно остановили игру. gamemode: - free: &afree for all&r &a%1%&r! - team: &ateam&r &a%1%&r! + free: Игровой режим &afree for all&r выставлен для арены &a%1%&r! + team: Игровой режим &ateam&r выставлен для арены &a%1%&r! general: - break: - place: - use: + break: сломать + place: поставить + use: использовать goal: - added: ' : &a%1%&r' - installing: ' : &a/pa install [goalname]&r' - removed: ' : &a%1%&r' + added: 'Цель создана: &a%1%&r' + installing: 'Установите цели командой: &a/pa install [goalname]&r' + removed: 'Цель удалена: &a%1%&r' blockdestroy: - typeset: ' : &e%1%' - setflag: ' : %1%' - tosetflag: ' : %1%' + typeset: 'Тип блока заменён на: &e%1%' + setflag: 'Блок выбран: %1%' + tosetflag: 'Блок для выбора: %1%' dom: - claiming: '&e %1% !' - claimed: '&e %1% !' - score: '&e %1% %2% !' - unclaiming: '&e %1% !' - unclaimingby: '&e %1% %2%!' + claiming: '&eКоманда %1% захватывает флаг!' + claimed: '&eКоманда %1% захватила флаг!' + score: '&eКоманда %1% получает %2% очков за удержание флага!' + unclaiming: '&eФлаг захваченый командой %1% захватывается другой командой!' + unclaimingby: '&eФлаг захваченый командой %1% перезахвачен командой %2%!' infected: - lost: '&6 !' - player: '&c%1% !' - you: '&c !' - won: '&6 !' + lost: '&6Заражённые игроки были убиты!' + player: '&c%1% заражён!' + you: '&cВы заражены!' + won: '&6Заражённые игроки победили в игре!' killreward: - added: ' : &e%1%&f->&a%2%' - removed: ' : &e%1%' + added: 'Награда за убийство добавлена: &e%1%&f->&a%2%' + removed: 'Награда за убийство удалена: &e%1%' liberation: - liberated: %1% ! - setbutton: ' : %1%' - tosetbutton: ' : %1%' + liberated: Команда %1% была освобождена! + setbutton: 'Кнопка выбрана: %1%' + tosetbutton: 'Кнопка для выбора: %1%' physicalflags: - holdflag: , ! + holdflag: Вы захватили флаг, верните его к себе на базу! sabotage: - tntignite: '%1% TNT %2%!' - set: 'TNT : %1%' - toset: 'TNT : %1%' - youtnt: TNT !' + tntignite: '%1% подожгли TNT команды %2%!' + set: 'TNT выбрана: %1%' + toset: 'TNT для выбора: %1%' + youtnt: У вас есть TNT для сабботажа!' tank: - tankdown: ! - tankmode: ! %1%, ! - tankwon: ! %1%! + tankdown: Танк убит! + tankmode: Режим танка! Все должны убить %1%, он танк! + tankwon: Танк победил! Поздравляем %1%! pillars: msg: - block_broken: '[%1%] %2% !' - lower: '[%1%] %2% !' - block_placed: '[%1%] %2% !' - higher: '[%1%] %2% !' - claimed: '[%1%] %2% !' - unclaimed: '[%1%] %2% !' - score: '%1% %2% ' + block_broken: '[%1%] %2% сломал блок!' + lower: '[%1%] %2% укоротил колонну!' + block_placed: '[%1%] %2% поставил блок!' + higher: '[%1%] %2% удлинил колону!' + claimed: '[%1%] %2% захватил колонну!' + unclaimed: '[%1%] %2% перехватил колонну!' + score: '%1% получают %2% очков' help: - head: '&e--- &aPVP Arena &e %1% &e---' - admin: '&c%1% - ' - setup: '&e%1% - ' - custom: '&e%1% - ' - game: '&a%1% - ' - info: '&9%1% - ' + head: '&e--- &aPVP Arena помощь&e %1% &e---' + admin: '&c%1% - помощь администрации' + setup: '&e%1% - помощь в создании' + custom: '&e%1% - помощь в настройке' + game: '&a%1% - помощь в игре' + info: '&9%1% - помощь в получении информации' import: - done: &e%1%&r! + done: Удачный импорт арены &e%1%&r! info: - classes: ': &a%1%&r' - goal_active: ': &a%1%&r' - goal_inactive: ': &b%1%&r &7== ==' - head_headlin: ' : &a%1%&r | [&a%2%&r]' - head_teams: ': &a%1%&r' - mod_active: ': &a%1%&r' - mod_inactive: ': &b%1%&r &7== ==' - owner: ': &a%1%&r' - regions: ': &a%1%&r' + classes: 'классы: &a%1%&r' + goal_active: 'Цель: &a%1%&r' + goal_inactive: 'Цель: &b%1%&r &7== неактивная ==' + head_headlin: 'Информация об арене: &a%1%&r | [&a%2%&r]' + head_teams: 'Команды: &a%1%&r' + mod_active: 'Модули: &a%1%&r' + mod_inactive: 'Модули: &b%1%&r &7== неактивная ==' + owner: 'Владельцы: &a%1%&r' + regions: 'Регионы: &a%1%&r' section: '----- &a%1%&r -----' install: - installed: ': &a%1%&r' + installed: 'установлены: &a%1%&r' list: - arenas: ' : %1%' - dead: '̸: %1%' - fighting: ': %1%' - lost: ': %1%' - lounge: ': %1%' - 'null': ': %1%' - players: ': %1%' - team: ' %1%: %2%' - ready: ': %1%' - warm: ': %1%' - watching: ': %1%' + arenas: 'Доступные арены: %1%' + dead: 'Мёртвые: %1%' + fighting: 'Сражающиеся: %1%' + lost: 'Потерянные: %1%' + lounge: 'Лобби: %1%' + 'null': 'Зависшие: %1%' + players: 'Игроки: %1%' + team: 'Команды %1%: %2%' + ready: 'Готовы: %1%' + warm: 'Ожидающие: %1%' + watching: 'Зрители: %1%' log: - plugindisabled: ( %1%) - pluginenabled: ( %1%) - trickerdisabled: . ? - trackingenabled: ' . : false .' - updatedisabled: . dev.bukkit . - updateenabled: ... + plugindisabled: выключен (версия %1%) + pluginenabled: включён (версия %1%) + trickerdisabled: Диагностика плагина выключена. Увидимся позже? + trackingenabled: 'Диагностика плагина включена. Выбор диагностики: false в главном файле конфигурации для выключения.' + updatedisabled: Обновление выключено. Пожалуйста проверьте dev.bukkit для обновления. + updateenabled: Проверка на наличие обновлений... warning: '%1%' messages: - toArena: ! - toPublic: ! - toTeam: ! - noplayer: PVP arena. + toArena: Теперь вы говорите внутри арены! + toPublic: Теперь вы говорите со всеми! + toTeam: Теперь вы разговариваете с вашей командой! + noplayer: Нет игроков в PVP arena. notice: - awarded: %1% - nodropitem: ! ! - noteleport: '/pa leave' ! - notice: ': %1%' - playerawarded: '%1% %2%' - remove: '&c &a%1%&c. ? - !&f , ''safeadmin'' + awarded: Вы были награждены %1% + nodropitem: Не так быстро! Не читерить! + noteleport: Пожалуйста используйте '/pa leave' для выхода из игры! + notice: 'Внимание: %1%' + playerawarded: '%1% был награждён %2%' + remove: '&cЭто навсегда удалит вашу арену &a%1%&c. Вы уверены? Тогда + введите команду ещё раз!&f Чтобы выключить это сообщение, посмотрите ''safeadmin'' в вашем config.yml' - waitingequal: ! - waitingforarena: , ! - welcomespec: ! - welcomespec2: /pa bet [] [] ! - youdeath: . ;)! - youescaped: . ;)! - youleft: ! - younocamp: . ! - playerhaswon: '%1% !' - playerready: '%1%&e !' - notreadyplayers: - players: + waitingequal: Ждём пока в командах будет минимальное число игроков! + waitingforarena: Ожидайте, пока игра завершится! + welcomespec: Добро пожаловать в зал зрителей! + welcomespec2: /pa bet [имя] [цена] сделать ставку на игрока или команду! + youdeath: Вы вошли в регион смерти. Пока ;)! + youescaped: Вы ушли с поля боя. Пока ;)! + youleft: Вы вышли из игры! + younocamp: Вы в некемперском регионе. Двигайтесь! + playerhaswon: '%1% победитель!' + playerready: '%1%&e готов!' + notreadyplayers: Игроки не готовы + players: Игроки ready: - list: ': %1%' - done: ! + list: 'Игроки: %1%' + done: Вы уже готовы! region: flag: - added: ' : &a%1%&r' - removed: ' : &a%1%&r' - height: ' : &a%1%&r' - pos1: . - pos2: . - protection_added: ' : &a%1%&r' - protection_removed: ' : &a%1%&r' - radius: ' : &a%1%&r' - removed: ' : %1%' - saved: . - select: 2 , ! - setting: . - typeset: ' : &e%1%' - youselect: &a%1%&r! + added: 'Флаг региона добавлен: &a%1%&r' + removed: 'Флаг региона удалён: &a%1%&r' + height: 'Высота региона установлена на: &a%1%&r' + pos1: Первая точка выбрана. + pos2: Вторая точка выбрана. + protection_added: 'Защита региона создана: &a%1%&r' + protection_removed: 'Защита региона удалена: &a%1%&r' + radius: 'Радиус региона: &a%1%&r' + removed: 'Регион удалён: %1%' + saved: Регион сохранён. + select: Выбирете 2 точки палочкой, сначала левой кнопкой мышки и потом правой! + setting: Найстройка региона включена. + typeset: 'Тип региона выбран: &e%1%' + youselect: Теперь вы выбираете регион для карты &a%1%&r! regions: - flags: ' : &a%1%&r' - head: '--- &a &r [&e%1%&r]---' - listhead: '--- &a &r [&e%1%&r]---' + flags: 'Флаги региона: &a%1%&r' + head: '--- &aРегион арены&r [&e%1%&r]---' + listhead: '--- &aРегионы арены&r [&e%1%&r]---' listvalue: '&a%1%&r: %2%, %3%' - protections: ' : &a%1%&r' - shape: ' : &a%1%&r' - type: ' : &a%1%&r' - reloaded: ! + protections: 'Защиты региона: &a%1%&r' + shape: 'Форма региона: &a%1%&r' + type: 'Тип региона: &a%1%&r' + reloaded: Конфигурация региона! round: - display: ' #%1%/%2%' - added: ' : &e%1%' - removed: ' : &e%1%' + display: 'Раунд #%1%/%2%' + added: 'Добавлена цель раунда: &e%1%' + removed: 'Удалена цель раунда: &e%1%' set: done: '&a%1%&r set to &e%2%&r!' - help: /pa {arenaname} set [] - unknown: ' : &e%1%&r!' + help: Используйте /pa {arenaname} set [страница] для получение инструкций + unknown: 'Неизестная страница: &e%1%&r!' setowner: - done: '&a%1%&r &a%2%&r!' + done: '&a%1%&r теперь владелец арены &a%2%&r!' spawn: - freelounge: - teamlounge: ' : %1%' - notset: ' : &a%1%&r' - removed: ' : &a%1%&r' - set: ' : &a%1%&r' - setdone: ' : &a%1%&r' - setstart: ' : &a%1%&r' + freelounge: Лобби выставлено + teamlounge: 'Лобби выставлено: %1%' + notset: 'Точка возраждения не указана: &a%1%&r' + removed: 'Точка возраждения удалена: &a%1%&r' + set: 'Точка возраждения указана: &a%1%&r' + setdone: 'Точка возраждения удачно выставлена: &a%1%&r' + setstart: 'Настройка точки возраждения начата: &a%1%&r' stats: - filedone: ! - head: %1% (%2%) - typenotfound: ' ! : &e%1%&r' + filedone: Файл статичтики загружен! + head: Статистика ТОП %1% (%2%) + typenotfound: 'Тип статистики не найден! Доступные значения: &e%1%&r' stattype: - DAMAGE: - DAMAGETAKE: - DEATHS: - KILLS: - LOSSES: - MAXDAMAGE: - MAXDAMAGETAKE: - 'NULL': - WINS: + DAMAGE: полный наносимый урон + DAMAGETAKE: полный забираемый урон + DEATHS: смерти + KILLS: убийства + LOSSES: матчей проиграно + MAXDAMAGE: максимальный урон + MAXDAMAGETAKE: максимальный нанесённый урон + 'NULL': имя игрока + WINS: матчей выиграно team: - haswon: '%1% !' - ready: '%1% !' + haswon: '%1% Чемпионы!' + ready: '%1% готовы!' teams: - list: ' : %1%' - add: ' : %1%' - set: ' : %1%' - remove: ' : %1%' + list: 'Доступные команды: %1%' + add: 'Команда создана: %1%' + set: 'Команда выбрана: %1%' + remove: 'Команда удалена: %1%' time: - minutes: - seconds: + minutes: минут + seconds: секунд timer: - countdowninterrupt: interrupted! ! - ending: %1%! - resetting: %1%! - starting: %1%! + countdowninterrupt: Таймер interrupted! Ударьте железный блок для готовности! + ending: Матч закончится через %1%! + resetting: Арена будет перезапущена через %1%! + starting: Начало через %1%! warmingup: Warming up... %1%! - pvpactivating: %1%! - walls: %1%! + pvpactivating: ПвП будет включен через %1%! + walls: Стены будут убраны через %1%! uninstall: - done: ': &a%1%&r' + done: 'Удалено: &a%1%&r' whitelist: - added: &a%1%&r &e%2%&r ! - allcleared: ! - cleared: &e%1%&r ! - help: ': blacklist clear | blacklist [type] [clear|add|remove] [id]' + added: Добавление &a%1%&r в &e%2%&r вайтлист! + allcleared: Все вайтлисты очищены! + cleared: Вайтлист &e%1%&r очищен! + help: 'Используйте: blacklist clear | blacklist [type] [clear|add|remove] [id]' removed: Removed &a%1%&r from &e%2%&r whitelist! show: 'Whitelist &e%1%&r:' mod: aftermatch: - aftermatch: AfterMatch ! - startingin: AfterMatch %1%! - spawnnotset: 'after' ! + aftermatch: AfterMatch начинается! + startingin: AfterMatch через %1%! + spawnnotset: Точка возраждения 'after' не установлена! announcements: - ignoreon: ! - ignoreoff: ! + ignoreon: Теперь вы игнорируете оповещения! + ignoreoff: Теперь вы получаете оповещения! arenaboards: - createarenaboard: - arenaboarddestroyed: ! - boardexists: !' - sortingby: %1% + createarenaboard: создать Границу Арены + arenaboarddestroyed: Граница арены уничтожена! + boardexists: Граница арены с таким именем уже существует!' + sortingby: Граница арены теперь сортируется через %1% autovote: - arenarunning: ' : %1%' - autojoin: ! - playervoted: '%2% %1%!' - youvoted: %1%! + arenarunning: 'Игра запущена: %1%' + autojoin: Авто присоединение к игре началось! + playervoted: '%2% проголосовал за %1%!' + youvoted: Вы проголосовали за %1%! duel: - accepted: '%1% &e ! .' - announce: '%1% &e ! &f/pa %2% accept.' - starting: ! + accepted: '%1% &eсогласился на дуель! Дуедь начинается.' + announce: '%1% &eвызывает вас на дуель! Принять вызов &f/pa %2% accept.' + starting: Дуель начинается! fixinventorylos: - gamemode: ! - invenory: ! + gamemode: Смена игрового режима перед присоединением! + invenory: Очистка инвентаря перед присоединением! latelounge: - llannounce: %1% ! , %2%. /pa %1% - llposition: %1%! - llrejoin: , . , ! - llwait: , ! + llannounce: Игра на карте %1% начинается! Игроков,которые хотят начат играть %2%. Присоединиться /pa %1% + llposition: Ваше место в очереди %1%! + llrejoin: Проверка готовности говорит,что вы не смогли подключится к игре. Переподсоединитесь, когда сможете! + llwait: Игра скоро начнётся, пожалуйста подождите! playerfinder: - near: ' %1% !' - point: ! + near: 'Ближайщий игрок от вас в %1% блоках!' + point: Компас указывает позицию ближайшего игрока! powerups: - invalidpowerupeffect: ' : %1%' - puplayer: '%1% %2%!' - puserver: ! + invalidpowerupeffect: 'Неверный эффект повышения: %1%' + puplayer: '%1% достиг повышения %2%!' + puserver: Понижение! skins: - dc: DisguiseCraft! - md: MobDisguise! - nomod: , ! - showclass: &e%1%&r &a%2% - showteam: %1% %2% + dc: Подключение в DisguiseCraft! + md: Подключение в MobDisguise! + nomod: Не найден плагин превращений, модуль скинов выключен! + showclass: Класс &e%1%&r будет превращён в &a%2% + showteam: Команда %1% будет превращёна в %2% specialjoin: - done: - %1% - start: ! - stop: ! + done: Блок готовности выбран тут - %1% + start: Выбор блока готовности! + stop: Отмена нажатия на блок готовности! startfreeze: - announce: %1% ! + announce: Игра начнётся через %1% секунд! tempperms: - noperms: , . - head: ' &e%1%&r:' - added: &e%1%&r &a%2%&r - removed: &e%1%&r &a%2%&r + noperms: Плагин прав не найден, по умалчанию доступно оперторам. + head: 'Временные права для &e%1%&r:' + added: Временные права &e%1%&r сделаны для &a%2%&r + removed: Временные права &e%1%&r удалены у &a%2%&r vault: 'on': <3 eConomy 'off': net.slipcor pvparena - 1.14.1-SNAPSHOT + 1.15.0-SNAPSHOT PVP Arena + https://github.com/Eredrim/pvparena + UTF-8 @@ -38,12 +40,6 @@ - http://pa.slipcor.net - - jenkins - https://ci2.craftyn.com - - clean package install pvparena-${project.version}${buildVersion} @@ -65,17 +61,17 @@ org.apache.maven.plugins maven-compiler-plugin - 2.3.2 + 3.8.1 - 1.7 - 1.7 + 8 + 8 UTF-8 org.apache.maven.plugins maven-jar-plugin - 2.3.2 + 3.2.0 org.apache.maven.plugins diff --git a/src/net/slipcor/pvparena/commands/PAA_Set.java b/src/net/slipcor/pvparena/commands/PAA_Set.java index 2d3b26541..bf4fdd49d 100644 --- a/src/net/slipcor/pvparena/commands/PAA_Set.java +++ b/src/net/slipcor/pvparena/commands/PAA_Set.java @@ -153,17 +153,15 @@ private void set(final CommandSender player, final Arena arena, final String nod Language.parse(arena, MSG.SET_DONE, node, String.valueOf(dValue))); } else if ("tp".equals(type)) { - if (!"exit".equals(value) && !"old".equals(value) - && !"spectator".equals(value)) { + if (!"exit".equals(value) && !"old".equals(value) && !"spectator".equals(value)) { arena.msg(player, Language.parse(arena, MSG.ERROR_ARGUMENT_TYPE, value, "tp (exit|old|spectator|...)")); return; } - arena.getArenaConfig().setManually(node, String.valueOf(value)); + arena.getArenaConfig().setManually(node, value); arena.msg( player, - Language.parse(arena, MSG.SET_DONE, node, - String.valueOf(value))); + Language.parse(arena, MSG.SET_DONE, node, value)); } else if ("material".equals(type)) { if ("hand".equals(value)) { if (player instanceof Player) { @@ -181,13 +179,10 @@ private void set(final CommandSender player, final Arena arena, final String nod } try { - final Material mat = Material.valueOf(value); + final Material mat = Material.valueOf(value.toUpperCase()); if (mat != Material.AIR) { arena.getArenaConfig().setManually(node, mat.name()); - arena.msg( - player, - Language.parse(arena, MSG.SET_DONE, node, - String.valueOf(mat.name()))); + arena.msg(player, Language.parse(arena, MSG.SET_DONE, node, mat.name())); } arena.getArenaConfig().save(); diff --git a/src/net/slipcor/pvparena/core/ColorUtils.java b/src/net/slipcor/pvparena/core/ColorUtils.java index f2f41887c..83a506ab0 100644 --- a/src/net/slipcor/pvparena/core/ColorUtils.java +++ b/src/net/slipcor/pvparena/core/ColorUtils.java @@ -6,6 +6,8 @@ import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; import static net.slipcor.pvparena.core.StringParser.joinArray; @@ -83,8 +85,7 @@ following colors are the sames (ignore): WHITE, YELLOW, BLACK * @return true if material can be colored */ public static boolean isColorableMaterial(Material type) { - return type.name().endsWith("_WOOL") || type.name().endsWith("_CONCRETE") || - type.name().endsWith("_STAINED_GLASS"); + return getColorableSuffixes().contains(getMaterialSuffix(type)); } /** @@ -101,15 +102,21 @@ public static Material getColoredMaterial(DyeColor dyeColor, Material typeMateri } public static boolean isSubType(Material type, Material check) { - if (type.name().endsWith("_WOOL") && check.name().endsWith("_WOOL")) { - return true; - } - if (type.name().endsWith("_CONCRETE") && check.name().endsWith("_CONCRETE")) { - return true; - } - if (type.name().endsWith("_STAINED_GLASS") && check.name().endsWith("_STAINED_GLASS")) { - return true; - } - return false; + return isColorableMaterial(type) && getMaterialSuffix(type).equals(getMaterialSuffix(check)); + } + + private static String getMaterialSuffix(Material material) { + return material.name().contains("_") ? material.name().split("_", 2)[1] : ""; + } + + /** + * Get the list of all colorable blocks + */ + private static List getColorableSuffixes() { + return Stream.of(Material.values()) + .filter(m -> m.name().startsWith("MAGENTA_")) + .filter(Material::isBlock) + .map(ColorUtils::getMaterialSuffix) + .collect(Collectors.toList()); } } diff --git a/src/net/slipcor/pvparena/core/Config.java b/src/net/slipcor/pvparena/core/Config.java index 117453acb..75b992920 100644 --- a/src/net/slipcor/pvparena/core/Config.java +++ b/src/net/slipcor/pvparena/core/Config.java @@ -77,17 +77,17 @@ public enum CFG { GENERAL_SMARTSPAWN("general.smartspawn", false, null), GENERAL_TIME("general.time", -1, null), GENERAL_TYPE("general.type", "none", null), - GENERAL_WAND("general.wand", Material.STICK.toString(), null), + GENERAL_WAND("general.wand", Material.STICK, null), GOAL_ADDLIVESPERPLAYER("goal.livesPerPlayer", false, null), - ITEMS_EXCLUDEFROMDROPS("items.excludeFromDrops", new ItemStack[0], true, null), - ITEMS_KEEPONRESPAWN("items.keepOnRespawn", new ItemStack[0], true, null), + ITEMS_EXCLUDEFROMDROPS("items.excludeFromDrops", new ItemStack[0], null), + ITEMS_KEEPONRESPAWN("items.keepOnRespawn", new ItemStack[0], null), ITEMS_KEEPALLONRESPAWN("items.keepAllOnRespawn", false, null), ITEMS_MINPLAYERS("items.minplayers", 2, null), ITEMS_RANDOM("items.random", true, null), - ITEMS_REWARDS("items.rewards", new ItemStack[0], true, null), - ITEMS_TAKEOUTOFGAME("items.takeOutOfGame", new ItemStack[0], true, null), + ITEMS_REWARDS("items.rewards", new ItemStack[0], null), + ITEMS_TAKEOUTOFGAME("items.takeOutOfGame", new ItemStack[0], null), JOIN_RANGE("join.range", 0, null), JOIN_FORCE("join.forceregionjoin", false, null), @@ -128,7 +128,7 @@ public enum CFG { PLAYER_HEALTH("player.health", -1, null), PLAYER_HEALFORKILL("player.healforkill", false, null), PLAYER_HUNGER("player.hunger", true, null), - PLAYER_ITEMSONKILL("player.itemsonkill", new ItemStack[0], true, null), + PLAYER_ITEMSONKILL("player.itemsonkill", new ItemStack[0], null), PLAYER_MAYCHANGEARMOR("player.mayChangeArmor", true, null), PLAYER_MAXHEALTH("player.maxhealth", -1, null), PLAYER_PREVENTDEATH("player.preventDeath", true, null), @@ -144,7 +144,7 @@ public enum CFG { PROTECT_SPAWN("protection.spawn", 0, null), READY_AUTOCLASS("ready.autoClass", "none", null), - READY_BLOCK("ready.block", Material.IRON_BLOCK.toString(), null), + READY_BLOCK("ready.block", Material.IRON_BLOCK, null), READY_CHECKEACHPLAYER("ready.checkEachPlayer", false, null), READY_CHECKEACHTEAM("ready.checkEachTeam", true, null), READY_ENFORCECOUNTDOWN("ready.enforceCountdown", false, null), @@ -194,7 +194,7 @@ public enum CFG { GOAL_BEACONS_TICKINTERVAL("goal.beacons.tickinterval", 60, "Beacons"), GOAL_BEACONS_TICKREWARD("goal.beacons.tickreward", 1, "Beacons"), - GOAL_BLOCKDESTROY_BLOCKTYPE("goal.blockdestroy.blocktype", Material.IRON_BLOCK.toString(), "BlockDestroy"), + GOAL_BLOCKDESTROY_BLOCKTYPE("goal.blockdestroy.blocktype", Material.IRON_BLOCK, "BlockDestroy"), GOAL_BLOCKDESTROY_LIVES("goal.blockdestroy.bdlives", 1, "BlockDestroy"), GOAL_CHECKPOINTS_CLAIMRANGE("goal.checkpoints.cpclaimrange", 5, "CheckPoints"), @@ -210,7 +210,7 @@ public enum CFG { GOAL_DOM_TICKINTERVAL("goal.dom.tickinterval", 60, "Domination"), GOAL_DOM_TICKREWARD("goal.dom.tickreward", 1, "Domination"), - GOAL_FLAGS_FLAGTYPE("goal.flags.flagType", Material.WHITE_WOOL.toString(), "Flags"), + GOAL_FLAGS_FLAGTYPE("goal.flags.flagType", Material.WHITE_WOOL, "Flags"), GOAL_FLAGS_LIVES("goal.flags.flives", 3, "Flags"), GOAL_FLAGS_MUSTBESAFE("goal.flags.mustBeSafe", true, "Flags"), GOAL_FLAGS_WOOLFLAGHEAD("goal.flags.woolFlagHead", true, "Flags"), @@ -231,7 +231,7 @@ public enum CFG { GOAL_PLIVES_LIVES("goal.playerlives.plives", 3, "PlayerLives"), GOAL_TANK_LIVES("goal.tank.tlives", 1, "Tank"), GOAL_TDC_LIVES("goal.teamdc.tdclives", 10, "TeamDeathConfirm"), - GOAL_TDC_ITEM("goal.teamdc.tdcitem", Material.WHITE_WOOL.toString(), "TeamDeathConfirm"), + GOAL_TDC_ITEM("goal.teamdc.tdcitem", Material.WHITE_WOOL, "TeamDeathConfirm"), GOAL_TDM_LIVES("goal.teamdm.tdlives", 10, "TeamDeathMatch"), GOAL_TDM_SUICIDESCORE("goal.teamdm.suicideScore", false, "TeamDeathMatch"), GOAL_TLIVES_LIVES("goal.teamlives.tlives", 10, "TeamLives"), @@ -329,13 +329,13 @@ public enum CFG { new ItemStack(Material.PINK_WOOL, 1), new ItemStack(Material.PURPLE_WOOL, 1), new ItemStack(Material.YELLOW_WOOL, 1), - new ItemStack(Material.WHITE_WOOL, 1)}, true, "BlockDissolve"), + new ItemStack(Material.WHITE_WOOL, 1)}, "BlockDissolve"), MODULES_BLOCKDISSOLVE_STARTSECONDS("modules.blockdissolve.startseconds", 10, "BlockDissolve"), MODULES_BLOCKDISSOLVE_TICKS("modules.blockdissolve.ticks", 40, "BlockDissolve"), MODULES_CHESTFILLER_CHESTLOCATION("modules.chestfiller.chestlocation", "none", "ChestFiller"), MODULES_CHESTFILLER_CLEAR("modules.chestfiller.clear", false, "ChestFiller"), - MODULES_CHESTFILLER_ITEMS("modules.chestfiller.cfitems", new ItemStack[]{new ItemStack(Material.STONE)}, true, "ChestFiller"), + MODULES_CHESTFILLER_ITEMS("modules.chestfiller.cfitems", new ItemStack[]{new ItemStack(Material.STONE)}, "ChestFiller"), MODULES_CHESTFILLER_MAXITEMS("modules.chestfiller.cfmaxitems", 5, "ChestFiller"), MODULES_CHESTFILLER_MINITEMS("modules.chestfiller.cfminitems", 0, "ChestFiller"), @@ -348,7 +348,7 @@ public enum CFG { MODULES_FIXINVENTORYLOSS_INVENTORY("modules.fixinventoryloss.inventory", false, "FixInventoryLoss"), MODULES_ITEMS_INTERVAL("modules.items.interval", 0, "Items"), - MODULES_ITEMS_ITEMS("modules.items.items", new ItemStack[0], true, "Items"), + MODULES_ITEMS_ITEMS("modules.items.items", new ItemStack[0], "Items"), MODULES_RESPAWNRELAY_INTERVAL("modules.respawnrelay.respawnseconds", 10, "RespawnRelay"), MODULES_RESPAWNRELAY_CHOOSESPAWN("modules.respawnrelay.choosespawn", false, "RespawnRelay"), @@ -411,7 +411,7 @@ public enum CFG { MODULES_VAULT_REWARD_TRIGGER("modules.vault.reward.trigger", 0.0d, "Vault"), MODULES_VAULT_REWARD_WIN("modules.vault.reward.playerWin", 0.0d, "Vault"), - MODULES_WALLS_MATERIAL("modules.walls.wallmaterial", Material.SAND.toString(), "Walls"), + MODULES_WALLS_MATERIAL("modules.walls.wallmaterial", Material.SAND, "Walls"), MODULES_WALLS_SCOREBOARDCOUNTDOWN("modules.walls.scoreboardcountdown", false, "Walls"), MODULES_WALLS_SECONDS("modules.walls.wallseconds", 300, "Walls"), @@ -463,10 +463,17 @@ public static CFG getByNode(final String node) { module = source; } - CFG(final String node, final ItemStack[] value, final boolean multiple, final String source) { + CFG(final String node, final ItemStack[] value, final String source) { this.node = node; this.value = getSerializableItemStacks(value); - type = multiple ? "items" : "material"; + type = "items"; + module = source; + } + + CFG(final String node, final Material value, final String source) { + this.node = node; + this.value = value.name(); + type = "material"; module = source; } diff --git a/src/net/slipcor/pvparena/goals/GoalBlockDestroy.java b/src/net/slipcor/pvparena/goals/GoalBlockDestroy.java index a76f69eb0..596513ec7 100644 --- a/src/net/slipcor/pvparena/goals/GoalBlockDestroy.java +++ b/src/net/slipcor/pvparena/goals/GoalBlockDestroy.java @@ -374,9 +374,8 @@ public PACheck getLives(final PACheck res, final ArenaPlayer aPlayer) { if (res.getPriority() <= PRIORITY + 1000) { res.setError( this, - String.valueOf(getLifeMap().containsKey(aPlayer.getArenaTeam() - .getName()) ? getLifeMap().get(aPlayer - .getArenaTeam().getName()) : 0)); + String.valueOf(getLifeMap().getOrDefault(aPlayer.getArenaTeam().getName(), 0)) + ); } return res; } diff --git a/src/net/slipcor/pvparena/goals/GoalCheckPoints.java b/src/net/slipcor/pvparena/goals/GoalCheckPoints.java index 4bb7a4bcd..2ff7d5334 100644 --- a/src/net/slipcor/pvparena/goals/GoalCheckPoints.java +++ b/src/net/slipcor/pvparena/goals/GoalCheckPoints.java @@ -301,9 +301,8 @@ public PACheck getLives(final PACheck res, final ArenaPlayer aPlayer) { if (res.getPriority() <= PRIORITY + 1000) { res.setError( this, - String.valueOf(getLifeMap().containsKey(aPlayer.getArenaTeam() - .getName()) ? getLifeMap().get(aPlayer - .getArenaTeam().getName()) : 0)); + String.valueOf(getLifeMap().getOrDefault(aPlayer.getArenaTeam().getName(), 0)) + ); } return res; } diff --git a/src/net/slipcor/pvparena/goals/GoalDomination.java b/src/net/slipcor/pvparena/goals/GoalDomination.java index 5f9226c6b..12f3eda32 100644 --- a/src/net/slipcor/pvparena/goals/GoalDomination.java +++ b/src/net/slipcor/pvparena/goals/GoalDomination.java @@ -618,9 +618,8 @@ public PACheck getLives(final PACheck res, final ArenaPlayer aPlayer) { if (res.getPriority() <= PRIORITY + 1000) { res.setError( this, - String.valueOf(getLifeMap().containsKey(aPlayer.getArenaTeam() - .getName()) ? getLifeMap().get(aPlayer - .getArenaTeam().getName()) : 0)); + String.valueOf(getLifeMap().getOrDefault(aPlayer.getArenaTeam().getName(), 0)) + ); } return res; } diff --git a/src/net/slipcor/pvparena/goals/GoalFlags.java b/src/net/slipcor/pvparena/goals/GoalFlags.java index 50fc67f9c..47cd119b4 100644 --- a/src/net/slipcor/pvparena/goals/GoalFlags.java +++ b/src/net/slipcor/pvparena/goals/GoalFlags.java @@ -752,9 +752,8 @@ public PACheck getLives(final PACheck res, final ArenaPlayer aPlayer) { if (res.getPriority() <= PRIORITY + 1000) { res.setError( this, - String.valueOf(getLifeMap().containsKey(aPlayer.getArenaTeam() - .getName()) ? getLifeMap().get(aPlayer - .getArenaTeam().getName()) : 0)); + String.valueOf(getLifeMap().getOrDefault(aPlayer.getArenaTeam().getName(), 0)) + ); } return res; } diff --git a/src/net/slipcor/pvparena/goals/GoalInfect.java b/src/net/slipcor/pvparena/goals/GoalInfect.java index f50a0d14b..03b6b2058 100644 --- a/src/net/slipcor/pvparena/goals/GoalInfect.java +++ b/src/net/slipcor/pvparena/goals/GoalInfect.java @@ -602,8 +602,8 @@ public PACheck getLives(final PACheck res, final ArenaPlayer aPlayer) { if (res.getPriority() <= PRIORITY + 1000) { res.setError( this, - String.valueOf(getLifeMap().containsKey(aPlayer.getName()) ? getLifeMap().get(aPlayer - .getName()) : 0)); + String.valueOf(getLifeMap().getOrDefault(aPlayer.getName(), 0)) + ); } return res; } diff --git a/src/net/slipcor/pvparena/goals/GoalLiberation.java b/src/net/slipcor/pvparena/goals/GoalLiberation.java index a90ffc637..af4608dc7 100644 --- a/src/net/slipcor/pvparena/goals/GoalLiberation.java +++ b/src/net/slipcor/pvparena/goals/GoalLiberation.java @@ -535,8 +535,8 @@ public PACheck getLives(final PACheck res, final ArenaPlayer aPlayer) { if (res.getPriority() <= PRIORITY + 1000) { res.setError( this, - String.valueOf(getLifeMap().containsKey(aPlayer.getName()) ? getLifeMap().get(aPlayer - .getName()) : 0)); + String.valueOf(getLifeMap().getOrDefault(aPlayer.getName(), 0)) + ); } return res; } diff --git a/src/net/slipcor/pvparena/goals/GoalPhysicalFlags.java b/src/net/slipcor/pvparena/goals/GoalPhysicalFlags.java index 9429fe405..091255b11 100644 --- a/src/net/slipcor/pvparena/goals/GoalPhysicalFlags.java +++ b/src/net/slipcor/pvparena/goals/GoalPhysicalFlags.java @@ -686,9 +686,8 @@ public PACheck getLives(final PACheck res, final ArenaPlayer aPlayer) { if (res.getPriority() <= PRIORITY + 1000) { res.setError( this, - String.valueOf(getLifeMap().containsKey(aPlayer.getArenaTeam() - .getName()) ? getLifeMap().get(aPlayer - .getArenaTeam().getName()) : 0)); + String.valueOf(getLifeMap().getOrDefault(aPlayer.getArenaTeam().getName(), 0)) + ); } return res; } diff --git a/src/net/slipcor/pvparena/goals/GoalPlayerLives.java b/src/net/slipcor/pvparena/goals/GoalPlayerLives.java index ea5717f57..04b9d1512 100644 --- a/src/net/slipcor/pvparena/goals/GoalPlayerLives.java +++ b/src/net/slipcor/pvparena/goals/GoalPlayerLives.java @@ -276,8 +276,8 @@ public PACheck getLives(final PACheck res, final ArenaPlayer aPlayer) { if (arena.isFreeForAll()) { res.setError( this, - String.valueOf(getLifeMap().containsKey(aPlayer.getName()) ? getLifeMap().get(aPlayer - .getName()) : 0)); + String.valueOf(getLifeMap().getOrDefault(aPlayer.getName(), 0)) + ); } else { if (getLifeMap().containsKey(aPlayer.getArenaTeam().getName())) { diff --git a/src/net/slipcor/pvparena/goals/GoalTank.java b/src/net/slipcor/pvparena/goals/GoalTank.java index 9117f1176..ec2b41483 100644 --- a/src/net/slipcor/pvparena/goals/GoalTank.java +++ b/src/net/slipcor/pvparena/goals/GoalTank.java @@ -277,8 +277,8 @@ public PACheck getLives(final PACheck res, final ArenaPlayer aPlayer) { if (res.getPriority() <= PRIORITY + 1000) { res.setError( this, - String.valueOf(getLifeMap().containsKey(aPlayer.getName()) ? getLifeMap().get(aPlayer - .getName()) : 0)); + String.valueOf(getLifeMap().getOrDefault(aPlayer.getName(), 0)) + ); } return res; } diff --git a/src/net/slipcor/pvparena/goals/GoalTeamLives.java b/src/net/slipcor/pvparena/goals/GoalTeamLives.java index 331749d37..5ead522dd 100644 --- a/src/net/slipcor/pvparena/goals/GoalTeamLives.java +++ b/src/net/slipcor/pvparena/goals/GoalTeamLives.java @@ -250,8 +250,8 @@ public PACheck getLives(final PACheck res, final ArenaPlayer aPlayer) { if (res.getPriority() <= PRIORITY + 1000) { res.setError( this, - String.valueOf(getLifeMap().containsKey(aPlayer.getArenaTeam().getName()) ? getLifeMap() - .get(aPlayer.getArenaTeam().getName()) : 0)); + String.valueOf(getLifeMap().getOrDefault(aPlayer.getArenaTeam().getName(), 0)) + ); } return res; } From 2f41352b952d6cb5363024aa26ae3024404b7fa2 Mon Sep 17 00:00:00 2001 From: Eredrim Date: Mon, 27 Apr 2020 20:30:53 +0200 Subject: [PATCH 02/43] v1.15 - code cleanup --- src/net/slipcor/pvparena/arena/Arena.java | 18 +++--------------- .../slipcor/pvparena/arena/ArenaPlayer.java | 4 ++++ .../slipcor/pvparena/arena/PlayerState.java | 17 ++++++----------- src/net/slipcor/pvparena/core/Debug.java | 2 +- .../pvparena/goals/GoalPlayerLives.java | 6 ++---- .../pvparena/listeners/PlayerListener.java | 9 +++------ .../runnables/InventoryRefillRunnable.java | 4 ++-- 7 files changed, 21 insertions(+), 39 deletions(-) diff --git a/src/net/slipcor/pvparena/arena/Arena.java b/src/net/slipcor/pvparena/arena/Arena.java index f250e2ebd..5dc69a780 100644 --- a/src/net/slipcor/pvparena/arena/Arena.java +++ b/src/net/slipcor/pvparena/arena/Arena.java @@ -1535,13 +1535,7 @@ private void resetPlayer(final Player player, final String destination, final bo //noinspection deprecation ArenaModuleManager.resetPlayer(this, player, soft, force); - String sClass = ""; - if (aPlayer.getArenaClass() != null) { - sClass = aPlayer.getArenaClass().getName(); - } - - if (!soft && (!"custom".equalsIgnoreCase(sClass) || - cfg.getBoolean(CFG.GENERAL_CUSTOMRETURNSGEAR))) { + if (!soft && (!aPlayer.hasCustomClass() || cfg.getBoolean(CFG.GENERAL_CUSTOMRETURNSGEAR))) { ArenaPlayer.reloadInventory(this, player, true); } @@ -1712,8 +1706,7 @@ public void unKillPlayer(final Player player, final DamageCause cause, final Ent PlayerState.playersetHealth(player, iHealth); player.setFoodLevel(cfg.getInt(CFG.PLAYER_FOODLEVEL, 20)); player.setSaturation(cfg.getInt(CFG.PLAYER_SATURATION, 20)); - player.setExhaustion((float) cfg.getDouble( - CFG.PLAYER_EXHAUSTION, 0.0)); + player.setExhaustion((float) cfg.getDouble(CFG.PLAYER_EXHAUSTION, 0.0)); player.setVelocity(new Vector()); player.setFallDistance(0); @@ -2069,12 +2062,7 @@ public void tpPlayerToCoordName(final Player player, final String place, final b aPlayer.setTelePass(true); final Location destination = loc.toLocation().add(offset.getX(), offset.getY(), offset.getZ()); if(runAsync) { - Bukkit.getScheduler().runTaskLater(PVPArena.instance, new Runnable() { - @Override - public void run() { - teleportPlayer(place, aPlayer, destination); - } - }, 2); + Bukkit.getScheduler().runTaskLater(PVPArena.instance, () -> teleportPlayer(place, aPlayer, destination), 2); } else { this.teleportPlayer(place, aPlayer, destination); } diff --git a/src/net/slipcor/pvparena/arena/ArenaPlayer.java b/src/net/slipcor/pvparena/arena/ArenaPlayer.java index 03a4c7a39..037fe7053 100644 --- a/src/net/slipcor/pvparena/arena/ArenaPlayer.java +++ b/src/net/slipcor/pvparena/arena/ArenaPlayer.java @@ -615,6 +615,10 @@ public boolean isPublicChatting() { return publicChatting; } + public boolean hasCustomClass() { + return this.getArenaClass() != null && "custom".equalsIgnoreCase(this.getArenaClass().getName()); + } + public void readDump() { debug.i("reading dump: " + name, name); debugPrint(); diff --git a/src/net/slipcor/pvparena/arena/PlayerState.java b/src/net/slipcor/pvparena/arena/PlayerState.java index d9c49a5f5..f9e92494e 100644 --- a/src/net/slipcor/pvparena/arena/PlayerState.java +++ b/src/net/slipcor/pvparena/arena/PlayerState.java @@ -105,7 +105,7 @@ public static void fullReset(final Arena arena, final Player player) { } if (arena.getArenaConfig().getInt(CFG.PLAYER_MAXHEALTH) > 0) { - player.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(arena.getArenaConfig().getInt(CFG.PLAYER_MAXHEALTH)); + player.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(arena.getArenaConfig().getInt(CFG.PLAYER_MAXHEALTH)); } if (iHealth > player.getAttribute(Attribute.GENERIC_MAX_HEALTH).getBaseValue()) { @@ -115,12 +115,9 @@ public static void fullReset(final Arena arena, final Player player) { } player.setFireTicks(0); try { - Bukkit.getScheduler().runTaskLater(PVPArena.instance, new Runnable() { - @Override - public void run() { - if (player.getFireTicks() > 0) { - player.setFireTicks(0); - } + Bukkit.getScheduler().runTaskLater(PVPArena.instance, () -> { + if (player.getFireTicks() > 0) { + player.setFireTicks(0); } }, 5L); } catch (Exception e) { @@ -129,8 +126,7 @@ public void run() { player.setVelocity(new Vector()); player.setFoodLevel(arena.getArenaConfig().getInt(CFG.PLAYER_FOODLEVEL)); player.setSaturation(arena.getArenaConfig().getInt(CFG.PLAYER_SATURATION)); - player.setExhaustion((float) arena.getArenaConfig().getDouble( - CFG.PLAYER_EXHAUSTION)); + player.setExhaustion((float) arena.getArenaConfig().getDouble(CFG.PLAYER_EXHAUSTION)); player.setLevel(0); player.setExp(0); if (arena.getArenaConfig().getInt(CFG.GENERAL_GAMEMODE) > -1) { @@ -250,8 +246,7 @@ public static void playersetHealth(final Player player, final double value) { final double current = player.getHealth(); final double regain = value - current; - final EntityRegainHealthEvent event = new EntityRegainHealthEvent(player, regain, - RegainReason.CUSTOM); + final EntityRegainHealthEvent event = new EntityRegainHealthEvent(player, regain, RegainReason.CUSTOM); Bukkit.getPluginManager().callEvent(event); } diff --git a/src/net/slipcor/pvparena/core/Debug.java b/src/net/slipcor/pvparena/core/Debug.java index 9924601ef..e9136a088 100644 --- a/src/net/slipcor/pvparena/core/Debug.java +++ b/src/net/slipcor/pvparena/core/Debug.java @@ -13,8 +13,8 @@ import java.io.StringWriter; import java.text.SimpleDateFormat; import java.util.*; -import java.util.logging.*; import java.util.logging.Formatter; +import java.util.logging.*; /** diff --git a/src/net/slipcor/pvparena/goals/GoalPlayerLives.java b/src/net/slipcor/pvparena/goals/GoalPlayerLives.java index 04b9d1512..42fd79e6d 100644 --- a/src/net/slipcor/pvparena/goals/GoalPlayerLives.java +++ b/src/net/slipcor/pvparena/goals/GoalPlayerLives.java @@ -248,8 +248,7 @@ public void commitPlayerDeath(final Player player, final boolean doesRespawn, } final List returned; - if (arena.getArenaConfig().getBoolean( - CFG.PLAYER_DROPSINVENTORY)) { + if (arena.getArenaConfig().getBoolean(CFG.PLAYER_DROPSINVENTORY)) { returned = InventoryManager.drop(player); event.getDrops().clear(); } else { @@ -257,8 +256,7 @@ public void commitPlayerDeath(final Player player, final boolean doesRespawn, returned.addAll(event.getDrops()); } - PACheck.handleRespawn(arena, - ArenaPlayer.parsePlayer(player.getName()), returned); + PACheck.handleRespawn(arena, ArenaPlayer.parsePlayer(player.getName()), returned); } } diff --git a/src/net/slipcor/pvparena/listeners/PlayerListener.java b/src/net/slipcor/pvparena/listeners/PlayerListener.java index 3bab67edc..ac7392c12 100644 --- a/src/net/slipcor/pvparena/listeners/PlayerListener.java +++ b/src/net/slipcor/pvparena/listeners/PlayerListener.java @@ -381,7 +381,7 @@ public static void finallyKillPlayer(final Arena arena, final Player player, final ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(player.getName()); final ArenaTeam team = aPlayer.getArenaTeam(); - final String playerName = team == null ? player.getName() : team.colorizePlayer(player); + final String playerName = (team == null) ? player.getName() : team.colorizePlayer(player); if (arena.getArenaConfig().getBoolean(CFG.USES_DEATHMESSAGES)) { arena.broadcast(Language.parse(arena, MSG.FIGHT_KILLED_BY, @@ -397,14 +397,11 @@ public static void finallyKillPlayer(final Arena arena, final Player player, } } - if (ArenaPlayer.parsePlayer(player.getName()).getArenaClass() == null - || !"custom".equalsIgnoreCase(ArenaPlayer.parsePlayer(player.getName()).getArenaClass() - .getName())) { + if (!aPlayer.hasCustomClass()) { InventoryManager.clearInventory(player); } - arena.removePlayer(player, - arena.getArenaConfig().getString(CFG.TP_DEATH), true, false); + arena.removePlayer(player, arena.getArenaConfig().getString(CFG.TP_DEATH), true, false); aPlayer.setStatus(Status.LOST); aPlayer.addDeath(); diff --git a/src/net/slipcor/pvparena/runnables/InventoryRefillRunnable.java b/src/net/slipcor/pvparena/runnables/InventoryRefillRunnable.java index b9807084b..bcf331cf4 100644 --- a/src/net/slipcor/pvparena/runnables/InventoryRefillRunnable.java +++ b/src/net/slipcor/pvparena/runnables/InventoryRefillRunnable.java @@ -78,7 +78,7 @@ public void run() { final ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(player.getName()); arena.getDebugger().i("refilling " + player.getName()); if (aPlayer.getStatus() == Status.FIGHT) { - if ("custom".equals(aPlayer.getArenaClass().getName()) && !arena.getArenaConfig().getBoolean(CFG.PLAYER_REFILLCUSTOMINVENTORY) || !arena.getArenaConfig().getBoolean(CFG.PLAYER_REFILLINVENTORY)) { + if (aPlayer.hasCustomClass() && !arena.getArenaConfig().getBoolean(CFG.PLAYER_REFILLCUSTOMINVENTORY) || !arena.getArenaConfig().getBoolean(CFG.PLAYER_REFILLINVENTORY)) { if (refill) { final ItemStack[] items = new ItemStack[additions.size()]; int pos = 0; @@ -101,7 +101,7 @@ public void run() { new ItemStack(ColorUtils.getWoolMaterialFromChatColor(chatColor), 1)); PVPArena.instance.getAgm().refillInventory(arena, player); } - } else if (refill && "custom".equals(aPlayer.getArenaClass().getName())) { + } else if (refill && aPlayer.hasCustomClass()) { ArenaPlayer.reloadInventory(arena, player, false); for (final ItemStack item : additions) { From e95c9e9602c1265ca3459a716dd974ea8bf79e84 Mon Sep 17 00:00:00 2001 From: Eredrim Date: Wed, 29 Apr 2020 16:37:30 +0200 Subject: [PATCH 03/43] v1.15 - fixes death screen when player lose its last life --- src/net/slipcor/pvparena/listeners/PlayerListener.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/net/slipcor/pvparena/listeners/PlayerListener.java b/src/net/slipcor/pvparena/listeners/PlayerListener.java index ac7392c12..1bec57349 100644 --- a/src/net/slipcor/pvparena/listeners/PlayerListener.java +++ b/src/net/slipcor/pvparena/listeners/PlayerListener.java @@ -397,6 +397,9 @@ public static void finallyKillPlayer(final Arena arena, final Player player, } } + // Trick to avoid death screen + Bukkit.getScheduler().scheduleSyncDelayedTask(PVPArena.instance, player::closeInventory, 1); + if (!aPlayer.hasCustomClass()) { InventoryManager.clearInventory(player); } From 7575cd2913b8850800030435115c9d1b710a030a Mon Sep 17 00:00:00 2001 From: Eredrim Date: Thu, 30 Apr 2020 18:30:08 +0200 Subject: [PATCH 04/43] v1.15 - add translation and rewrite docs for squads mod --- doc/mods/squads.md | 22 +++++++++++++++------ lang/lang_en.yml | 15 ++++++++++++++ lang/lang_fr.yml | 15 ++++++++++++++ src/net/slipcor/pvparena/core/Language.java | 11 +++++++++++ 4 files changed, 57 insertions(+), 6 deletions(-) diff --git a/doc/mods/squads.md b/doc/mods/squads.md index 8f9f1a996..5cc8c97f1 100644 --- a/doc/mods/squads.md +++ b/doc/mods/squads.md @@ -2,7 +2,9 @@ ## Description -This mod adds squads to the game, basically only showing players belonging together apart from teams and classes. +This mod allow players to make squads. Instead of respawning anywhere / at the team spawn, you spawn at a random squad member. + +Squads are an addition to teams or even a replacement (in case of a FFA arena). ## Installation @@ -11,19 +13,27 @@ Unzip the module files (files tab, "PA Files v*.*.*") into the /pvparena/files f - `/pa install [modname]`, activate per arena via - `/pa [arenaname] !tm [modname]` -## Setup +## Usage -\- +Place signs, similar to the Class Signs: + +``` +[Squad name] +[ignored] +free +free +``` + +You can add another (one) sign below for display of more player names -## Config settings ( config.yml !!! NOT per arena! ) +## Config settings ( in your arena config file ) - modules.squads.ingameSquadSwitch \- allow switching squads ingame ## Commands - `/pa [arena] !sq` \- show the arena squads -- `/pa [arena] !sq add [name]` \- add squad [name] -- `/pa [arena] !sq add [name] [limit]` \- add squad with player limit +- `/pa [arena] !sq add [name] [limit]` \- add squad with player limit (set to 0 to remove limit) - `/pa [arena] !sq remove [name]` \- remove squad [name] - `/pa [arena] !sq set [name] [limit]` \- set player limit for squad diff --git a/lang/lang_en.yml b/lang/lang_en.yml index 6a0236968..b7cd3d217 100644 --- a/lang/lang_en.yml +++ b/lang/lang_en.yml @@ -563,6 +563,21 @@ nulang: done: Join block set here - %1% start: Setting join block! stop: Aborted join block selection! + squads: + nosquad: 'No squads loaded! Add some: /pa [arena] !sq add [name]' + listhead: Squads for arena &b%1% + listitem: 'Squad %1% (max: %2%) %3%' + added: Squad %1% has been added + set: Squad %1% has been set + removed: Squad %1% has been removed + notexist: Squad %1% doesn't exist + error: Error while editing squads, syntax is not correct! + full: This squad is full! + help: |- + /pa !sq | show the arena squads + /pa !sq add [name] [limit] | add squad with player limit (set to 0 for no limit) + /pa !sq set [name] [limit] | set player limit for squad + /pa !sq remove [name] | remove squad [name] startfreeze: announce: The game will start in %1% seconds! tempperms: diff --git a/lang/lang_fr.yml b/lang/lang_fr.yml index 196051df1..a913bd22a 100644 --- a/lang/lang_fr.yml +++ b/lang/lang_fr.yml @@ -616,6 +616,21 @@ nulang: done: Le join block est configuré - %1% start: Configuration du join block ! stop: Annulation de la selection du join block! + squads: + nosquad: 'Aucune escouade n''est chargée. Ajoutez-en avec la commande /pa [arena] !sq add [name]' + listhead: Liste des escoudes de l'arène &b%1% + listitem: 'Escouade %1% (max: %2%) %3%' + added: L'escouade %1% a été ajoutée + set: L'escouade %1% a été modifiée + removed: L'escouade %1% a été supprimée + notexist: L'escouade %1% n'existe pas + error: Erreur lors de l'édition des escouades, la syntaxe de la command est incorrecte ! + full: L'escouade est pleine ! + help: |- + /pa !sq | affiche la liste des escouades de l'arène + /pa !sq add [name] [limit] | ajoute une escoude avec une limite (mettre 0 pour ne pas avoir de limite) + /pa !sq set [name] [limit] | modifier la limite de joueurs d'une escouade + /pa !sq remove [name] | supprimer une escouade startfreeze: announce: Le jeu commencera dans %1% secondes ! tempperms: diff --git a/src/net/slipcor/pvparena/core/Language.java b/src/net/slipcor/pvparena/core/Language.java index 0517c64b4..e76b9ef6b 100644 --- a/src/net/slipcor/pvparena/core/Language.java +++ b/src/net/slipcor/pvparena/core/Language.java @@ -668,6 +668,17 @@ public enum MSG { MODULE_SPECIALJOIN_START("nulang.mod.specialjoin.start", "Setting join block!"), MODULE_SPECIALJOIN_STOP("nulang.mod.specialjoin.stop", "Aborted join block selection!"), + MODULE_SQUADS_NOSQUAD("nulang.mod.squads.nosquad", "No squads loaded! Add some: /pa [arena] !sq add [name]"), + MODULE_SQUADS_LISTHEAD("nulang.mod.squads.listhead", "Squads for arena &b%1%"), + MODULE_SQUADS_LISTITEM("nulang.mod.squads.listitem", "Squad %1% (max: %2%) %3%"), + MODULE_SQUADS_ADDED("nulang.mod.squads.added", "Squad %1% has been added"), + MODULE_SQUADS_SET("nulang.mod.squads.set", "Squad %1% has been set"), + MODULE_SQUADS_REMOVED("nulang.mod.squads.removed", "Squad %1% has been removed"), + MODULE_SQUADS_NOTEXIST("nulang.mod.squads.notexist", "Squad %1% doesn't exist!"), + MODULE_SQUADS_ERROR("nulang.mod.squads.error", "Error while editing squads, syntax is not correct!"), + MODULE_SQUADS_FULL("nulang.mod.squads.full", "This squad is full!"), + MODULE_SQUADS_HELP("nulang.mod.squads.help", "/pa !sq | show the arena squads\n/pa !sq add [name] [limit] | add squad with player limit (set to 0 for no limit)\n/pa !sq set [name] [limit] | set player limit for squad\n/pa !sq remove [name] | remove squad [name]"), + MODULE_STARTFREEZE_ANNOUNCE("nulang.mod.startfreeze.announce", "The game will start in %1% seconds!"), MODULE_TEMPPERMS_NOPERMS("nulang.mod.tempperms.noperms", "Permissions plugin not found, defaulting to OP."), From 5f1fc8b33a5f59c0bd7c4ef1494eb7ceddf64af5 Mon Sep 17 00:00:00 2001 From: Eredrim Date: Thu, 30 Apr 2020 19:35:11 +0200 Subject: [PATCH 05/43] v1.15 - fix "no pvp" warn for infected arenas --- src/net/slipcor/pvparena/core/Config.java | 5 +++++ src/net/slipcor/pvparena/managers/ConfigurationManager.java | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/net/slipcor/pvparena/core/Config.java b/src/net/slipcor/pvparena/core/Config.java index 75b992920..dff88f91f 100644 --- a/src/net/slipcor/pvparena/core/Config.java +++ b/src/net/slipcor/pvparena/core/Config.java @@ -792,6 +792,10 @@ public Set getKeys(final String path) { return section.getKeys(false); } + public List getStringList(final CFG cfg) { + return this.getStringList(cfg.getNode(), null); + } + public List getStringList(final String path, final List def) { if (cfg.get(path) == null) { return def == null ? new LinkedList() : def; @@ -800,6 +804,7 @@ public List getStringList(final String path, final List def) { return cfg.getStringList(path); } + // ///////////////////////////////////////////////////////////////////////// // // // MUTATORS // diff --git a/src/net/slipcor/pvparena/managers/ConfigurationManager.java b/src/net/slipcor/pvparena/managers/ConfigurationManager.java index 58e8124e5..966cd23c5 100644 --- a/src/net/slipcor/pvparena/managers/ConfigurationManager.java +++ b/src/net/slipcor/pvparena/managers/ConfigurationManager.java @@ -282,8 +282,8 @@ public static boolean configParse(final Arena arena, final Config cfg) { .getValues(true); if (arena.isFreeForAll()) { - if (!arena.getArenaConfig().getBoolean(CFG.PERMS_TEAMKILL)) { - PVPArena.instance.getLogger().warning("Arena " + arena.getName() + " is running in NO-PVP mode! Make sure people can die! Ignore this if you're running infect!"); + if (!arena.getArenaConfig().getBoolean(CFG.PERMS_TEAMKILL) && !arena.getArenaConfig().getStringList(CFG.LISTS_GOALS).contains("Infect")) { + PVPArena.instance.getLogger().warning("Arena " + arena.getName() + " is running in NO-PVP mode! Make sure people can die!"); } } else { for (final Map.Entry stringObjectEntry : tempMap.entrySet()) { From aa5d88fbef87c7f876b57abaf3bff7fc7d2bfe48 Mon Sep 17 00:00:00 2001 From: Eredrim Date: Fri, 8 May 2020 21:14:13 +0200 Subject: [PATCH 06/43] v1.15 - Improve flags, physical flags and domination goals to handle all colorable items --- doc/commands/region.md | 6 +- doc/goals/domination.md | 51 +- doc/goals/flags.md | 42 +- doc/goals/physicalflags.md | 67 +- doc/regions.md | 26 +- src/net/slipcor/pvparena/classes/PABlock.java | 10 +- .../pvparena/classes/PABlockLocation.java | 86 +-- src/net/slipcor/pvparena/core/ColorUtils.java | 26 + src/net/slipcor/pvparena/core/Config.java | 12 +- .../slipcor/pvparena/core/StringParser.java | 3 +- .../pvparena/goals/GoalDomination.java | 464 ++++++------ src/net/slipcor/pvparena/goals/GoalFlags.java | 579 +++++++-------- .../pvparena/goals/GoalPhysicalFlags.java | 660 ++++++++---------- .../pvparena/loadables/ArenaRegion.java | 7 +- .../runnables/CircleParticleRunnable.java | 19 +- 15 files changed, 1043 insertions(+), 1015 deletions(-) diff --git a/doc/commands/region.md b/doc/commands/region.md index 3ad4f9e35..2dfe4f8e5 100644 --- a/doc/commands/region.md +++ b/doc/commands/region.md @@ -27,8 +27,4 @@ Valid regionshapes include: - CUBOID (default) - SPHERIC -- CYLINDRIC - -## ToDo - -Add more region shapes :D \ No newline at end of file +- CYLINDRIC \ No newline at end of file diff --git a/doc/goals/domination.md b/doc/goals/domination.md index 4ec9a5176..1d334c517 100644 --- a/doc/goals/domination.md +++ b/doc/goals/domination.md @@ -4,33 +4,56 @@ Domination is designed to use teams. As always, it defaults to red and blue. -It activates Flags (to set) that can be claimed by players. In order to do that, they have to stand near that flag, -alone or at least only one team. Flags can be unclaimed if a different team or multiple teams are too close to a claimed flag. +The game is simple : -Each claimed flag gives points every few seconds (tickinterval) that add up to a score, the first team to have enough points wins. +There are one or several flags that can be claimed by players. +When players are in the range of a flag, a load bar appears and they will claim the flag after few seconds. +Obviously, if a player on another team come also within the flag range, loading stops. + +When a flag is claimed, it take team color. Player of other team can get it back by the same process. +In this case, flag will be released in a first time (it takes white color) and only then it will take color of +second team. + +Each claimed flag gives points every few seconds (tickinterval) that add up to a score, the first team to have enough +points wins. ## Setup Flags have to be added.In order to do that, use `/pa [arenaname] flag`. This toggles edit mode. -Don't forget to exit it again after setting the flags. Set them by clicking the flag type (WOOL by default). +Don't forget to type command again in order to exit edit mode after setting the flags. +Set them by clicking the flag type (WOOL by default). + +Given that flag must be able to change color, you can use the following blocks as flagtype +(color prefix doesn't matter): +* WHITE_BANNER +* WHITE_CARPET +* WHITE_CONCRETE +* WHITE_CONCRETE_POWDER +* WHITE_GLAZED_TERRACOTTA +* WHITE_SHULKER_BOX +* WHITE_STAINED_GLASS +* WHITE_STAINED_GLASS_PANE +* WHITE_TERRACOTTA +* WHITE_WALL_BANNER + +It suggest you to try glass block with a beacon bottom the flag. When flag will be claimed, glass blocks will change its +color, altering beacon light ray in the same time :wink: ## Config Settings - spamoffset => after how many updates should the arena announce? (default: 3) - claimrange => how near need players to be? (default: 3) -- dlives => domination lives ( max points ) -- onlywhenmore => only score when more than half of the points are claimed -- tickinterval => the amount of ticks to wait before doing an update (default: 60 = 3 seconds) -- tickreward => the amount of points to give for each score (default: 1) +- dlives => domination lives (max points). (default: 10) +- onlywhenmore => only score when more than half of the points are claimed. (default: false) +- particlecircle => creates a circle of particles around each flag to mark capture radius. (default: true) +- tickinterval => the amount of ticks to wait before doing an update. (default: 60 = 3 seconds) +- tickreward => the amount of points to give for each score. (default: 1) ## Warnings -This game mode has to check for player's position. Based on the player count this can lag your server. But, how else should I determine a claimed flag? :p - -## Supported Game Modes - -Supports both game modes, but we suggest you use the team game mode! +This game mode has to check for player's position. Based on the player count this can lag your server. +But, how else should I determine a claimed flag? :p -## YouTube video +## YouTube video (legacy) [click me](http://www.youtube.com/watch?v=Xi7yNURxAjw) diff --git a/doc/goals/flags.md b/doc/goals/flags.md index 866e26bc9..260c46ef8 100644 --- a/doc/goals/flags.md +++ b/doc/goals/flags.md @@ -2,28 +2,48 @@ ## Description -This activates Flags (to set), per team. Team A captures the flag of team B and brings it home. To do this, simply hit the flag / your flag. +This activates Flags (to set), per team. Team A captures the flag of team B and brings it home. +To do this, simply hit/click on flags. ## Setup -Flags have to be added.In order to do that, use `/pa [arenaname] [teamname]flag` \- this enables setting. +Firstly, check if flag type is that you want (wool by default) or change it by editing +your arena configuration ou using `/pa set` command. +You can use any solid block as flag. Flags automatically take team color if flag type is one +of the following material (color prefix doesn't matter): -Do this by clicking the flag type (WOOL by default). Don't click with your wand, just click with your hand or anything else. +* WHITE_BANNER +* WHITE_CARPET +* WHITE_CONCRETE +* WHITE_CONCRETE_POWDER +* WHITE_GLAZED_TERRACOTTA +* WHITE_SHULKER_BOX +* WHITE_STAINED_GLASS +* WHITE_STAINED_GLASS_PANE +* WHITE_TERRACOTTA +* WHITE_WALL_BANNER -You can activate a special "touchdown" way of playing. Set a flag called "touchdown", it will be BLACK ingame. Players claim this flag and bring it home. Only one team can bring this flag home, obviously :) +  + +Flags have to be added afterwards. In order to do that, use `/pa [arenaname] [teamname]flag` \- this enables setting. +Just left click on your flag block. Clicked block must have same type as defined in your config. However nothing will +happen. + +You can activate a special "touchdown" way of playing. Set a flag called "touchdown", it will be BLACK ingame. +Players claim this flag and bring it home. Only one team can bring this flag home, obviously :) ## Config Settings - flives \- the count of flags being brought home that lead to winning -- flagType \- the material checked for flags (default: WOOL) +- flagType \- the material checked for flags (default: WHITE_WOOL). Plugin handle automatically flag colors if flagType +is a colorable item. - mustBeSafe \- do claimed flags prevent bringing home other flags? \- (default: true) - woolFlagHead \- should PVP Arena enforce putting a wool head on flag carriers? - (default: true) -- effect \- the potion effect a player should get when carrying the flag (default: none; possible value: SLOWx2 - slowness, level 2 ; see bukkit docs - -## Supported Game Modes - -Only supports team game mode! +- effect \- the potion effect a player should get when carrying the flag (default: none; possible value: SLOWx2 - +slowness, level 2) ; see bukkit docs +- alterOnCatch \- change flag aspect when a player catch it. If flag is colorable (list below), color is passed to white + otherwise block is replaced by bedrock. (default: true) -## YouTube video +## YouTube video (legacy) [click me](http://www.youtube.com/watch?v=SuL78bce-f0) diff --git a/doc/goals/physicalflags.md b/doc/goals/physicalflags.md index 9f817621d..2d4df4731 100644 --- a/doc/goals/physicalflags.md +++ b/doc/goals/physicalflags.md @@ -1,23 +1,44 @@ -# PhysicalFlags - ## Description - -This activates Flags (to set), per team. Team A captures the flag of team B and brings it home. To do this, simply break the flag block and click your flag when holding the flag block! - ## Setup - -Flags have to be added.In order to do that, use `/pa [arenaname] [teamname]flag` - this enables setting. - -Do this by clicking the flag type (WOOL by default). Don't click with your wand, -just click with your hand or anything else. - -You can activate a special "touchdown" way of playing. Set a flag called "touchdown", it will be BLACK ingame. Players claim this flag and bring it home. - -Only one team can bring this flag home, obviously :) - ## Config Settings - -- flives - the count of flags being brought home that lead to winning -- flagType - the material checked for flags (default: WOOL) -- mustBeSafe - do claimed flags prevent bringing home other flags? - (default: true) - -## Supported Game Modes - -Only supports team game mode! +# PhysicalFlags + +## Description + +This activates Flags (to set), per team. Team A have to break team B flag and brings it at home. +Point is score when team A place team B flag on its own flag. + +## Setup + +Firstly, check if flag type is that you want (wool by default) or change it by editing +your arena configuration ou using `/pa set` command. +You can use any solid block as flag. Flags automatically take team color if flag type is one +of the following material (color prefix doesn't matter): + +* WHITE_BANNER +* WHITE_CARPET +* WHITE_CONCRETE +* WHITE_CONCRETE_POWDER +* WHITE_GLAZED_TERRACOTTA +* WHITE_SHULKER_BOX +* WHITE_STAINED_GLASS +* WHITE_STAINED_GLASS_PANE +* WHITE_TERRACOTTA +* WHITE_WALL_BANNER + +  + +Flags have to be added afterwards. In order to do that, use `/pa [arenaname] [teamname]flag` \- this enables setting. +Just left click on your flag block. Clicked block must have same type as defined in your config. However nothing will +happen. + +You can activate a special "touchdown" way of playing. Set a flag called "touchdown", it will be BLACK ingame. +Players claim this flag and bring it home. Only one team can bring this flag home, obviously :) + +## Config Settings + +- flives \- the count of flags being brought home that lead to winning +- flagType \- the material checked for flags (default: WHITE_WOOL). Plugin handle automatically flag colors if flagType +is a colorable item. +- mustBeSafe \- do claimed flags prevent bringing home other flags? \- (default: true) +- woolFlagHead \- should PVP Arena enforce putting a wool head on flag carriers? - (default: true) +- effect \- the potion effect a player should get when carrying the flag (default: none; possible value: SLOWx2 - +slowness, level 2) ; see bukkit docs + diff --git a/doc/regions.md b/doc/regions.md index 879baf747..cb4ba5625 100644 --- a/doc/regions.md +++ b/doc/regions.md @@ -36,6 +36,8 @@ The following Region Types exist: - EXIT => the region where players should be after exiting the arena, no functionality atm - JOIN => the region where players should be when joining, see Configuration page, enforcement is disabled by default - SPAWN => a spawn region where players are randomly placed in when spawning or respawning +- BL_INV => blacklist inventory access +- WL_INV => whitelist inventory access ## Region Flags @@ -53,15 +55,17 @@ Those are valid Region Flags: The BATTLE Region parses region protection flags (other regions can assigned protections, too, but atm they don't really use them). Set them via `/pa !p [regionname] [protection]` - you can add on, off, yes, no, true, false to specify a setting, or just as just told to toggle the state. Note that there is an "ALL" protection node that triggers/sets all protection nodes Valid protections are: -- BREAK - Block breaking -- FIRE - Fire (spreading) -- MOBS - Mob spawning -- NATURE - Environment changes (leaves, shrooms, water, lava) -- PAINTING - Painting placement/destruction -- PISTON - Piston triggering -- PLACE - Block placement -- REDSTONE - Redstone current change -- TNT - TNT usage -- TNTBREAK - TNT block break -- TELEPORT - Players Teleportation +- BREAK - prevent player block breaking +- FIRE - prevent fire spreading/burning +- MOBS - prevent mob spawning +- NATURE - prevent water flow/growth +- PAINTING - prevent painting/itemframe breakage +- PISTON - prevent piston usage +- PLACE - prevent player block placing +- TNT - prevent tnt interaction +- TNTBREAK - prevent tnt block damage (explosion still hurts) +- DROP - prevent player item dropping +- INVENTORY - prevent inventory interaction +- PICKUP - prevent player item pickup +- TELEPORT - prevent player teleportation diff --git a/src/net/slipcor/pvparena/classes/PABlock.java b/src/net/slipcor/pvparena/classes/PABlock.java index 3878c176d..e41259fe7 100644 --- a/src/net/slipcor/pvparena/classes/PABlock.java +++ b/src/net/slipcor/pvparena/classes/PABlock.java @@ -5,24 +5,24 @@ public class PABlock { private final String name; public PABlock(final PABlockLocation loc, final String string) { - location = loc; - name = string; + this.location = loc; + this.name = string; } @Override public boolean equals(final Object o) { if (o instanceof PABlock) { final PABlock other = (PABlock) o; - return name.equals(other.name) && location.equals(other.location); + return this.name.equals(other.name) && this.location.equals(other.location); } return false; } public PABlockLocation getLocation() { - return location; + return this.location; } public String getName() { - return name; + return this.name; } } diff --git a/src/net/slipcor/pvparena/classes/PABlockLocation.java b/src/net/slipcor/pvparena/classes/PABlockLocation.java index 3cf916ea8..75b40a592 100644 --- a/src/net/slipcor/pvparena/classes/PABlockLocation.java +++ b/src/net/slipcor/pvparena/classes/PABlockLocation.java @@ -30,30 +30,30 @@ public PABlockLocation(final String world, final int x, final int y, final int z public PABlockLocation(final String value) { String[] split = value.split(":"); - world = split[0]; + this.world = split[0]; String[] ints = split[1].split(","); - x = Integer.parseInt(ints[0]); - y = Integer.parseInt(ints[1]); - z = Integer.parseInt(ints[2]); + this.x = Integer.parseInt(ints[0]); + this.y = Integer.parseInt(ints[1]); + this.z = Integer.parseInt(ints[2]); } public PABlockLocation(final Location bukkitLocation) { - world = bukkitLocation.getWorld().getName(); - x = bukkitLocation.getBlockX(); - y = bukkitLocation.getBlockY(); - z = bukkitLocation.getBlockZ(); + this.world = bukkitLocation.getWorld().getName(); + this.x = bukkitLocation.getBlockX(); + this.y = bukkitLocation.getBlockY(); + this.z = bukkitLocation.getBlockZ(); } @Override public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + (world == null ? 0 : world.hashCode()); - result = prime * result + x; - result = prime * result + y; - result = prime * result + z; + result = prime * result + (this.world == null ? 0 : this.world.hashCode()); + result = prime * result + this.x; + result = prime * result + this.y; + result = prime * result + this.z; return result; } @@ -65,24 +65,24 @@ public boolean equals(final Object obj) { if (obj == null) { return false; } - if (getClass() != obj.getClass()) { + if (this.getClass() != obj.getClass()) { return false; } final PABlockLocation other = (PABlockLocation) obj; - if (world == null) { + if (this.world == null) { if (other.world != null) { return false; } - } else if (!world.equals(other.world)) { + } else if (!this.world.equals(other.world)) { return false; } - if (x != other.x) { + if (this.x != other.x) { return false; } - if (y != other.y) { + if (this.y != other.y) { return false; } - return z == other.z; + return this.z == other.z; } public double getDistance(final PABlockLocation otherLocation) { @@ -90,14 +90,14 @@ public double getDistance(final PABlockLocation otherLocation) { throw new IllegalArgumentException( "Cannot measure distance to a null location"); } - if (!otherLocation.world.equals(world)) { + if (!otherLocation.world.equals(this.world)) { throw new IllegalArgumentException( - "Cannot measure distance between " + world + " and " + "Cannot measure distance between " + this.world + " and " + otherLocation.world); } - return Math.sqrt(Math.pow(x - otherLocation.x, 2.0D) - + Math.pow(y - otherLocation.y, 2.0D) + Math.pow(z - otherLocation.z, 2.0D)); + return Math.sqrt(Math.pow(this.x - otherLocation.x, 2.0D) + + Math.pow(this.y - otherLocation.y, 2.0D) + Math.pow(this.z - otherLocation.z, 2.0D)); } public double getDistanceSquared(final PABlockLocation otherLocation) { @@ -105,77 +105,77 @@ public double getDistanceSquared(final PABlockLocation otherLocation) { throw new IllegalArgumentException( "Cannot measure distance to a null location"); } - if (!otherLocation.world.equals(world)) { + if (!otherLocation.world.equals(this.world)) { throw new IllegalArgumentException( - "Cannot measure distance between " + world + " and " + "Cannot measure distance between " + this.world + " and " + otherLocation.world); } - return Math.pow(x - otherLocation.x, 2.0D) - + Math.pow(y - otherLocation.y, 2.0D) + Math.pow(z - otherLocation.z, 2.0D); + return Math.pow(this.x - otherLocation.x, 2.0D) + + Math.pow(this.y - otherLocation.y, 2.0D) + Math.pow(this.z - otherLocation.z, 2.0D); } public PABlockLocation getMidpoint(final PABlockLocation location) { - return new PABlockLocation(world, (x + location.x) / 2, (y + location.y) / 2, - (z + location.z) / 2); + return new PABlockLocation(this.world, (this.x + location.x) / 2, (this.y + location.y) / 2, + (this.z + location.z) / 2); } public String getWorldName() { - return world; + return this.world; } public int getX() { - return x; + return this.x; } public int getY() { - return y; + return this.y; } public int getZ() { - return z; + return this.z; } public boolean isInAABB(final PABlockLocation min, final PABlockLocation max) { - if (x < min.x || x > max.x) { + if (this.x < min.x || this.x > max.x) { return false; } - if (y < min.y || y > max.y) { + if (this.y < min.y || this.y > max.y) { return false; } - return !(z < min.z || z > max.z); + return !(this.z < min.z || this.z > max.z); } public PABlockLocation pointTo(final PABlockLocation dest, final Double length) { - final Vector source = new Vector(x, y, z); + final Vector source = new Vector(this.x, this.y, this.z); final Vector destination = new Vector(dest.x, dest.y, dest.z); Vector goal = source.subtract(destination); goal = goal.normalize().multiply(length); - return new PABlockLocation(world, x + x + goal.getBlockX(), y - + goal.getBlockY(), z + goal.getBlockZ()); + return new PABlockLocation(this.world, this.x + this.x + goal.getBlockX(), this.y + + goal.getBlockY(), this.z + goal.getBlockZ()); } public void setX(final int value) { - x = value; + this.x = value; } public void setY(final int value) { - y = value; + this.y = value; } public void setZ(final int value) { - z = value; + this.z = value; } public Location toLocation() { - return new Location(Bukkit.getWorld(world), x, y, z); + return new Location(Bukkit.getWorld(this.world), this.x, this.y, this.z); } @Override public String toString() { - return world + ':' + x + ',' + y + ',' + z; + return this.world + ':' + this.x + ',' + this.y + ',' + this.z; } } diff --git a/src/net/slipcor/pvparena/core/ColorUtils.java b/src/net/slipcor/pvparena/core/ColorUtils.java index 83a506ab0..3c2ac1507 100644 --- a/src/net/slipcor/pvparena/core/ColorUtils.java +++ b/src/net/slipcor/pvparena/core/ColorUtils.java @@ -1,8 +1,13 @@ package net.slipcor.pvparena.core; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.DyeColor; import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; +import org.bukkit.block.data.Rotatable; import java.util.Arrays; import java.util.List; @@ -119,4 +124,25 @@ private static List getColorableSuffixes() { .map(ColorUtils::getMaterialSuffix) .collect(Collectors.toList()); } + + /** + * Change flag color keeping rotation and facing + * @param flagBlock Block (location) of the flag + * @param flagColor New flag color + */ + public static void setNewFlagColor(Block flagBlock, ChatColor flagColor) { + final BlockData originalBlockData = flagBlock.getBlockData().clone(); + Material newMaterial = ColorUtils.getColoredMaterialFromChatColor(flagColor, flagBlock.getType()); + BlockData newData = Bukkit.getServer().createBlockData(newMaterial); + + if(originalBlockData instanceof Directional) { + ((Directional) newData).setFacing(((Directional) originalBlockData).getFacing()); + } + + if(originalBlockData instanceof Rotatable) { + ((Rotatable) newData).setRotation(((Rotatable) originalBlockData).getRotation()); + } + + flagBlock.setBlockData(newData); + } } diff --git a/src/net/slipcor/pvparena/core/Config.java b/src/net/slipcor/pvparena/core/Config.java index dff88f91f..a67865933 100644 --- a/src/net/slipcor/pvparena/core/Config.java +++ b/src/net/slipcor/pvparena/core/Config.java @@ -206,7 +206,7 @@ public enum CFG { GOAL_DOM_CLAIMRANGE("goal.dom.claimrange", 3, "Domination"), GOAL_DOM_LIVES("goal.dom.dlives", 10, "Domination"), GOAL_DOM_ONLYWHENMORE("goal.dom.onlywhenmore", false, "Domination"), - GOAL_DOM_PARTICLECIRCLE("goal.dom.particlecircle", false, "Domination"), + GOAL_DOM_PARTICLECIRCLE("goal.dom.particlecircle", true, "Domination"), GOAL_DOM_TICKINTERVAL("goal.dom.tickinterval", 60, "Domination"), GOAL_DOM_TICKREWARD("goal.dom.tickreward", 1, "Domination"), @@ -215,6 +215,7 @@ public enum CFG { GOAL_FLAGS_MUSTBESAFE("goal.flags.mustBeSafe", true, "Flags"), GOAL_FLAGS_WOOLFLAGHEAD("goal.flags.woolFlagHead", true, "Flags"), GOAL_FLAGS_FLAGEFFECT("goal.flags.effect", "none", "Flags"), + GOAL_FLAGS_ALTERONCATCH("goal.flags.alterOnCatch", true, "Flags"), GOAL_FOOD_FMAXITEMS("goal.food.fmaxitems", 50, "Food"), GOAL_FOOD_FPLAYERITEMS("goal.food.fplayeritems", 10, "Food"), @@ -228,6 +229,13 @@ public enum CFG { GOAL_LLIVES_LIVES("goal.liberation.llives", 3, "Liberation"), GOAL_PDM_LIVES("goal.playerdm.pdlives", 3, "PlayerDeathMatch"), + + GOAL_PFLAGS_FLAGTYPE("goal.physicalflags.flagType", Material.WHITE_WOOL, "PhysicalFlags"), + GOAL_PFLAGS_LIVES("goal.physicalflags.flives", 3, "PhysicalFlags"), + GOAL_PFLAGS_MUSTBESAFE("goal.physicalflags.mustBeSafe", true, "PhysicalFlags"), + GOAL_PFLAGS_WOOLFLAGHEAD("goal.physicalflags.woolFlagHead", true, "PhysicalFlags"), + GOAL_PFLAGS_FLAGEFFECT("goal.physicalflags.effect", "none", "PhysicalFlags"), + GOAL_PLIVES_LIVES("goal.playerlives.plives", 3, "PlayerLives"), GOAL_TANK_LIVES("goal.tank.tlives", 1, "Tank"), GOAL_TDC_LIVES("goal.teamdc.tdclives", 10, "TeamDeathConfirm"), @@ -534,7 +542,7 @@ public String getType() { } public String getModule() { - return module; + return this.module; } public boolean hasModule() { diff --git a/src/net/slipcor/pvparena/core/StringParser.java b/src/net/slipcor/pvparena/core/StringParser.java index f5e1efe13..e786b150b 100644 --- a/src/net/slipcor/pvparena/core/StringParser.java +++ b/src/net/slipcor/pvparena/core/StringParser.java @@ -91,8 +91,7 @@ public static String colorVar(final String string) { * @return a colored string */ public static String colorVar(final String string, final boolean value) { - return (value ? ChatColor.GREEN.toString() : ChatColor.RED.toString()) + string - + ChatColor.WHITE; + return (value ? ChatColor.GREEN.toString() : ChatColor.RED.toString()) + string + ChatColor.WHITE; } public static String joinArray(final Object[] array, final String glue) { diff --git a/src/net/slipcor/pvparena/goals/GoalDomination.java b/src/net/slipcor/pvparena/goals/GoalDomination.java index 12f3eda32..1778a586c 100644 --- a/src/net/slipcor/pvparena/goals/GoalDomination.java +++ b/src/net/slipcor/pvparena/goals/GoalDomination.java @@ -23,6 +23,7 @@ import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitTask; import java.util.*; @@ -37,11 +38,14 @@ public class GoalDomination extends ArenaGoal { + private static final int PRIORITY = 8; + private static final int INTERVAL = 200; + private BukkitTask circleTask = null; public GoalDomination() { super("Domination"); - debug = new Debug(99); + this.debug = new Debug(99); } private Map flagMap = new HashMap<>(); @@ -55,29 +59,27 @@ public String version() { return PVPArena.instance.getDescription().getVersion(); } - private static final int PRIORITY = 8; - @Override public boolean allowsJoinInBattle() { - return arena.getArenaConfig().getBoolean(CFG.PERMS_JOININBATTLE); + return this.arena.getArenaConfig().getBoolean(CFG.PERMS_JOININBATTLE); } - private void barStart(Location location, String title, ChatColor color, int range, long interval) { - if (!arena.getArenaConfig().getBoolean(CFG.GOAL_DOM_BOSSBAR)) { + private void barStart(Location location, String title, ChatColor color, int range) { + if (!this.arena.getArenaConfig().getBoolean(CFG.GOAL_DOM_BOSSBAR)) { return; } - if (getBarMap().containsKey(location)) { - PAClaimBar claimBar = getBarMap().get(location); - claimBar.restart(title, color, location, range, interval); + if (this.getBarMap().containsKey(location)) { + PAClaimBar claimBar = this.getBarMap().get(location); + claimBar.restart(title, color, location, range, INTERVAL); } else { - PAClaimBar claimBar = new PAClaimBar(arena, title, color, location, range, interval); - getBarMap().put(location, claimBar); + PAClaimBar claimBar = new PAClaimBar(this.arena, title, color, location, range, INTERVAL); + this.getBarMap().put(location, claimBar); } } private void barStop(Location location) { - if (getBarMap().containsKey(location)) { - getBarMap().get(location).stop(); + if (this.getBarMap().containsKey(location)) { + this.getBarMap().get(location).stop(); } } @@ -106,12 +108,12 @@ public PACheck checkEnd(final PACheck res) { return res; } - final int count = TeamManager.countActiveTeams(arena); + final int count = TeamManager.countActiveTeams(this.arena); if (count == 1) { res.setPriority(this, PRIORITY); // yep. only one team left. go! } else if (count == 0) { - arena.getDebugger().i("No teams playing!"); + this.arena.getDebugger().i("No teams playing!"); } return res; @@ -120,7 +122,7 @@ public PACheck checkEnd(final PACheck res) { @Override public String checkForMissingSpawns(final Set list) { - final String team = checkForMissingTeamSpawn(list); + final String team = this.checkForMissingTeamSpawn(list); if (team != null) { return team; } @@ -142,12 +144,12 @@ public PACheck checkJoin(final CommandSender sender, final PACheck res, final St return res; } - final int maxPlayers = arena.getArenaConfig().getInt(CFG.READY_MAXPLAYERS); - final int maxTeamPlayers = arena.getArenaConfig().getInt( + final int maxPlayers = this.arena.getArenaConfig().getInt(CFG.READY_MAXPLAYERS); + final int maxTeamPlayers = this.arena.getArenaConfig().getInt( CFG.READY_MAXTEAMPLAYERS); - if (maxPlayers > 0 && arena.getFighters().size() >= maxPlayers) { - res.setError(this, Language.parse(arena, MSG.ERROR_JOIN_ARENA_FULL)); + if (maxPlayers > 0 && this.arena.getFighters().size() >= maxPlayers) { + res.setError(this, Language.parse(this.arena, MSG.ERROR_JOIN_ARENA_FULL)); return res; } @@ -155,12 +157,12 @@ public PACheck checkJoin(final CommandSender sender, final PACheck res, final St return res; } - if (!arena.isFreeForAll()) { - final ArenaTeam team = arena.getTeam(args[0]); + if (!this.arena.isFreeForAll()) { + final ArenaTeam team = this.arena.getTeam(args[0]); if (team != null && maxTeamPlayers > 0 && team.getTeamMembers().size() >= maxTeamPlayers) { - res.setError(this, Language.parse(arena, MSG.ERROR_JOIN_TEAM_FULL, team.getName())); + res.setError(this, Language.parse(this.arena, MSG.ERROR_JOIN_TEAM_FULL, team.getName())); return res; } } @@ -181,7 +183,7 @@ private Set checkLocationPresentTeams(final Location loc, final int dist final Set result = new HashSet<>(); final Location flagCenter = Utils.getCenteredLocation(loc); - for (final ArenaPlayer p : arena.getFighters()) { + for (final ArenaPlayer p : this.arena.getFighters()) { if (p.get().getLocation().distance(flagCenter) > distance) { continue; @@ -219,130 +221,127 @@ void checkMove() { */ - arena.getDebugger().i("------------------"); - arena.getDebugger().i(" checkMove();"); - arena.getDebugger().i("------------------"); + this.arena.getDebugger().i("------------------"); + this.arena.getDebugger().i(" checkMove();"); + this.arena.getDebugger().i("------------------"); - final int checkDistance = arena.getArenaConfig().getInt(CFG.GOAL_DOM_CLAIMRANGE); + final int checkDistance = this.arena.getArenaConfig().getInt(CFG.GOAL_DOM_CLAIMRANGE); - for (final PABlockLocation paLoc : SpawnManager.getBlocksStartingWith(arena, "flag")) { + for (final PABlockLocation paLoc : SpawnManager.getBlocksStartingWith(this.arena, "flag")) { // arena.getDebugger().info("checking location: " + loc.toString()); final Location loc = paLoc.toLocation(); - final Set teams = checkLocationPresentTeams(loc, checkDistance); + final Set teams = this.checkLocationPresentTeams(loc, checkDistance); - arena.getDebugger().i("teams: " + StringParser.joinSet(teams, ", ")); + this.arena.getDebugger().i("teams: " + StringParser.joinSet(teams, ", ")); // teams now contains all teams near the flag if (teams.size() < 1) { // arena.getDebugger().info("=> noone there!"); // no one there - if (getRunnerMap().containsKey(loc)) { - arena.getDebugger().i("flag is being (un)claimed! Cancelling!"); + if (this.getRunnerMap().containsKey(loc)) { + this.arena.getDebugger().i("flag is being (un)claimed! Cancelling!"); // cancel unclaiming/claiming if noone's near - Bukkit.getScheduler().cancelTask(getRunnerMap().get(loc).runID); - getRunnerMap().remove(loc); - barStop(loc); + this.getRunnerMap().get(loc).cancel(); + this.getRunnerMap().remove(loc); + this.barStop(loc); } - if (getFlagMap().containsKey(loc)) { - final String team = getFlagMap().get(loc); + if (this.getFlagMap().containsKey(loc)) { + final String team = this.getFlagMap().get(loc); - if (!getLifeMap().containsKey(team)) { + if (!this.getLifeMap().containsKey(team)) { continue; } // flag claimed! add score! - maybeAddScoreAndBroadCast(team); + this.maybeAddScoreAndBroadCast(team); } continue; } // there are actually teams at the flag - arena.getDebugger().i("=> at least one team is at the flag!"); + this.arena.getDebugger().i("=> at least one team is at the flag!"); - if (getFlagMap().containsKey(loc)) { + if (this.getFlagMap().containsKey(loc)) { // flag is taken. by whom? - if (teams.contains(getFlagMap().get(loc))) { + if (teams.contains(this.getFlagMap().get(loc))) { // owning team is there - arena.getDebugger().i(" - owning team is there"); + this.arena.getDebugger().i(" - owning team is there"); if (teams.size() > 1) { // another team is there - arena.getDebugger().i(" - and another one"); - if (getRunnerMap().containsKey(loc)) { + this.arena.getDebugger().i(" - and another one"); + if (this.getRunnerMap().containsKey(loc)) { // it is being unclaimed - arena.getDebugger().i(" - being unclaimed. continue!"); + this.arena.getDebugger().i(" - being unclaimed. continue!"); } else { // unclaim - arena.getDebugger().i(" - not being unclaimed. do it!"); - ArenaTeam team = arena.getTeam(getFlagMap().get(loc)); - String contestingMsg = Language.parse(arena, MSG.GOAL_DOMINATION_CONTESTING, team.getColoredName() + ChatColor.YELLOW); - arena.broadcast(contestingMsg); + this.arena.getDebugger().i(" - not being unclaimed. do it!"); + ArenaTeam team = this.arena.getTeam(this.getFlagMap().get(loc)); + String contestingMsg = Language.parse(this.arena, MSG.GOAL_DOMINATION_CONTESTING, team.getColoredName() + ChatColor.YELLOW); + this.arena.broadcast(contestingMsg); final DominationRunnable domRunner = new DominationRunnable( - arena, false, loc, - getFlagMap().get(loc), this); - domRunner.runID = Bukkit.getScheduler() - .scheduleSyncRepeatingTask(PVPArena.instance, domRunner, 10 * 20L, 10 * 20L); + this.arena, false, loc, + this.getFlagMap().get(loc), this); - getRunnerMap().put(loc, domRunner); - barStart(loc, contestingMsg, ChatColor.WHITE, checkDistance, 200L); + domRunner.runTaskTimer(PVPArena.instance, INTERVAL, INTERVAL); + + this.getRunnerMap().put(loc, domRunner); + this.barStart(loc, contestingMsg, ChatColor.WHITE, checkDistance); } } else { // just the owning team is there - arena.getDebugger().i(" - noone else"); - if (getRunnerMap().containsKey(loc)) { - arena.getDebugger().i(" - being unclaimed. cancel!"); + this.arena.getDebugger().i(" - noone else"); + if (this.getRunnerMap().containsKey(loc)) { + this.arena.getDebugger().i(" - being unclaimed. cancel!"); // it is being unclaimed // cancel task! - Bukkit.getScheduler() - .cancelTask(getRunnerMap().get(loc).runID); - getRunnerMap().remove(loc); - barStop(loc); + this.getRunnerMap().get(loc).cancel(); + this.getRunnerMap().remove(loc); + this.barStop(loc); } else { - final String team = getFlagMap().get(loc); + final String team = this.getFlagMap().get(loc); - if (!getLifeMap().containsKey(team)) { + if (!this.getLifeMap().containsKey(team)) { continue; } - maybeAddScoreAndBroadCast(team); + this.maybeAddScoreAndBroadCast(team); } } continue; } - arena.getDebugger().i(" - owning team is not there!"); + this.arena.getDebugger().i(" - owning team is not there!"); // owning team is NOT there ==> unclaim! - if (getRunnerMap().containsKey(loc)) { - if (getRunnerMap().get(loc).take) { - arena.getDebugger().i(" - runnable is trying to score, abort"); + if (this.getRunnerMap().containsKey(loc)) { + if (this.getRunnerMap().get(loc).isTaken()) { + this.arena.getDebugger().i(" - runnable is trying to score, abort"); - Bukkit.getScheduler().cancelTask(getRunnerMap().get(loc).runID); - getRunnerMap().remove(loc); + this.getRunnerMap().get(loc).cancel(); + this.getRunnerMap().remove(loc); } else { - arena.getDebugger().i(" - being unclaimed. continue."); + this.arena.getDebugger().i(" - being unclaimed. continue."); } continue; } - arena.getDebugger().i(" - not yet being unclaimed, do it!"); + this.arena.getDebugger().i(" - not yet being unclaimed, do it!"); // create an unclaim runnable - ArenaTeam team = arena.getTeam(getFlagMap().get(loc)); - String unclaimingMsg = Language.parse(arena, MSG.GOAL_DOMINATION_UNCLAIMING, team.getColoredName() + ChatColor.YELLOW); - arena.broadcast(unclaimingMsg); - final DominationRunnable running = new DominationRunnable(arena, - false, loc, getFlagMap().get(loc), this); - final long interval = 20L * 10; - - running.runID = Bukkit.getScheduler().scheduleSyncRepeatingTask( - PVPArena.instance, running, interval, interval); - getRunnerMap().put(loc, running); - barStart(loc, unclaimingMsg, ChatColor.WHITE, checkDistance, interval); + ArenaTeam team = this.arena.getTeam(this.getFlagMap().get(loc)); + String unclaimingMsg = Language.parse(this.arena, MSG.GOAL_DOMINATION_UNCLAIMING, team.getColoredName() + ChatColor.YELLOW); + this.arena.broadcast(unclaimingMsg); + final DominationRunnable running = new DominationRunnable(this.arena, + false, loc, this.getFlagMap().get(loc), this); + + running.runTaskTimer(PVPArena.instance, INTERVAL, INTERVAL); + this.getRunnerMap().put(loc, running); + this.barStart(loc, unclaimingMsg, ChatColor.WHITE, checkDistance); } else { // flag not taken - arena.getDebugger().i("- flag not taken"); + this.arena.getDebugger().i("- flag not taken"); /* * check if a runnable @@ -355,46 +354,43 @@ void checkMove() { * yes => create runnable; * no => continue */ - if (getRunnerMap().containsKey(loc)) { - arena.getDebugger().i(" - being claimed"); + if (this.getRunnerMap().containsKey(loc)) { + this.arena.getDebugger().i(" - being claimed"); if (teams.size() < 2) { - arena.getDebugger().i(" - only one team present"); - if (teams.contains(getRunnerMap().get(loc).team)) { + this.arena.getDebugger().i(" - only one team present"); + if (teams.contains(this.getRunnerMap().get(loc).team)) { // just THE team that is claiming => NEXT - arena.getDebugger().i(" - claiming team present. next!"); + this.arena.getDebugger().i(" - claiming team present. next!"); continue; } } - arena.getDebugger().i(" - more than one team or another team. cancel claim!"); + this.arena.getDebugger().i(" - more than one team or another team. cancel claim!"); // more than THE team that is claiming => cancel! - Bukkit.getScheduler().cancelTask(getRunnerMap().get(loc).runID); - getRunnerMap().remove(loc); - barStop(loc); + this.getRunnerMap().get(loc).cancel(); + this.getRunnerMap().remove(loc); + this.barStop(loc); } else { - arena.getDebugger().i(" - not being claimed"); + this.arena.getDebugger().i(" - not being claimed"); // not being claimed if (teams.size() < 2) { - arena.getDebugger().i(" - just one team present"); + this.arena.getDebugger().i(" - just one team present"); for (final String sName : teams) { - arena.getDebugger().i("TEAM " + sName + " IS CLAIMING " + this.arena.getDebugger().i("TEAM " + sName + " IS CLAIMING " + loc); - final ArenaTeam team = arena.getTeam(sName); - String claimingMsg = Language.parse(arena, MSG.GOAL_DOMINATION_CLAIMING, + final ArenaTeam team = this.arena.getTeam(sName); + String claimingMsg = Language.parse(this.arena, MSG.GOAL_DOMINATION_CLAIMING, team.getColoredName() + ChatColor.YELLOW); - arena.broadcast(claimingMsg); + this.arena.broadcast(claimingMsg); final DominationRunnable running = new DominationRunnable( - arena, true, loc, sName, this); - final long interval = 20L * 10; - running.runID = Bukkit.getScheduler() - .scheduleSyncRepeatingTask( - PVPArena.instance, running, - interval, interval); - getRunnerMap().put(loc, running); - barStart(loc, claimingMsg, team.getColor(), checkDistance, interval); + this.arena, true, loc, sName, this); + + running.runTaskTimer(PVPArena.instance, INTERVAL, INTERVAL); + this.getRunnerMap().put(loc, running); + this.barStart(loc, claimingMsg, team.getColor(), checkDistance); } } else { - arena.getDebugger().i(" - more than one team present. continue!"); + this.arena.getDebugger().i(" - more than one team present. continue!"); } } } @@ -402,9 +398,9 @@ void checkMove() { } private void maybeAddScoreAndBroadCast(final String team) { - if (arena.getArenaConfig().getBoolean(CFG.GOAL_DOM_ONLYWHENMORE)) { + if (this.arena.getArenaConfig().getBoolean(CFG.GOAL_DOM_ONLYWHENMORE)) { final Map claimed = new HashMap<>(); - for (final String s : getFlagMap().values()) { + for (final String s : this.getFlagMap().values()) { final int toAdd; if (claimed.containsKey(s)) { toAdd = claimed.get(s) + 1; @@ -423,29 +419,28 @@ private void maybeAddScoreAndBroadCast(final String team) { } } - reduceLivesCheckEndAndCommit(arena, team); + this.reduceLivesCheckEndAndCommit(this.arena, team); - final int max = arena.getArenaConfig().getInt(CFG.GOAL_DOM_LIVES); - if (!getLifeMap().containsKey(team)) { + final int max = this.arena.getArenaConfig().getInt(CFG.GOAL_DOM_LIVES); + if (!this.getLifeMap().containsKey(team)) { return; } - final int lives = getLifeMap().get(team); + final int lives = this.getLifeMap().get(team); - if ((max - lives) % announceOffset != 0) { + if ((max - lives) % this.announceOffset != 0) { return; } - arena.broadcast(Language.parse(arena, MSG.GOAL_DOMINATION_SCORE, - arena.getTeam(team).getColoredName() + this.arena.broadcast(Language.parse(this.arena, MSG.GOAL_DOMINATION_SCORE, + this.arena.getTeam(team).getColoredName() + ChatColor.YELLOW, (max - lives) + "/" + max)); } @Override public PACheck checkSetBlock(final PACheck res, final Player player, final Block block) { - if (res.getPriority() > PRIORITY - || !PAA_Region.activeSelections.containsKey(player.getName())) { + if (res.getPriority() > PRIORITY || !PAA_Region.activeSelections.containsKey(player.getName())) { return res; } if (block == null || !ColorUtils.isColorableMaterial(block.getType())) { @@ -505,7 +500,7 @@ private void commit(final Arena arena, final String sTeam) { + ChatColor.YELLOW)); } - getLifeMap().clear(); + this.getLifeMap().clear(); new EndRunnable(arena, arena.getArenaConfig().getInt( CFG.TIME_ENDCOUNTDOWN)); } @@ -514,27 +509,27 @@ private void commit(final Arena arena, final String sTeam) { public void commitCommand(final CommandSender sender, final String[] args) { if (PAA_Region.activeSelections.containsKey(sender.getName())) { PAA_Region.activeSelections.remove(sender.getName()); - arena.msg(sender, Language.parse(arena, MSG.GOAL_FLAGS_SET, "flags")); + this.arena.msg(sender, Language.parse(this.arena, MSG.GOAL_FLAGS_SET, "flags")); } else { - PAA_Region.activeSelections.put(sender.getName(), arena); - arena.msg(sender, Language.parse(arena, MSG.GOAL_FLAGS_TOSET, "flags")); + PAA_Region.activeSelections.put(sender.getName(), this.arena); + this.arena.msg(sender, Language.parse(this.arena, MSG.GOAL_FLAGS_TOSET, "flags")); } } @Override public void commitEnd(final boolean force) { - if (arena.realEndRunner != null) { - arena.getDebugger().i("[DOMINATION] already ending"); + if (this.arena.realEndRunner != null) { + this.arena.getDebugger().i("[DOMINATION] already ending"); return; } - arena.getDebugger().i("[DOMINATION]"); + this.arena.getDebugger().i("[DOMINATION]"); - final PAGoalEvent gEvent = new PAGoalEvent(arena, this, ""); + final PAGoalEvent gEvent = new PAGoalEvent(this.arena, this, ""); Bukkit.getPluginManager().callEvent(gEvent); ArenaTeam aTeam = null; - for (final ArenaTeam team : arena.getTeams()) { + for (final ArenaTeam team : this.arena.getTeams()) { for (final ArenaPlayer ap : team.getTeamMembers()) { if (ap.getStatus() == Status.FIGHT) { aTeam = team; @@ -545,22 +540,22 @@ public void commitEnd(final boolean force) { if (aTeam != null && !force) { ArenaModuleManager.announce( - arena, - Language.parse(arena, MSG.TEAM_HAS_WON, aTeam.getColor() + this.arena, + Language.parse(this.arena, MSG.TEAM_HAS_WON, aTeam.getColor() + aTeam.getName() + ChatColor.YELLOW), "END"); ArenaModuleManager.announce( - arena, - Language.parse(arena, MSG.TEAM_HAS_WON, aTeam.getColor() + this.arena, + Language.parse(this.arena, MSG.TEAM_HAS_WON, aTeam.getColor() + aTeam.getName() + ChatColor.YELLOW), "WINNER"); - arena.broadcast(Language.parse(arena, MSG.TEAM_HAS_WON, aTeam.getColor() + this.arena.broadcast(Language.parse(this.arena, MSG.TEAM_HAS_WON, aTeam.getColor() + aTeam.getName() + ChatColor.YELLOW)); } - if (ArenaModuleManager.commitEnd(arena, aTeam)) { + if (ArenaModuleManager.commitEnd(this.arena, aTeam)) { return; } - new EndRunnable(arena, arena.getArenaConfig().getInt( + new EndRunnable(this.arena, this.arena.getArenaConfig().getInt( CFG.TIME_ENDCOUNTDOWN)); } @@ -568,13 +563,11 @@ public void commitEnd(final boolean force) { public boolean commitSetFlag(final Player player, final Block block) { if (PVPArena.hasAdminPerms(player) - || PVPArena.hasCreatePerms(player, arena) - && player.getEquipment().getItemInMainHand() != null - && player.getEquipment().getItemInMainHand().getType().toString().equals(arena + || PVPArena.hasCreatePerms(player, this.arena) + && player.getInventory().getItemInMainHand().getType().toString().equals(this.arena .getArenaConfig().getString(CFG.GENERAL_WAND))) { - final Set flags = SpawnManager.getBlocksStartingWith(arena, - "flag"); + final Set flags = SpawnManager.getBlocksStartingWith(this.arena,"flag"); if (flags.contains(new PABlockLocation(block.getLocation()))) { return false; @@ -582,10 +575,9 @@ public boolean commitSetFlag(final Player player, final Block block) { final String flagName = "flag" + flags.size(); - SpawnManager.setBlock(arena, - new PABlockLocation(block.getLocation()), flagName); + SpawnManager.setBlock(this.arena, new PABlockLocation(block.getLocation()), flagName); - arena.msg(player, Language.parse(arena, MSG.GOAL_FLAGS_SET, flagName)); + this.arena.msg(player, Language.parse(this.arena, MSG.GOAL_FLAGS_SET, flagName)); return true; } return false; @@ -593,24 +585,22 @@ public boolean commitSetFlag(final Player player, final Block block) { @Override public void displayInfo(final CommandSender sender) { - sender.sendMessage("needed points: " + - arena.getArenaConfig().getInt(CFG.GOAL_DOM_LIVES)); - sender.sendMessage("claim range: " + - arena.getArenaConfig().getInt(CFG.GOAL_DOM_CLAIMRANGE)); + sender.sendMessage("needed points: " + this.arena.getArenaConfig().getInt(CFG.GOAL_DOM_LIVES)); + sender.sendMessage("claim range: " + this.arena.getArenaConfig().getInt(CFG.GOAL_DOM_CLAIMRANGE)); } private Map getFlagMap() { - if (flagMap == null) { - flagMap = new HashMap<>(); + if (this.flagMap == null) { + this.flagMap = new HashMap<>(); } - return flagMap; + return this.flagMap; } private Map getBarMap() { - if (flagBars == null) { - flagBars = new HashMap<>(); + if (this.flagBars == null) { + this.flagBars = new HashMap<>(); } - return flagBars; + return this.flagBars; } @Override @@ -618,29 +608,29 @@ public PACheck getLives(final PACheck res, final ArenaPlayer aPlayer) { if (res.getPriority() <= PRIORITY + 1000) { res.setError( this, - String.valueOf(getLifeMap().getOrDefault(aPlayer.getArenaTeam().getName(), 0)) + String.valueOf(this.getLifeMap().getOrDefault(aPlayer.getArenaTeam().getName(), 0)) ); } return res; } private Map getRunnerMap() { - if (runnerMap == null) { - runnerMap = new HashMap<>(); + if (this.runnerMap == null) { + this.runnerMap = new HashMap<>(); } - return runnerMap; + return this.runnerMap; } @Override public boolean hasSpawn(final String string) { - for (final String teamName : arena.getTeamNames()) { + for (final String teamName : this.arena.getTeamNames()) { if (string.toLowerCase().startsWith( teamName.toLowerCase() + "spawn")) { return true; } - if (arena.getArenaConfig().getBoolean(CFG.GENERAL_CLASSSPAWN)) { - for (final ArenaClass aClass : arena.getClasses()) { + if (this.arena.getArenaConfig().getBoolean(CFG.GENERAL_CLASSSPAWN)) { + for (final ArenaClass aClass : this.arena.getClasses()) { if (string.toLowerCase().startsWith(teamName.toLowerCase() + aClass.getName().toLowerCase() + "spawn")) { return true; @@ -655,13 +645,13 @@ public boolean hasSpawn(final String string) { public void initate(final Player player) { final ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(player.getName()); final ArenaTeam team = aPlayer.getArenaTeam(); - if (!getLifeMap().containsKey(team.getName())) { - getLifeMap().put(aPlayer.getArenaTeam().getName(), arena.getArenaConfig() + if (!this.getLifeMap().containsKey(team.getName())) { + this.getLifeMap().put(aPlayer.getArenaTeam().getName(), this.arena.getArenaConfig() .getInt(CFG.GOAL_DOM_LIVES)); - final Set spawns = SpawnManager.getBlocksStartingWith(arena, "flag"); + final Set spawns = SpawnManager.getBlocksStartingWith(this.arena, "flag"); for (final PABlockLocation spawn : spawns) { - takeFlag(spawn); + this.takeFlag(spawn); } } } @@ -673,68 +663,65 @@ public boolean isInternal() { @Override public void parseStart() { - getLifeMap().clear(); - for (final ArenaTeam team : arena.getTeams()) { + this.getLifeMap().clear(); + for (final ArenaTeam team : this.arena.getTeams()) { if (!team.getTeamMembers().isEmpty()) { - arena.getDebugger().i("adding team " + team.getName()); + this.arena.getDebugger().i("adding team " + team.getName()); // team is active - getLifeMap().put(team.getName(), - arena.getArenaConfig().getInt(CFG.GOAL_DOM_LIVES, 3)); + this.getLifeMap().put(team.getName(), + this.arena.getArenaConfig().getInt(CFG.GOAL_DOM_LIVES, 3)); } } - final Set spawns = SpawnManager.getBlocksStartingWith(arena, "flag"); + final Set spawns = SpawnManager.getBlocksStartingWith(this.arena, "flag"); for (final PABlockLocation spawn : spawns) { - takeFlag(spawn); + this.takeFlag(spawn); } - final DominationMainRunnable domMainRunner = new DominationMainRunnable(arena, this); - final int tickInterval = arena.getArenaConfig().getInt(CFG.GOAL_DOM_TICKINTERVAL); - domMainRunner.rID = Bukkit.getScheduler().scheduleSyncRepeatingTask( - PVPArena.instance, domMainRunner, tickInterval, tickInterval); + final DominationMainRunnable domMainRunner = new DominationMainRunnable(this.arena, this); + final int tickInterval = this.arena.getArenaConfig().getInt(CFG.GOAL_DOM_TICKINTERVAL); + domMainRunner.runTaskTimer(PVPArena.instance, tickInterval, tickInterval); - announceOffset = arena.getArenaConfig().getInt(CFG.GOAL_DOM_ANNOUNCEOFFSET); + this.announceOffset = this.arena.getArenaConfig().getInt(CFG.GOAL_DOM_ANNOUNCEOFFSET); - if(arena.getArenaConfig().getBoolean(CFG.GOAL_DOM_PARTICLECIRCLE)) { - circleTask = Bukkit.getScheduler().runTaskTimer(PVPArena.instance, new CircleParticleRunnable(arena, CFG.GOAL_DOM_CLAIMRANGE, getFlagMap()), 1L, 1L); + if(this.arena.getArenaConfig().getBoolean(CFG.GOAL_DOM_PARTICLECIRCLE)) { + this.circleTask = Bukkit.getScheduler().runTaskTimer(PVPArena.instance, new CircleParticleRunnable(this.arena, CFG.GOAL_DOM_CLAIMRANGE, this.getFlagMap()), 1L, 1L); } } - private boolean reduceLivesCheckEndAndCommit(final Arena arena, final String team) { + private void reduceLivesCheckEndAndCommit(final Arena arena, final String team) { arena.getDebugger().i("reducing lives of team " + team); - if (getLifeMap().get(team) != null) { + if (this.getLifeMap().get(team) != null) { final int score = arena.getArenaConfig().getInt(CFG.GOAL_DOM_TICKREWARD); - final int iLives = getLifeMap().get(team) - score; + final int iLives = this.getLifeMap().get(team) - score; final PAGoalEvent gEvent = new PAGoalEvent(arena, this, "score:null:"+team+":"+score); Bukkit.getPluginManager().callEvent(gEvent); if (iLives > 0) { - getLifeMap().put(team, iLives); + this.getLifeMap().put(team, iLives); } else { - getLifeMap().remove(team); - commit(arena, team); - return true; + this.getLifeMap().remove(team); + this.commit(arena, team); } } - return false; } @Override public void reset(final boolean force) { - getBarMap().clear(); - getLifeMap().clear(); - getRunnerMap().clear(); - getFlagMap().clear(); - if (circleTask != null) { - circleTask.cancel(); - circleTask = null; + this.getBarMap().clear(); + this.getLifeMap().clear(); + this.getRunnerMap().clear(); + this.getFlagMap().clear(); + if (this.circleTask != null) { + this.circleTask.cancel(); + this.circleTask = null; } } @Override public void setDefaults(final YamlConfiguration config) { - if (arena.isFreeForAll()) { + if (this.arena.isFreeForAll()) { return; } @@ -742,7 +729,7 @@ public void setDefaults(final YamlConfiguration config) { config.set("teams", null); } if (config.get("teams") == null) { - arena.getDebugger().i("no teams defined, adding custom red and blue!"); + this.arena.getDebugger().i("no teams defined, adding custom red and blue!"); config.addDefault("teams.red", ChatColor.RED.name()); config.addDefault("teams.blue", ChatColor.BLUE.name()); } @@ -754,15 +741,14 @@ public void setDefaults(final YamlConfiguration config) { * @param paBlockLocation the location to take/reset*/ private void takeFlag(final PABlockLocation paBlockLocation) { Block flagBlock = paBlockLocation.toLocation().getBlock(); - flagBlock.setType(ColorUtils.getColoredMaterialFromChatColor(ChatColor.WHITE, flagBlock.getType())); + ColorUtils.setNewFlagColor(flagBlock, ChatColor.WHITE); } @Override public Map timedEnd(final Map scores) { - for (final ArenaTeam team : arena.getTeams()) { - double score = getLifeMap().containsKey(team.getName()) ? getLifeMap() - .get(team.getName()) : 0; + for (final ArenaTeam team : this.arena.getTeams()) { + double score = this.getLifeMap().getOrDefault(team.getName(), 0); if (scores.containsKey(team.getName())) { scores.put(team.getName(), scores.get(team.getName()) + score); } else { @@ -773,13 +759,11 @@ public Map timedEnd(final Map scores) { return scores; } - class DominationRunnable implements Runnable { - public final boolean take; - public final Location loc; - public int runID = -1; + private static class DominationRunnable extends BukkitRunnable { + private final boolean taken; + private final Location loc; private final Arena arena; public final String team; - //private final Debug debug = new Debug(39); private final GoalDomination domination; /** @@ -787,13 +771,13 @@ class DominationRunnable implements Runnable { * * @param arena the arena we are running in */ - public DominationRunnable(final Arena arena, final boolean take, final Location loc2, final String teamName, + public DominationRunnable(final Arena arena, final boolean taken, final Location loc2, final String teamName, final GoalDomination goal) { this.arena = arena; - this.take = take; - team = teamName; - loc = loc2; - domination = goal; + this.taken = taken; + this.team = teamName; + this.loc = loc2; + this.domination = goal; arena.getDebugger().i("Domination constructor"); } @@ -802,33 +786,33 @@ public DominationRunnable(final Arena arena, final boolean take, final Location */ @Override public void run() { - arena.getDebugger().i("DominationRunnable commiting"); - arena.getDebugger().i("team " + team + ", take: " + take); - if (take) { + this.arena.getDebugger().i("DominationRunnable commiting"); + this.arena.getDebugger().i("team " + this.team + ", take: " + this.taken); + if (this.taken) { // claim a flag for the team - if (!domination.getFlagMap().containsKey(loc)) { + if (!this.domination.getFlagMap().containsKey(this.loc)) { // flag unclaimed! claim! - arena.getDebugger().i("clag unclaimed. claim!"); - domination.getFlagMap().put(loc, team); + this.arena.getDebugger().i("clag unclaimed. claim!"); + this.domination.getFlagMap().put(this.loc, this.team); // long interval = 20L * 5; - arena.broadcast(Language.parse(arena, - MSG.GOAL_DOMINATION_CLAIMED, arena.getTeam(team) + this.arena.broadcast(Language.parse(this.arena, + MSG.GOAL_DOMINATION_CLAIMED, this.arena.getTeam(this.team) .getColoredName() + ChatColor.YELLOW)); - takeFlag(arena, loc, team); - domination.getFlagMap().put(loc, team); + this.takeFlag(this.arena, this.loc, this.team); + this.domination.getFlagMap().put(this.loc, this.team); // claim done. end timer - Bukkit.getScheduler().cancelTask(runID); - domination.getRunnerMap().remove(loc); + this.cancel(); + this.domination.getRunnerMap().remove(this.loc); } } else { // unclaim - arena.getDebugger().i("unclaimed"); - takeFlag(arena, loc, ""); - Bukkit.getScheduler().cancelTask(runID); - domination.getRunnerMap().remove(loc); - domination.getFlagMap().remove(loc); + this.arena.getDebugger().i("unclaimed"); + this.takeFlag(this.arena, this.loc, ""); + this.cancel(); + this.domination.getRunnerMap().remove(this.loc); + this.domination.getFlagMap().remove(this.loc); } } @@ -842,22 +826,24 @@ private void takeFlag(final Arena arena, final Location lBlock, final String nam } } if (team == null) { - flagBlock.setType(ColorUtils.getColoredMaterialFromChatColor(ChatColor.WHITE, flagBlock.getType())); - return; + ColorUtils.setNewFlagColor(flagBlock, ChatColor.WHITE); + } else { + ColorUtils.setNewFlagColor(flagBlock, team.getColor()); } - flagBlock.setType(ColorUtils.getColoredMaterialFromChatColor(team.getColor(), flagBlock.getType())); + } + + private boolean isTaken() { + return this.taken; } } - class DominationMainRunnable implements Runnable { - public int rID = -1; + private static class DominationMainRunnable extends BukkitRunnable { private final Arena arena; - //private final Debug debug = new Debug(39); private final GoalDomination domination; public DominationMainRunnable(final Arena arena, final GoalDomination goal) { this.arena = arena; - domination = goal; + this.domination = goal; arena.getDebugger().i("DominationMainRunnable constructor"); } @@ -866,10 +852,10 @@ public DominationMainRunnable(final Arena arena, final GoalDomination goal) { */ @Override public void run() { - if (!arena.isFightInProgress() || arena.realEndRunner != null) { - Bukkit.getScheduler().cancelTask(rID); + if (!this.arena.isFightInProgress() || this.arena.realEndRunner != null) { + this.cancel(); } - domination.checkMove(); + this.domination.checkMove(); } } } diff --git a/src/net/slipcor/pvparena/goals/GoalFlags.java b/src/net/slipcor/pvparena/goals/GoalFlags.java index 47cd119b4..764dc332d 100644 --- a/src/net/slipcor/pvparena/goals/GoalFlags.java +++ b/src/net/slipcor/pvparena/goals/GoalFlags.java @@ -20,10 +20,11 @@ import net.slipcor.pvparena.managers.StatisticsManager.type; import net.slipcor.pvparena.managers.TeamManager; import net.slipcor.pvparena.runnables.EndRunnable; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; +import org.bukkit.*; import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.Directional; +import org.bukkit.block.data.Rotatable; import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; @@ -52,26 +53,26 @@ public class GoalFlags extends ArenaGoal implements Listener { - public GoalFlags() { - super("Flags"); - debug = new Debug(100); - } - + private static final int PRIORITY = 6; + private static final String TOUCHDOWN = "touchdown"; private Map flagMap; private Map headGearMap; private String flagName = ""; + public GoalFlags() { + super("Flags"); + this.debug = new Debug(100); + } + @Override public String version() { return PVPArena.instance.getDescription().getVersion(); } - private static final int PRIORITY = 6; - @Override public boolean allowsJoinInBattle() { - return arena.getArenaConfig().getBoolean(CFG.PERMS_JOININBATTLE); + return this.arena.getArenaConfig().getBoolean(CFG.PERMS_JOININBATTLE); } @Override @@ -80,13 +81,11 @@ public PACheck checkCommand(final PACheck res, final String string) { return res; } - if ("flagtype".equalsIgnoreCase(string) - || "flageffect".equalsIgnoreCase(string) - || "touchdown".equalsIgnoreCase(string)) { + if ("flagtype".equalsIgnoreCase(string) || "flageffect".equalsIgnoreCase(string) || TOUCHDOWN.equalsIgnoreCase(string)) { res.setPriority(this, PRIORITY); } - for (final ArenaTeam team : arena.getTeams()) { + for (final ArenaTeam team : this.arena.getTeams()) { final String sTeam = team.getName(); if (string.contains(sTeam + "flag")) { res.setPriority(this, PRIORITY); @@ -98,9 +97,9 @@ public PACheck checkCommand(final PACheck res, final String string) { @Override public List getMain() { - final List result = Arrays.asList("flagtype", "flageffect", "touchdown"); - if (arena != null) { - for (final ArenaTeam team : arena.getTeams()) { + final List result = Arrays.asList("flagtype", "flageffect", TOUCHDOWN); + if (this.arena != null) { + for (final ArenaTeam team : this.arena.getTeams()) { final String sTeam = team.getName(); result.add(sTeam + "flag"); } @@ -122,12 +121,12 @@ public PACheck checkEnd(final PACheck res) { return res; } - final int count = TeamManager.countActiveTeams(arena); + final int count = TeamManager.countActiveTeams(this.arena); if (count == 1) { res.setPriority(this, PRIORITY); // yep. only one team left. go! } else if (count == 0) { - arena.getDebugger().i("No teams playing!"); + this.arena.getDebugger().i("No teams playing!"); } return res; @@ -135,12 +134,12 @@ public PACheck checkEnd(final PACheck res) { @Override public String checkForMissingSpawns(final Set list) { - final String team = checkForMissingTeamSpawn(list); + final String team = this.checkForMissingTeamSpawn(list); if (team != null) { return team; } - return checkForMissingTeamCustom(list, "flag"); + return this.checkForMissingTeamCustom(list, "flag"); } /** @@ -156,112 +155,109 @@ public PACheck checkInteract(final PACheck res, final Player player, final Block if (block == null || res.getPriority() > PRIORITY) { return res; } - arena.getDebugger().i("checking interact", player); - if (arena.realEndRunner != null) { - arena.getDebugger().i("[CTF] already ending!!"); + this.arena.getDebugger().i("checking interact", player); + if (this.arena.realEndRunner != null) { + this.arena.getDebugger().i("[CTF] already ending!!"); return res; } - Material flagType = arena.getArenaConfig().getMaterial(CFG.GOAL_FLAGS_FLAGTYPE); + Material flagType = this.arena.getArenaConfig().getMaterial(CFG.GOAL_FLAGS_FLAGTYPE); if (!ColorUtils.isSubType(block.getType(), flagType)) { - arena.getDebugger().i("block, but not flag", player); + this.arena.getDebugger().i("block, but not flag", player); return res; } - arena.getDebugger().i("flag click!", player); + this.arena.getDebugger().i("flag click!", player); Vector vLoc; Vector vFlag = null; final ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(player.getName()); - if (getFlagMap().containsValue(player.getName())) { - arena.getDebugger().i("player " + player.getName() + " has got a flag", player); + if (this.getFlagMap().containsValue(player.getName())) { + this.arena.getDebugger().i("player " + player.getName() + " has got a flag", player); vLoc = block.getLocation().toVector(); final String sTeam = aPlayer.getArenaTeam().getName(); - arena.getDebugger().i("block: " + vLoc, player); - if (!SpawnManager.getBlocksStartingWith(arena, sTeam + "flag").isEmpty()) { + this.arena.getDebugger().i("block: " + vLoc, player); + if (!SpawnManager.getBlocksStartingWith(this.arena, sTeam + "flag").isEmpty()) { vFlag = SpawnManager .getBlockNearest( - SpawnManager.getBlocksStartingWith(arena, sTeam + "flag"), + SpawnManager.getBlocksStartingWith(this.arena, sTeam + "flag"), new PABlockLocation(player.getLocation())) .toLocation().toVector(); } else { - arena.getDebugger().i(sTeam + "flag = null", player); + this.arena.getDebugger().i(sTeam + "flag = null", player); } - arena.getDebugger().i("player is in the team " + sTeam, player); + this.arena.getDebugger().i("player is in the team " + sTeam, player); if (vFlag != null && vLoc.distance(vFlag) < 2) { - arena.getDebugger().i("player is at his flag", player); + this.arena.getDebugger().i("player is at his flag", player); - if (getFlagMap().containsKey(sTeam) - || getFlagMap().containsKey("touchdown")) { - arena.getDebugger().i("the flag of the own team is taken!", player); + if (this.getFlagMap().containsKey(sTeam) || this.getFlagMap().containsKey(TOUCHDOWN)) { + this.arena.getDebugger().i("the flag of the own team is taken!", player); - if (arena.getArenaConfig().getBoolean( + if (this.arena.getArenaConfig().getBoolean( CFG.GOAL_FLAGS_MUSTBESAFE) - && !getFlagMap().containsKey("touchdown")) { - arena.getDebugger().i("cancelling", player); + && !this.getFlagMap().containsKey(TOUCHDOWN)) { + this.arena.getDebugger().i("cancelling", player); - arena.msg(player, - Language.parse(arena, MSG.GOAL_FLAGS_NOTSAFE)); + this.arena.msg(player, + Language.parse(this.arena, MSG.GOAL_FLAGS_NOTSAFE)); return res; } } - String flagTeam = getHeldFlagTeam(player.getName()); + String flagTeam = this.getHeldFlagTeam(player.getName()); - arena.getDebugger().i("the flag belongs to team " + flagTeam, player); + this.arena.getDebugger().i("the flag belongs to team " + flagTeam, player); try { - if ("touchdown".equals(flagTeam)) { - arena.broadcast(Language.parse(arena, - MSG.GOAL_FLAGS_TOUCHHOME, arena.getTeam(sTeam) + if (TOUCHDOWN.equals(flagTeam)) { + this.arena.broadcast(Language.parse(this.arena, + MSG.GOAL_FLAGS_TOUCHHOME, this.arena.getTeam(sTeam) .colorizePlayer(player) + ChatColor.YELLOW, String - .valueOf(getLifeMap().get(aPlayer + .valueOf(this.getLifeMap().get(aPlayer .getArenaTeam().getName()) - 1))); } else { - arena.broadcast(Language.parse(arena, - MSG.GOAL_FLAGS_BROUGHTHOME, arena + this.arena.broadcast(Language.parse(this.arena, + MSG.GOAL_FLAGS_BROUGHTHOME, this.arena .getTeam(sTeam).colorizePlayer(player) + ChatColor.YELLOW, - arena.getTeam(flagTeam).getColoredName() + this.arena.getTeam(flagTeam).getColoredName() + ChatColor.YELLOW, String - .valueOf(getLifeMap().get(flagTeam) - 1))); + .valueOf(this.getLifeMap().get(flagTeam) - 1))); } - getFlagMap().remove(flagTeam); + this.getFlagMap().remove(flagTeam); } catch (final Exception e) { Bukkit.getLogger().severe( "[PVP Arena] team unknown/no lives: " + flagTeam); e.printStackTrace(); } - if ("touchdown".equals(flagTeam)) { - takeFlag(ChatColor.BLACK, false, - SpawnManager.getBlockByExactName(arena, "touchdownflag")); + if (TOUCHDOWN.equals(flagTeam)) { + this.releaseFlag(ChatColor.BLACK, this.getTeamFlagLoc(TOUCHDOWN)); } else { - takeFlag(arena.getTeam(flagTeam).getColor(), false, - SpawnManager.getBlockByExactName(arena, flagTeam + "flag")); + this.releaseFlag(this.arena.getTeam(flagTeam).getColor(), this.getTeamFlagLoc(flagTeam)); } - removeEffects(player); - if (arena.getArenaConfig().getBoolean( + this.removeEffects(player); + if (this.arena.getArenaConfig().getBoolean( CFG.GOAL_FLAGS_WOOLFLAGHEAD)) { - if (getHeadGearMap().get(player.getName()) == null) { + if (this.getHeadGearMap().get(player.getName()) == null) { player.getInventory().setHelmet( new ItemStack(Material.AIR, 1)); } else { player.getInventory().setHelmet( - getHeadGearMap().get(player.getName()).clone()); - getHeadGearMap().remove(player.getName()); + this.getHeadGearMap().get(player.getName()).clone()); + this.getHeadGearMap().remove(player.getName()); } } - flagTeam = "touchdown".equals(flagTeam) ? flagTeam + ':' + aPlayer + flagTeam = TOUCHDOWN.equals(flagTeam) ? flagTeam + ':' + aPlayer .getArenaTeam().getName() : flagTeam; - reduceLivesCheckEndAndCommit(arena, flagTeam); // TODO move to + this.reduceLivesCheckEndAndCommit(this.arena, flagTeam); // TODO move to // "commit" ? - final PAGoalEvent gEvent = new PAGoalEvent(arena, this, "trigger:" + aPlayer.getName()); + final PAGoalEvent gEvent = new PAGoalEvent(this.arena, this, "trigger:" + aPlayer.getName()); Bukkit.getPluginManager().callEvent(gEvent); } } else { @@ -269,72 +265,72 @@ public PACheck checkInteract(final PACheck res, final Player player, final Block if (pTeam == null) { return res; } - final Set setTeam = new HashSet<>(); - for (final ArenaTeam team : arena.getTeams()) { - setTeam.add(team); - } - setTeam.add(new ArenaTeam("touchdown", "BLACK")); + final Set setTeam = new HashSet<>(this.arena.getTeams()); + + setTeam.add(new ArenaTeam(TOUCHDOWN, "BLACK")); for (final ArenaTeam team : setTeam) { final String aTeam = team.getName(); if (aTeam.equals(pTeam.getName())) { - arena.getDebugger().i("equals!OUT! ", player); + this.arena.getDebugger().i("equals!OUT! ", player); continue; } - if (team.getTeamMembers().size() < 1 - && !"touchdown".equals(team.getName())) { - arena.getDebugger().i("size!OUT! ", player); + + if (team.getTeamMembers().size() < 1 && !TOUCHDOWN.equals(team.getName())) { + this.arena.getDebugger().i("size!OUT! ", player); continue; // dont check for inactive teams } - if (getFlagMap() != null && getFlagMap().containsKey(aTeam)) { - arena.getDebugger().i("taken!OUT! ", player); + + if (this.getFlagMap() != null && this.getFlagMap().containsKey(aTeam)) { + this.arena.getDebugger().i("taken!OUT! ", player); continue; // already taken } - arena.getDebugger().i("checking for flag of team " + aTeam, player); + + this.arena.getDebugger().i("checking for flag of team " + aTeam, player); vLoc = block.getLocation().toVector(); - arena.getDebugger().i("block: " + vLoc, player); - if (!SpawnManager.getBlocksStartingWith(arena, aTeam + "flag").isEmpty()) { + this.arena.getDebugger().i("block: " + vLoc, player); + + if (!SpawnManager.getBlocksStartingWith(this.arena, aTeam + "flag").isEmpty()) { vFlag = SpawnManager .getBlockNearest( - SpawnManager.getBlocksStartingWith(arena, aTeam + SpawnManager.getBlocksStartingWith(this.arena, aTeam + "flag"), new PABlockLocation(player.getLocation())) .toLocation().toVector(); } + if (vFlag != null && vLoc.distance(vFlag) < 2) { - arena.getDebugger().i("flag found!", player); - arena.getDebugger().i("vFlag: " + vFlag, player); + this.arena.getDebugger().i("flag found!", player); + this.arena.getDebugger().i("vFlag: " + vFlag, player); - if ("touchdown".equals(team.getName())) { + if (TOUCHDOWN.equals(team.getName())) { - arena.broadcast(Language.parse(arena, + this.arena.broadcast(Language.parse(this.arena, MSG.GOAL_FLAGS_GRABBEDTOUCH, pTeam.colorizePlayer(player) + ChatColor.YELLOW)); } else { - arena.broadcast(Language - .parse(arena, MSG.GOAL_FLAGS_GRABBED, + this.arena.broadcast(Language + .parse(this.arena, MSG.GOAL_FLAGS_GRABBED, pTeam.colorizePlayer(player) + ChatColor.YELLOW, team.getColoredName() + ChatColor.YELLOW)); } try { - getHeadGearMap().put(player.getName(), player.getInventory() - .getHelmet().clone()); - } catch (final Exception e) { + this.getHeadGearMap().put(player.getName(), player.getInventory().getHelmet().clone()); + } catch (final Exception ignored) { } - if (arena.getArenaConfig().getBoolean(CFG.GOAL_FLAGS_WOOLFLAGHEAD)) { - final ItemStack itemStack = new ItemStack(getFlagOverrideTeamMaterial(arena, aTeam)); + if (this.arena.getArenaConfig().getBoolean(CFG.GOAL_FLAGS_WOOLFLAGHEAD)) { + final ItemStack itemStack = new ItemStack(this.getFlagOverrideTeamMaterial(this.arena, aTeam)); player.getInventory().setHelmet(itemStack); } - applyEffects(player); + this.applyEffects(player); - takeFlag(team.getColor(), true, - new PABlockLocation(block.getLocation())); - getFlagMap().put(aTeam, player.getName()); // TODO move to + this.takeFlag(new PABlockLocation(block.getLocation())); + this.getFlagMap().put(aTeam, player.getName()); // TODO move to // "commit" ? return res; @@ -346,7 +342,7 @@ public PACheck checkInteract(final PACheck res, final Player player, final Block } private void applyEffects(final Player player) { - final String value = arena.getArenaConfig().getString( + final String value = this.arena.getArenaConfig().getString( CFG.GOAL_FLAGS_FLAGEFFECT); if ("none".equalsIgnoreCase(value)) { @@ -360,7 +356,7 @@ private void applyEffects(final Player player) { if (split.length > 1) { try { amp = Integer.parseInt(split[1]); - } catch (final Exception e) { + } catch (final Exception ignored) { } } @@ -390,12 +386,12 @@ public PACheck checkJoin(final CommandSender sender, final PACheck res, final St return res; } - final int maxPlayers = arena.getArenaConfig().getInt(CFG.READY_MAXPLAYERS); - final int maxTeamPlayers = arena.getArenaConfig().getInt( + final int maxPlayers = this.arena.getArenaConfig().getInt(CFG.READY_MAXPLAYERS); + final int maxTeamPlayers = this.arena.getArenaConfig().getInt( CFG.READY_MAXTEAMPLAYERS); - if (maxPlayers > 0 && arena.getFighters().size() >= maxPlayers) { - res.setError(this, Language.parse(arena, MSG.ERROR_JOIN_ARENA_FULL)); + if (maxPlayers > 0 && this.arena.getFighters().size() >= maxPlayers) { + res.setError(this, Language.parse(this.arena, MSG.ERROR_JOIN_ARENA_FULL)); return res; } @@ -403,12 +399,12 @@ public PACheck checkJoin(final CommandSender sender, final PACheck res, final St return res; } - if (!arena.isFreeForAll()) { - final ArenaTeam team = arena.getTeam(args[0]); + if (!this.arena.isFreeForAll()) { + final ArenaTeam team = this.arena.getTeam(args[0]); if (team != null && maxTeamPlayers > 0 && team.getTeamMembers().size() >= maxTeamPlayers) { - res.setError(this, Language.parse(arena, MSG.ERROR_JOIN_TEAM_FULL, team.getName())); + res.setError(this, Language.parse(this.arena, MSG.ERROR_JOIN_TEAM_FULL, team.getName())); return res; } } @@ -425,13 +421,13 @@ public PACheck checkSetBlock(final PACheck res, final Player player, final Block return res; } - Material flagType = arena.getArenaConfig().getMaterial(CFG.GOAL_FLAGS_FLAGTYPE); + Material flagType = this.arena.getArenaConfig().getMaterial(CFG.GOAL_FLAGS_FLAGTYPE); if (block == null || !ColorUtils.isSubType(block.getType(), flagType)) { return res; } if (!PVPArena.hasAdminPerms(player) - && !PVPArena.hasCreatePerms(player, arena)) { + && !PVPArena.hasCreatePerms(player, this.arena)) { return res; } res.setPriority(this, PRIORITY); // success :) @@ -487,7 +483,7 @@ private void commit(final Arena arena, final String sTeam, final boolean win) { + ChatColor.YELLOW)); } - getLifeMap().clear(); + this.getLifeMap().clear(); new EndRunnable(arena, arena.getArenaConfig().getInt( CFG.TIME_ENDCOUNTDOWN)); } @@ -496,9 +492,9 @@ private void commit(final Arena arena, final String sTeam, final boolean win) { public void commitCommand(final CommandSender sender, final String[] args) { if ("flagtype".equalsIgnoreCase(args[0])) { if (args.length < 2) { - arena.msg( + this.arena.msg( sender, - Language.parse(arena, MSG.ERROR_INVALID_ARGUMENT_COUNT, + Language.parse(this.arena, MSG.ERROR_INVALID_ARGUMENT_COUNT, String.valueOf(args.length), "2")); return; } @@ -506,35 +502,35 @@ public void commitCommand(final CommandSender sender, final String[] args) { final Material mat = Material.getMaterial(args[1].toUpperCase()); if (mat == null) { - arena.msg(sender, - Language.parse(arena, MSG.ERROR_MAT_NOT_FOUND, args[1])); + this.arena.msg(sender, + Language.parse(this.arena, MSG.ERROR_MAT_NOT_FOUND, args[1])); return; } - arena.getArenaConfig().set(CFG.GOAL_FLAGS_FLAGTYPE, mat.name()); + this.arena.getArenaConfig().set(CFG.GOAL_FLAGS_FLAGTYPE, mat.name()); - arena.getArenaConfig().save(); - arena.msg(sender, Language.parse(arena, MSG.GOAL_FLAGS_TYPESET, + this.arena.getArenaConfig().save(); + this.arena.msg(sender, Language.parse(this.arena, MSG.GOAL_FLAGS_TYPESET, CFG.GOAL_FLAGS_FLAGTYPE.toString())); } else if ("flageffect".equalsIgnoreCase(args[0])) { // /pa [arena] flageffect SLOW 2 if (args.length < 2) { - arena.msg( + this.arena.msg( sender, - Language.parse(arena, MSG.ERROR_INVALID_ARGUMENT_COUNT, + Language.parse(this.arena, MSG.ERROR_INVALID_ARGUMENT_COUNT, String.valueOf(args.length), "2")); return; } if ("none".equalsIgnoreCase(args[1])) { - arena.getArenaConfig().set(CFG.GOAL_FLAGS_FLAGEFFECT, args[1]); + this.arena.getArenaConfig().set(CFG.GOAL_FLAGS_FLAGEFFECT, args[1]); - arena.getArenaConfig().save(); - arena.msg( + this.arena.getArenaConfig().save(); + this.arena.msg( sender, - Language.parse(arena, MSG.SET_DONE, + Language.parse(this.arena, MSG.SET_DONE, CFG.GOAL_FLAGS_FLAGEFFECT.getNode(), args[1])); return; } @@ -552,7 +548,7 @@ public void commitCommand(final CommandSender sender, final String[] args) { } if (pet == null) { - arena.msg(sender, Language.parse(arena, + this.arena.msg(sender, Language.parse(this.arena, MSG.ERROR_POTIONEFFECTTYPE_NOTFOUND, args[1])); return; } @@ -563,52 +559,52 @@ public void commitCommand(final CommandSender sender, final String[] args) { try { amp = Integer.parseInt(args[2]); } catch (final Exception e) { - arena.msg(sender, - Language.parse(arena, MSG.ERROR_NOT_NUMERIC, args[2])); + this.arena.msg(sender, + Language.parse(this.arena, MSG.ERROR_NOT_NUMERIC, args[2])); return; } } final String value = args[1] + 'x' + amp; - arena.getArenaConfig().set(CFG.GOAL_FLAGS_FLAGEFFECT, value); + this.arena.getArenaConfig().set(CFG.GOAL_FLAGS_FLAGEFFECT, value); - arena.getArenaConfig().save(); - arena.msg( + this.arena.getArenaConfig().save(); + this.arena.msg( sender, - Language.parse(arena, MSG.SET_DONE, + Language.parse(this.arena, MSG.SET_DONE, CFG.GOAL_FLAGS_FLAGEFFECT.getNode(), value)); } else if (args[0].contains("flag")) { - for (final ArenaTeam team : arena.getTeams()) { + for (final ArenaTeam team : this.arena.getTeams()) { final String sTeam = team.getName(); if (args[0].contains(sTeam + "flag")) { - flagName = args[0]; - PAA_Region.activeSelections.put(sender.getName(), arena); + this.flagName = args[0]; + PAA_Region.activeSelections.put(sender.getName(), this.arena); - arena.msg(sender, - Language.parse(arena, MSG.GOAL_FLAGS_TOSET, flagName)); + this.arena.msg(sender, + Language.parse(this.arena, MSG.GOAL_FLAGS_TOSET, this.flagName)); } } - } else if ("touchdown".equalsIgnoreCase(args[0])) { - flagName = args[0] + "flag"; - PAA_Region.activeSelections.put(sender.getName(), arena); + } else if (TOUCHDOWN.equalsIgnoreCase(args[0])) { + this.flagName = args[0] + "flag"; + PAA_Region.activeSelections.put(sender.getName(), this.arena); - arena.msg(sender, Language.parse(arena, MSG.GOAL_FLAGS_TOSET, flagName)); + this.arena.msg(sender, Language.parse(this.arena, MSG.GOAL_FLAGS_TOSET, this.flagName)); } } @Override public void commitEnd(final boolean force) { - if (arena.realEndRunner != null) { - arena.getDebugger().i("[FLAGS] already ending"); + if (this.arena.realEndRunner != null) { + this.arena.getDebugger().i("[FLAGS] already ending"); return; } - arena.getDebugger().i("[FLAGS]"); + this.arena.getDebugger().i("[FLAGS]"); - final PAGoalEvent gEvent = new PAGoalEvent(arena, this, ""); + final PAGoalEvent gEvent = new PAGoalEvent(this.arena, this, ""); Bukkit.getPluginManager().callEvent(gEvent); ArenaTeam aTeam = null; - for (final ArenaTeam team : arena.getTeams()) { + for (final ArenaTeam team : this.arena.getTeams()) { for (final ArenaPlayer ap : team.getTeamMembers()) { if (ap.getStatus() == Status.FIGHT) { aTeam = team; @@ -619,40 +615,40 @@ public void commitEnd(final boolean force) { if (aTeam != null && !force) { ArenaModuleManager.announce( - arena, - Language.parse(arena, MSG.TEAM_HAS_WON, aTeam.getColor() + this.arena, + Language.parse(this.arena, MSG.TEAM_HAS_WON, aTeam.getColor() + aTeam.getName() + ChatColor.YELLOW), "END"); ArenaModuleManager.announce( - arena, - Language.parse(arena, MSG.TEAM_HAS_WON, aTeam.getColor() + this.arena, + Language.parse(this.arena, MSG.TEAM_HAS_WON, aTeam.getColor() + aTeam.getName() + ChatColor.YELLOW), "WINNER"); - arena.broadcast(Language.parse(arena, MSG.TEAM_HAS_WON, aTeam.getColor() + this.arena.broadcast(Language.parse(this.arena, MSG.TEAM_HAS_WON, aTeam.getColor() + aTeam.getName() + ChatColor.YELLOW)); } - if (ArenaModuleManager.commitEnd(arena, aTeam)) { + if (ArenaModuleManager.commitEnd(this.arena, aTeam)) { return; } - new EndRunnable(arena, arena.getArenaConfig().getInt( + new EndRunnable(this.arena, this.arena.getArenaConfig().getInt( CFG.TIME_ENDCOUNTDOWN)); } @Override public boolean commitSetFlag(final Player player, final Block block) { - arena.getDebugger().i("trying to set a flag", player); + this.arena.getDebugger().i("trying to set a flag", player); // command : /pa redflag1 // location: red1flag: - SpawnManager.setBlock(arena, new PABlockLocation(block.getLocation()), - flagName); + SpawnManager.setBlock(this.arena, new PABlockLocation(block.getLocation()), + this.flagName); - arena.msg(player, Language.parse(arena, MSG.GOAL_FLAGS_SET, flagName)); + this.arena.msg(player, Language.parse(this.arena, MSG.GOAL_FLAGS_SET, this.flagName)); PAA_Region.activeSelections.remove(player.getName()); - flagName = ""; + this.flagName = ""; return true; } @@ -669,76 +665,71 @@ public void configParse(final YamlConfiguration config) { @Override public void disconnect(final ArenaPlayer aPlayer) { - if (getFlagMap() == null) { + if (this.getFlagMap() == null) { return; } - final String sTeam = getHeldFlagTeam(aPlayer.getName()); - final ArenaTeam flagTeam = arena.getTeam(sTeam); + final String sTeam = this.getHeldFlagTeam(aPlayer.getName()); + final ArenaTeam flagTeam = this.arena.getTeam(sTeam); if (flagTeam == null) { if (sTeam == null) { return; } - arena.broadcast(Language.parse(arena, MSG.GOAL_FLAGS_DROPPEDTOUCH, aPlayer + this.arena.broadcast(Language.parse(this.arena, MSG.GOAL_FLAGS_DROPPEDTOUCH, aPlayer .getArenaTeam().getColorCodeString() + aPlayer.getName() + ChatColor.YELLOW)); - getFlagMap().remove("touchdown"); - if (getHeadGearMap() != null && getHeadGearMap().get(aPlayer.getName()) != null) { + this.getFlagMap().remove(TOUCHDOWN); + if (this.getHeadGearMap() != null && this.getHeadGearMap().get(aPlayer.getName()) != null) { if (aPlayer.get() != null) { aPlayer.get().getInventory() - .setHelmet(getHeadGearMap().get(aPlayer.getName()).clone()); + .setHelmet(this.getHeadGearMap().get(aPlayer.getName()).clone()); } - getHeadGearMap().remove(aPlayer.getName()); + this.getHeadGearMap().remove(aPlayer.getName()); } - takeFlag(ChatColor.BLACK, false, - SpawnManager.getBlockByExactName(arena, "touchdownflag")); + this.releaseFlag(ChatColor.BLACK, this.getTeamFlagLoc(TOUCHDOWN)); return; } - arena.broadcast(Language.parse(arena, MSG.GOAL_FLAGS_DROPPED, aPlayer + this.arena.broadcast(Language.parse(this.arena, MSG.GOAL_FLAGS_DROPPED, aPlayer .getArenaTeam().getColorCodeString() + aPlayer.getName() + ChatColor.YELLOW, flagTeam.getName() + ChatColor.YELLOW)); - getFlagMap().remove(flagTeam.getName()); - if (getHeadGearMap() != null && getHeadGearMap().get(aPlayer.getName()) != null) { + this.getFlagMap().remove(flagTeam.getName()); + if (this.getHeadGearMap() != null && this.getHeadGearMap().get(aPlayer.getName()) != null) { if (aPlayer.get() != null) { aPlayer.get().getInventory() - .setHelmet(getHeadGearMap().get(aPlayer.getName()).clone()); + .setHelmet(this.getHeadGearMap().get(aPlayer.getName()).clone()); } - getHeadGearMap().remove(aPlayer.getName()); + this.getHeadGearMap().remove(aPlayer.getName()); } - takeFlag(flagTeam.getColor(), false, - SpawnManager.getBlockByExactName(arena, flagTeam.getName() + "flag")); + this.releaseFlag(flagTeam.getColor(), this.getTeamFlagLoc(flagTeam.getName())); } @Override public void displayInfo(final CommandSender sender) { - sender.sendMessage("flageffect: " + - arena.getArenaConfig().getString(CFG.GOAL_FLAGS_FLAGEFFECT)); - sender.sendMessage("flagtype: " + - arena.getArenaConfig().getString(CFG.GOAL_FLAGS_FLAGTYPE)); - sender.sendMessage("lives: " + - arena.getArenaConfig().getInt(CFG.GOAL_FLAGS_LIVES)); - sender.sendMessage(StringParser.colorVar("mustbesafe", - arena.getArenaConfig().getBoolean(CFG.GOAL_FLAGS_MUSTBESAFE)) + - " | " + StringParser.colorVar("flaghead", - arena.getArenaConfig().getBoolean(CFG.GOAL_FLAGS_WOOLFLAGHEAD))); + Config cfg = this.arena.getArenaConfig(); + sender.sendMessage("flageffect: " + cfg.getString(CFG.GOAL_FLAGS_FLAGEFFECT)); + sender.sendMessage("flagtype: " + cfg.getString(CFG.GOAL_FLAGS_FLAGTYPE)); + sender.sendMessage("lives: " + cfg.getInt(CFG.GOAL_FLAGS_LIVES)); + sender.sendMessage(StringParser.colorVar("mustbesafe", cfg.getBoolean(CFG.GOAL_FLAGS_MUSTBESAFE)) + + " | " + StringParser.colorVar("flaghead", cfg.getBoolean(CFG.GOAL_FLAGS_WOOLFLAGHEAD)) + + " | " + StringParser.colorVar("alterOnCatch", cfg.getBoolean(CFG.GOAL_FLAGS_ALTERONCATCH))); } private Map getFlagMap() { - if (flagMap == null) { - flagMap = new HashMap<>(); + if (this.flagMap == null) { + this.flagMap = new HashMap<>(); } - return flagMap; + return this.flagMap; } private Material getFlagOverrideTeamMaterial(final Arena arena, final String team) { if (arena.getArenaConfig().getUnsafe("flagColors." + team) == null) { - if ("touchdown".equals(team)) { + if (TOUCHDOWN.equals(team)) { return ColorUtils.getWoolMaterialFromChatColor(ChatColor.BLACK); } return ColorUtils.getWoolMaterialFromChatColor(arena.getTeam(team).getColor()); @@ -752,17 +743,17 @@ public PACheck getLives(final PACheck res, final ArenaPlayer aPlayer) { if (res.getPriority() <= PRIORITY + 1000) { res.setError( this, - String.valueOf(getLifeMap().getOrDefault(aPlayer.getArenaTeam().getName(), 0)) + String.valueOf(this.getLifeMap().getOrDefault(aPlayer.getArenaTeam().getName(), 0)) ); } return res; } private Map getHeadGearMap() { - if (headGearMap == null) { - headGearMap = new HashMap<>(); + if (this.headGearMap == null) { + this.headGearMap = new HashMap<>(); } - return headGearMap; + return this.headGearMap; } /** @@ -772,15 +763,15 @@ private Map getHeadGearMap() { * @return a team name */ private String getHeldFlagTeam(final String player) { - if (getFlagMap().size() < 1) { + if (this.getFlagMap().size() < 1) { return null; } - arena.getDebugger().i("getting held FLAG of player " + player, player); - for (final String sTeam : getFlagMap().keySet()) { - arena.getDebugger().i("team " + sTeam + " is in " + getFlagMap().get(sTeam) + this.arena.getDebugger().i("getting held FLAG of player " + player, player); + for (final String sTeam : this.getFlagMap().keySet()) { + this.arena.getDebugger().i("team " + sTeam + " is in " + this.getFlagMap().get(sTeam) + "s hands", player); - if (player.equals(getFlagMap().get(sTeam))) { + if (player.equals(this.getFlagMap().get(sTeam))) { return sTeam; } } @@ -789,14 +780,14 @@ private String getHeldFlagTeam(final String player) { @Override public boolean hasSpawn(final String string) { - for (final String teamName : arena.getTeamNames()) { + for (final String teamName : this.arena.getTeamNames()) { if (string.toLowerCase().startsWith( teamName.toLowerCase() + "spawn")) { return true; } - if (arena.getArenaConfig().getBoolean(CFG.GENERAL_CLASSSPAWN)) { - for (final ArenaClass aClass : arena.getClasses()) { + if (this.arena.getArenaConfig().getBoolean(CFG.GENERAL_CLASSSPAWN)) { + for (final ArenaClass aClass : this.arena.getClasses()) { if (string.toLowerCase().startsWith(teamName.toLowerCase() + aClass.getName().toLowerCase() + "spawn")) { return true; @@ -811,14 +802,12 @@ public boolean hasSpawn(final String string) { public void initate(final Player player) { final ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(player.getName()); final ArenaTeam team = aPlayer.getArenaTeam(); - if (!getLifeMap().containsKey(team.getName())) { - getLifeMap().put(aPlayer.getArenaTeam().getName(), arena.getArenaConfig() + if (!this.getLifeMap().containsKey(team.getName())) { + this.getLifeMap().put(aPlayer.getArenaTeam().getName(), this.arena.getArenaConfig() .getInt(CFG.GOAL_FLAGS_LIVES)); - takeFlag(team.getColor(), false, - SpawnManager.getBlockByExactName(arena, team.getName() + "flag")); - takeFlag(ChatColor.BLACK, false, - SpawnManager.getBlockByExactName(arena, "touchdownflag")); + this.releaseFlag(team.getColor(), this.getTeamFlagLoc(team.getName())); + this.releaseFlag(ChatColor.BLACK, this.getTeamFlagLoc(TOUCHDOWN)); } } @@ -831,99 +820,90 @@ public boolean isInternal() { public void parsePlayerDeath(final Player player, final EntityDamageEvent lastDamageCause) { - if (getFlagMap() == null) { - arena.getDebugger().i("no flags set!!", player); + if (this.getFlagMap() == null) { + this.arena.getDebugger().i("no flags set!!", player); return; } - final String sTeam = getHeldFlagTeam(player.getName()); - final ArenaTeam flagTeam = arena.getTeam(sTeam); + final String sTeam = this.getHeldFlagTeam(player.getName()); + final ArenaTeam flagTeam = this.arena.getTeam(sTeam); final ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(player.getName()); if (flagTeam == null) { if (sTeam == null) { return; } - arena.broadcast(Language.parse(arena, MSG.GOAL_FLAGS_DROPPEDTOUCH, aPlayer + this.arena.broadcast(Language.parse(this.arena, MSG.GOAL_FLAGS_DROPPEDTOUCH, aPlayer .getArenaTeam().getColorCodeString() + aPlayer.getName() + ChatColor.YELLOW)); - getFlagMap().remove("touchdown"); - if (getHeadGearMap() != null && getHeadGearMap().get(aPlayer.getName()) != null) { + this.getFlagMap().remove(TOUCHDOWN); + if (this.getHeadGearMap() != null && this.getHeadGearMap().get(aPlayer.getName()) != null) { if (aPlayer.get() != null) { aPlayer.get().getInventory() - .setHelmet(getHeadGearMap().get(aPlayer.getName()).clone()); + .setHelmet(this.getHeadGearMap().get(aPlayer.getName()).clone()); } - getHeadGearMap().remove(aPlayer.getName()); + this.getHeadGearMap().remove(aPlayer.getName()); } - takeFlag(ChatColor.BLACK, false, - SpawnManager.getBlockByExactName(arena, "touchdownflag")); + this.releaseFlag(ChatColor.BLACK, this.getTeamFlagLoc(TOUCHDOWN)); return; } - arena.broadcast(Language.parse(arena, MSG.GOAL_FLAGS_DROPPED, aPlayer + this.arena.broadcast(Language.parse(this.arena, MSG.GOAL_FLAGS_DROPPED, aPlayer .getArenaTeam().colorizePlayer(player) + ChatColor.YELLOW, flagTeam.getColoredName() + ChatColor.YELLOW)); - getFlagMap().remove(flagTeam.getName()); - if (getHeadGearMap() != null - && getHeadGearMap().get(player.getName()) != null) { - player.getInventory().setHelmet( - getHeadGearMap().get(player.getName()).clone()); - getHeadGearMap().remove(player.getName()); + this.getFlagMap().remove(flagTeam.getName()); + if (this.getHeadGearMap() != null && this.getHeadGearMap().get(player.getName()) != null) { + player.getInventory().setHelmet(this.getHeadGearMap().get(player.getName()).clone()); + this.getHeadGearMap().remove(player.getName()); } - takeFlag(flagTeam.getColor(), false, - SpawnManager.getBlockByExactName(arena, flagTeam.getName() + "flag")); + this.releaseFlag(flagTeam.getColor(), this.getTeamFlagLoc(flagTeam.getName())); } @Override public void parseStart() { - getLifeMap().clear(); - for (final ArenaTeam team : arena.getTeams()) { + this.getLifeMap().clear(); + for (final ArenaTeam team : this.arena.getTeams()) { if (!team.getTeamMembers().isEmpty()) { - arena.getDebugger().i("adding team " + team.getName()); + this.arena.getDebugger().i("adding team " + team.getName()); // team is active - getLifeMap().put(team.getName(), - arena.getArenaConfig().getInt(CFG.GOAL_FLAGS_LIVES, 3)); + this.getLifeMap().put(team.getName(), + this.arena.getArenaConfig().getInt(CFG.GOAL_FLAGS_LIVES, 3)); } - takeFlag(team.getColor(), false, - SpawnManager.getBlockByExactName(arena, team.getName() + "flag")); + this.releaseFlag(team.getColor(), this.getTeamFlagLoc(team.getName())); } - takeFlag(ChatColor.BLACK, false, - SpawnManager.getBlockByExactName(arena, "touchdownflag")); + this.releaseFlag(ChatColor.BLACK, this.getTeamFlagLoc(TOUCHDOWN)); } - private boolean reduceLivesCheckEndAndCommit(final Arena arena, final String team) { + private void reduceLivesCheckEndAndCommit(final Arena arena, final String team) { arena.getDebugger().i("reducing lives of team " + team); - if (getLifeMap().get(team) == null) { + if (this.getLifeMap().get(team) == null) { if (team.contains(":")) { final String realTeam = team.split(":")[1]; - final int pos = getLifeMap().get(realTeam) - 1; + final int pos = this.getLifeMap().get(realTeam) - 1; if (pos > 0) { - getLifeMap().put(realTeam, pos); + this.getLifeMap().put(realTeam, pos); } else { - getLifeMap().remove(realTeam); - commit(arena, realTeam, true); - return true; + this.getLifeMap().remove(realTeam); + this.commit(arena, realTeam, true); } } } else { - final int pos = getLifeMap().get(team) - 1; + final int pos = this.getLifeMap().get(team) - 1; if (pos > 0) { - getLifeMap().put(team, pos); + this.getLifeMap().put(team, pos); } else { - getLifeMap().remove(team); - commit(arena, team, false); - return true; + this.getLifeMap().remove(team); + this.commit(arena, team, false); } } - return false; } private void removeEffects(final Player player) { - final String value = arena.getArenaConfig().getString( + final String value = this.arena.getArenaConfig().getString( CFG.GOAL_FLAGS_FLAGEFFECT); if ("none".equalsIgnoreCase(value)) { @@ -945,8 +925,7 @@ private void removeEffects(final Player player) { } if (pet == null) { - PVPArena.instance.getLogger().warning( - "Invalid Potion Effect Definition: " + value); + PVPArena.instance.getLogger().warning("Invalid Potion Effect Definition: " + value); return; } @@ -956,14 +935,14 @@ private void removeEffects(final Player player) { @Override public void reset(final boolean force) { - getFlagMap().clear(); - getHeadGearMap().clear(); - getLifeMap().clear(); + this.getFlagMap().clear(); + this.getHeadGearMap().clear(); + this.getLifeMap().clear(); } @Override public void setDefaults(final YamlConfiguration config) { - if (arena.isFreeForAll()) { + if (this.arena.isFreeForAll()) { return; } @@ -971,53 +950,80 @@ public void setDefaults(final YamlConfiguration config) { config.set("teams", null); } if (config.get("teams") == null) { - arena.getDebugger().i("no teams defined, adding custom red and blue!"); + this.arena.getDebugger().i("no teams defined, adding custom red and blue!"); config.addDefault("teams.red", ChatColor.RED.name()); config.addDefault("teams.blue", ChatColor.BLUE.name()); } - if (arena.getArenaConfig().getBoolean(CFG.GOAL_FLAGS_WOOLFLAGHEAD) - && config.get("flagColors") == null) { - arena.getDebugger().i("no flagheads defined, adding white and black!"); - config.addDefault("flagColors.red", "WHITE"); - config.addDefault("flagColors.blue", "BLACK"); + if (this.arena.getArenaConfig().getBoolean(CFG.GOAL_FLAGS_WOOLFLAGHEAD) && config.get("flagColors") == null) { + this.arena.getDebugger().i("no flagheads defined, adding white and black!"); + config.addDefault("flagColors.red", ChatColor.WHITE.name()); + config.addDefault("flagColors.blue", ChatColor.BLACK.name()); } } /** - * take/reset an arena flag + * take an arena flag * - * @param flagColor the teamcolor to reset - * @param take true if take, else reset * @param paBlockLocation the location to take/reset */ - void takeFlag(final ChatColor flagColor, final boolean take, final PABlockLocation paBlockLocation) { + private void takeFlag(final PABlockLocation paBlockLocation) { if (paBlockLocation == null) { return; } - if (!ColorUtils.isSubType(Material.getMaterial(arena.getArenaConfig().getString(CFG.GOAL_FLAGS_FLAGTYPE)), Material.WHITE_WOOL)) { - paBlockLocation.toLocation() - .getBlock() - .setType( - take ? Material.BEDROCK : Material.valueOf(arena - .getArenaConfig().getString( - CFG.GOAL_FLAGS_FLAGTYPE))); + + if(this.arena.getArenaConfig().getBoolean(CFG.GOAL_FLAGS_ALTERONCATCH)) { + Block flagBlock = paBlockLocation.toLocation().getBlock(); + + if (ColorUtils.isColorableMaterial(flagBlock.getType())) { + ColorUtils.setNewFlagColor(flagBlock, ChatColor.WHITE); + } else { + flagBlock.setType(Material.BEDROCK); + } + } + } + + /** + * reset an arena flag + * + * @param flagColor the teamcolor to reset + * @param paBlockLocation the location to take/reset + */ + private void releaseFlag(final ChatColor flagColor, final PABlockLocation paBlockLocation) { + if (paBlockLocation == null) { return; } - if (take) { - paBlockLocation.toLocation().getBlock() - .setType(Material.WHITE_WOOL); - } else { - paBlockLocation.toLocation().getBlock() - .setType(ColorUtils.getWoolMaterialFromChatColor(flagColor)); + + if(this.arena.getArenaConfig().getBoolean(CFG.GOAL_FLAGS_ALTERONCATCH)) { + Block flagBlock = paBlockLocation.toLocation().getBlock(); + + if (ColorUtils.isColorableMaterial(flagBlock.getType())) { + ColorUtils.setNewFlagColor(flagBlock, flagColor); + } else { + flagBlock.setType(this.arena.getArenaConfig().getMaterial(CFG.GOAL_FLAGS_FLAGTYPE)); + } + } + } + + private void setNewBlockData(Block block, Material newMaterial) { + final BlockData originalBlockData = block.getBlockData().clone(); + BlockData newData = Bukkit.getServer().createBlockData(newMaterial); + + if(originalBlockData instanceof Directional) { + ((Directional) newData).setFacing(((Directional) originalBlockData).getFacing()); + } + + if(originalBlockData instanceof Rotatable) { + ((Rotatable) newData).setRotation(((Rotatable) originalBlockData).getRotation()); } + + block.setBlockData(newData); } @Override public Map timedEnd(final Map scores) { - for (final ArenaTeam team : arena.getTeams()) { - double score = getLifeMap().containsKey(team.getName()) ? getLifeMap() - .get(team.getName()) : 0; + for (final ArenaTeam team : this.arena.getTeams()) { + double score = this.getLifeMap().getOrDefault(team.getName(), 0); if (scores.containsKey(team.getName())) { scores.put(team.getName(), scores.get(team.getName()) + score); } else { @@ -1030,9 +1036,9 @@ public Map timedEnd(final Map scores) { @Override public void unload(final Player player) { - disconnect(ArenaPlayer.parsePlayer(player.getName())); - if (allowsJoinInBattle()) { - arena.hasNotPlayed(ArenaPlayer.parsePlayer(player.getName())); + this.disconnect(ArenaPlayer.parsePlayer(player.getName())); + if (this.allowsJoinInBattle()) { + this.arena.hasNotPlayed(ArenaPlayer.parsePlayer(player.getName())); } } @@ -1046,8 +1052,7 @@ public void onInventoryClick(final InventoryClickEvent event) { return; } - if (event.isCancelled() - || getHeldFlagTeam(player.getName()) == null) { + if (event.isCancelled() || this.getHeldFlagTeam(player.getName()) == null) { return; } @@ -1060,4 +1065,8 @@ public void onInventoryClick(final InventoryClickEvent event) { event.setCancelled(true); } } + + private PABlockLocation getTeamFlagLoc(String teamName) { + return SpawnManager.getBlockByExactName(this.arena, teamName + "flag"); + } } diff --git a/src/net/slipcor/pvparena/goals/GoalPhysicalFlags.java b/src/net/slipcor/pvparena/goals/GoalPhysicalFlags.java index 091255b11..8415fb1c2 100644 --- a/src/net/slipcor/pvparena/goals/GoalPhysicalFlags.java +++ b/src/net/slipcor/pvparena/goals/GoalPhysicalFlags.java @@ -23,6 +23,7 @@ import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.block.data.BlockData; import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; @@ -40,6 +41,8 @@ import java.util.*; +import static java.util.Optional.ofNullable; + /** *
  * Arena Goal class "PhysicalFlags"
@@ -52,26 +55,27 @@
 
 public class GoalPhysicalFlags extends ArenaGoal implements Listener {
 
-    public GoalPhysicalFlags() {
-        super("PhysicalFlags");
-        debug = new Debug(100);
-    }
-
+    private static final int PRIORITY = 7;
+    private static final String TOUCHDOWN = "touchdown";
     private Map flagMap;
+    private Map flagDataMap;
     private Map headGearMap;
 
     private String flagName = "";
 
+    public GoalPhysicalFlags() {
+        super("PhysicalFlags");
+        this.debug = new Debug(100);
+    }
+
     @Override
     public String version() {
         return PVPArena.instance.getDescription().getVersion();
     }
 
-    private static final int PRIORITY = 7;
-
     @Override
     public boolean allowsJoinInBattle() {
-        return arena.getArenaConfig().getBoolean(CFG.PERMS_JOININBATTLE);
+        return this.arena.getArenaConfig().getBoolean(CFG.PERMS_JOININBATTLE);
     }
 
     @Override
@@ -80,13 +84,11 @@ public PACheck checkCommand(final PACheck res, final String string) {
             return res;
         }
 
-        if ("flagtype".equalsIgnoreCase(string)
-                || "flageffect".equalsIgnoreCase(string)
-                || "touchdown".equalsIgnoreCase(string)) {
+        if ("flagtype".equalsIgnoreCase(string) || "flageffect".equalsIgnoreCase(string) || TOUCHDOWN.equalsIgnoreCase(string)) {
             res.setPriority(this, PRIORITY);
         }
 
-        for (final ArenaTeam team : arena.getTeams()) {
+        for (final ArenaTeam team : this.arena.getTeams()) {
             final String sTeam = team.getName();
             if (string.contains(sTeam + "flag")) {
                 res.setPriority(this, PRIORITY);
@@ -98,9 +100,9 @@ public PACheck checkCommand(final PACheck res, final String string) {
 
     @Override
     public List getMain() {
-        final List result = Arrays.asList("flagtype", "flageffect", "touchdown");
-        if (arena != null) {
-            for (final ArenaTeam team : arena.getTeams()) {
+        final List result = Arrays.asList("flagtype", "flageffect", TOUCHDOWN);
+        if (this.arena != null) {
+            for (final ArenaTeam team : this.arena.getTeams()) {
                 final String sTeam = team.getName();
                 result.add(sTeam + "flag");
             }
@@ -122,12 +124,12 @@ public PACheck checkEnd(final PACheck res) {
             return res;
         }
 
-        final int count = TeamManager.countActiveTeams(arena);
+        final int count = TeamManager.countActiveTeams(this.arena);
 
         if (count == 1) {
             res.setPriority(this, PRIORITY); // yep. only one team left. go!
         } else if (count == 0) {
-            arena.getDebugger().i("No teams playing!");
+            this.arena.getDebugger().i("No teams playing!");
         }
 
         return res;
@@ -135,11 +137,11 @@ public PACheck checkEnd(final PACheck res) {
 
     @Override
     public String checkForMissingSpawns(final Set list) {
-        final String team = checkForMissingTeamSpawn(list);
+        final String team = this.checkForMissingTeamSpawn(list);
         if (team != null) {
             return team;
         }
-        return checkForMissingTeamCustom(list, "flag");
+        return this.checkForMissingTeamCustom(list, "flag");
     }
 
     /**
@@ -150,140 +152,128 @@ public String checkForMissingSpawns(final Set list) {
      * @param block  the block being clicked
      * @return the PACheck instance
      */
-    @SuppressWarnings("deprecation")
     @Override
     public PACheck checkInteract(final PACheck res, final Player player, final Block block) {
         if (block == null || res.getPriority() > PRIORITY) {
             return res;
         }
-        arena.getDebugger().i("checking interact", player);
+        this.arena.getDebugger().i("checking interact", player);
 
-        Material flagType = arena.getArenaConfig().getMaterial(CFG.GOAL_FLAGS_FLAGTYPE);
+        Material flagType = this.arena.getArenaConfig().getMaterial(CFG.GOAL_PFLAGS_FLAGTYPE);
         if (!ColorUtils.isSubType(block.getType(), flagType)) {
-            arena.getDebugger().i("block, but not flag", player);
+            this.arena.getDebugger().i("block, but not flag", player);
             return res;
         }
-        arena.getDebugger().i("flag click!", player);
+        this.arena.getDebugger().i("flag click!", player);
 
         final ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(player.getName());
 
-        if (getFlagMap().containsValue(player.getName())) {
-            arena.getDebugger().i("player " + player.getName() + " has got a flag", player);
+        if (this.getFlagMap().containsValue(player.getName())) {
+            this.arena.getDebugger().i("player " + player.getName() + " has got a flag", player);
 
             final Vector vLoc = block.getLocation().toVector();
             final String sTeam = aPlayer.getArenaTeam().getName();
-            arena.getDebugger().i("block: " + vLoc, player);
+            this.arena.getDebugger().i("block: " + vLoc, player);
             Vector vFlag = null;
-            if (!SpawnManager.getBlocksStartingWith(arena, sTeam + "flag").isEmpty()) {
-                vFlag = SpawnManager
-                        .getBlockNearest(
-                                SpawnManager.getBlocksStartingWith(arena, sTeam + "flag"),
-                                new PABlockLocation(player.getLocation()))
-                        .toLocation().toVector();
+            if (this.getTeamFlagLoc(sTeam) != null) {
+                vFlag = this.getTeamFlagLoc(sTeam).toLocation().toVector();
             } else {
-                arena.getDebugger().i(sTeam + "flag = null", player);
+                this.arena.getDebugger().i(sTeam + "flag = null", player);
             }
 
-            arena.getDebugger().i("player is in the team " + sTeam, player);
+            this.arena.getDebugger().i("player is in the team " + sTeam, player);
             if (vFlag != null && vLoc.distance(vFlag) < 2) {
 
-                arena.getDebugger().i("player is at his flag", player);
+                this.arena.getDebugger().i("player is at his flag", player);
 
-                if (getFlagMap().containsKey(sTeam)
-                        || getFlagMap().containsKey("touchdown")) {
-                    arena.getDebugger().i("the flag of the own team is taken!", player);
+                if (this.getFlagMap().containsKey(sTeam) || this.getFlagMap().containsKey(TOUCHDOWN)) {
+                    this.arena.getDebugger().i("the flag of the own team is taken!", player);
 
-                    if (arena.getArenaConfig().getBoolean(
-                            CFG.GOAL_FLAGS_MUSTBESAFE)
-                            && !getFlagMap().containsKey("touchdown")) {
-                        arena.getDebugger().i("cancelling", player);
+                    if (this.arena.getArenaConfig().getBoolean(CFG.GOAL_PFLAGS_MUSTBESAFE)
+                            && !this.getFlagMap().containsKey(TOUCHDOWN)) {
+                        this.arena.getDebugger().i("cancelling", player);
 
-                        arena.msg(player,
-                                Language.parse(arena, MSG.GOAL_FLAGS_NOTSAFE));
+                        this.arena.msg(player, Language.parse(this.arena, MSG.GOAL_FLAGS_NOTSAFE));
                         return res;
                     }
                 }
 
-                String flagTeam = getHeldFlagTeam(player.getName());
-
-                arena.getDebugger().i("the flag belongs to team " + flagTeam, player);
-
-                if (player.getItemInHand() == null
-                        || !player
-                        .getItemInHand()
-                        .getType()
-                        .name()
-                        .equals(arena.getArenaConfig().getString(
-                                CFG.GOAL_FLAGS_FLAGTYPE))) {
-                    arena.getDebugger().i("player " + player.getName()
-                            + " is not holding the flag", player);
-                    arena.msg(player,
-                            Language.parse(arena, MSG.GOAL_PHYSICALFLAGS_HOLDFLAG));
+                String flagTeam = this.getHeldFlagTeam(player.getName());
+
+                this.arena.getDebugger().i("the flag belongs to team " + flagTeam, player);
+
+                ItemStack mainHandItem = player.getInventory().getItemInMainHand();
+                if (!ColorUtils.isSubType(mainHandItem.getType(), flagType)) {
+                    this.arena.getDebugger().i("player " + player.getName() + " is not holding the flag", player);
+                    this.arena.msg(player, Language.parse(this.arena, MSG.GOAL_PHYSICALFLAGS_HOLDFLAG));
                     return res;
                 }
 
-                player.getInventory().remove(player.getItemInHand());
+                player.getInventory().remove(mainHandItem);
                 player.updateInventory();
 
                 try {
-                    if ("touchdown".equals(flagTeam)) {
-                        arena.broadcast(Language.parse(arena,
-                                MSG.GOAL_FLAGS_TOUCHHOME, arena.getTeam(sTeam)
+                    if (TOUCHDOWN.equals(flagTeam)) {
+                        this.arena.broadcast(Language.parse(this.arena,
+                                MSG.GOAL_FLAGS_TOUCHHOME, this.arena.getTeam(sTeam)
                                         .colorizePlayer(player)
                                         + ChatColor.YELLOW, String
-                                        .valueOf(getLifeMap().get(aPlayer
+                                        .valueOf(this.getLifeMap().get(aPlayer
                                                 .getArenaTeam().getName()) - 1)));
                     } else {
-                        arena.broadcast(Language.parse(arena,
-                                MSG.GOAL_FLAGS_BROUGHTHOME, arena
+                        this.arena.broadcast(Language.parse(this.arena,
+                                MSG.GOAL_FLAGS_BROUGHTHOME, this.arena
                                         .getTeam(sTeam).colorizePlayer(player)
                                         + ChatColor.YELLOW,
-                                arena.getTeam(flagTeam).getColoredName()
+                                this.arena.getTeam(flagTeam).getColoredName()
                                         + ChatColor.YELLOW, String
-                                        .valueOf(getLifeMap().get(flagTeam) - 1)));
+                                        .valueOf(this.getLifeMap().get(flagTeam) - 1)));
                     }
-                    getFlagMap().remove(flagTeam);
+                    this.getFlagMap().remove(flagTeam);
                 } catch (final Exception e) {
                     Bukkit.getLogger().severe(
                             "[PVP Arena] team unknown/no lives: " + flagTeam);
                     e.printStackTrace();
                 }
-                if ("touchdown".equals(flagTeam)) {
-                    takeFlag(ChatColor.BLACK, false,
-                            SpawnManager.getBlockByExactName(arena, "touchdownflag"));
+                if (TOUCHDOWN.equals(flagTeam)) {
+                    this.releaseFlag(TOUCHDOWN);
                 } else {
-                    takeFlag(arena.getTeam(flagTeam).getColor(), false,
-                            SpawnManager.getBlockByExactName(arena, flagTeam + "flag"));
+                    this.releaseFlag(flagTeam);
                 }
-                removeEffects(player);
-                if (arena.getArenaConfig().getBoolean(
-                        CFG.GOAL_FLAGS_WOOLFLAGHEAD)) {
-                    player.getInventory().setHelmet(
-                            new ItemStack(Material.AIR, 1));
+                this.removeEffects(player);
+                if (this.arena.getArenaConfig().getBoolean(CFG.GOAL_PFLAGS_WOOLFLAGHEAD)) {
+                    player.getInventory().setHelmet(new ItemStack(Material.AIR, 1));
                 } else {
-                    if (getHeadGearMap().get(player.getName()) == null) {
-                        player.getInventory().setHelmet(
-                                getHeadGearMap().get(player.getName()).clone());
-                        getHeadGearMap().remove(player.getName());
+                    if (this.getHeadGearMap().get(player.getName()) == null) {
+                        player.getInventory().setHelmet(this.getHeadGearMap().get(player.getName()).clone());
+                        this.getHeadGearMap().remove(player.getName());
                     }
                 }
 
-                flagTeam = "touchdown".equals(flagTeam) ? flagTeam + ':' + aPlayer
-                        .getArenaTeam().getName() : flagTeam;
+                flagTeam = TOUCHDOWN.equals(flagTeam) ? flagTeam + ':' + aPlayer.getArenaTeam().getName() : flagTeam;
 
-                reduceLivesCheckEndAndCommit(arena, flagTeam);
+                this.reduceLivesCheckEndAndCommit(this.arena, flagTeam);
 
-                final PAGoalEvent gEvent = new PAGoalEvent(arena, this, "trigger:" + player.getName());
+                final PAGoalEvent gEvent = new PAGoalEvent(this.arena, this, "trigger:" + player.getName());
                 Bukkit.getPluginManager().callEvent(gEvent);
+
+                // used to cancel block put event
+                res.setPriority(this, PRIORITY);
             }
         }
 
         return res;
     }
 
+    @Override
+    public void commitInteract(final Player player, final Block clickedBlock) {}
+
+    private PABlockLocation getTeamFlagLoc(String teamName) {
+        return SpawnManager.getBlockByExactName(this.arena, teamName + "flag");
+    }
+
     private void applyEffects(final Player player) {
-        final String value = arena.getArenaConfig().getString(
-                CFG.GOAL_FLAGS_FLAGEFFECT);
+        final String value = this.arena.getArenaConfig().getString(CFG.GOAL_PFLAGS_FLAGEFFECT);
 
         if ("none".equalsIgnoreCase(value)) {
             return;
@@ -296,7 +286,7 @@ private void applyEffects(final Player player) {
         if (split.length > 1) {
             try {
                 amp = Integer.parseInt(split[1]);
-            } catch (final Exception e) {
+            } catch (final Exception ignored) {
 
             }
         }
@@ -327,12 +317,12 @@ public PACheck checkJoin(final CommandSender sender, final PACheck res, final St
             return res;
         }
 
-        final int maxPlayers = arena.getArenaConfig().getInt(CFG.READY_MAXPLAYERS);
-        final int maxTeamPlayers = arena.getArenaConfig().getInt(
+        final int maxPlayers = this.arena.getArenaConfig().getInt(CFG.READY_MAXPLAYERS);
+        final int maxTeamPlayers = this.arena.getArenaConfig().getInt(
                 CFG.READY_MAXTEAMPLAYERS);
 
-        if (maxPlayers > 0 && arena.getFighters().size() >= maxPlayers) {
-            res.setError(this, Language.parse(arena, MSG.ERROR_JOIN_ARENA_FULL));
+        if (maxPlayers > 0 && this.arena.getFighters().size() >= maxPlayers) {
+            res.setError(this, Language.parse(this.arena, MSG.ERROR_JOIN_ARENA_FULL));
             return res;
         }
 
@@ -340,12 +330,12 @@ public PACheck checkJoin(final CommandSender sender, final PACheck res, final St
             return res;
         }
 
-        if (!arena.isFreeForAll()) {
-            final ArenaTeam team = arena.getTeam(args[0]);
+        if (!this.arena.isFreeForAll()) {
+            final ArenaTeam team = this.arena.getTeam(args[0]);
 
             if (team != null && maxTeamPlayers > 0
                     && team.getTeamMembers().size() >= maxTeamPlayers) {
-                res.setError(this, Language.parse(arena, MSG.ERROR_JOIN_TEAM_FULL, team.getName()));
+                res.setError(this, Language.parse(this.arena, MSG.ERROR_JOIN_TEAM_FULL, team.getName()));
                 return res;
             }
         }
@@ -357,18 +347,16 @@ public PACheck checkJoin(final CommandSender sender, final PACheck res, final St
     @Override
     public PACheck checkSetBlock(final PACheck res, final Player player, final Block block) {
 
-        if (res.getPriority() > PRIORITY
-                || !PAA_Region.activeSelections.containsKey(player.getName())) {
+        if (res.getPriority() > PRIORITY || !PAA_Region.activeSelections.containsKey(player.getName())) {
             return res;
         }
 
-        Material flagType = arena.getArenaConfig().getMaterial(CFG.GOAL_FLAGS_FLAGTYPE);
+        Material flagType = this.arena.getArenaConfig().getMaterial(CFG.GOAL_PFLAGS_FLAGTYPE);
         if (block == null || !ColorUtils.isSubType(block.getType(), flagType)) {
             return res;
         }
 
-        if (!PVPArena.hasAdminPerms(player)
-                && !PVPArena.hasCreatePerms(player, arena)) {
+        if (!PVPArena.hasAdminPerms(player) && !PVPArena.hasCreatePerms(player, this.arena)) {
             return res;
         }
         res.setPriority(this, PRIORITY); // success :)
@@ -424,18 +412,18 @@ private void commit(final Arena arena, final String sTeam, final boolean win) {
                             + ChatColor.YELLOW));
         }
 
-        getLifeMap().clear();
-        new EndRunnable(arena, arena.getArenaConfig().getInt(
-                CFG.TIME_ENDCOUNTDOWN));
+        this.getLifeMap().clear();
+        this.getFlagDataMap().clear();
+        new EndRunnable(arena, arena.getArenaConfig().getInt(CFG.TIME_ENDCOUNTDOWN));
     }
 
     @Override
     public void commitCommand(final CommandSender sender, final String[] args) {
         if ("flagtype".equalsIgnoreCase(args[0])) {
             if (args.length < 2) {
-                arena.msg(
+                this.arena.msg(
                         sender,
-                        Language.parse(arena, MSG.ERROR_INVALID_ARGUMENT_COUNT,
+                        Language.parse(this.arena, MSG.ERROR_INVALID_ARGUMENT_COUNT,
                                 String.valueOf(args.length), "2"));
                 return;
             }
@@ -443,36 +431,36 @@ public void commitCommand(final CommandSender sender, final String[] args) {
             final Material mat = Material.getMaterial(args[1].toUpperCase());
 
             if (mat == null) {
-                arena.msg(sender,
-                        Language.parse(arena, MSG.ERROR_MAT_NOT_FOUND, args[1]));
+                this.arena.msg(sender,
+                        Language.parse(this.arena, MSG.ERROR_MAT_NOT_FOUND, args[1]));
                 return;
             }
 
-            arena.getArenaConfig().set(CFG.GOAL_FLAGS_FLAGTYPE, mat.name());
+            this.arena.getArenaConfig().set(CFG.GOAL_PFLAGS_FLAGTYPE, mat.name());
 
-            arena.getArenaConfig().save();
-            arena.msg(sender, Language.parse(arena, MSG.GOAL_FLAGS_TYPESET,
-                    CFG.GOAL_FLAGS_FLAGTYPE.toString()));
+            this.arena.getArenaConfig().save();
+            this.arena.msg(sender, Language.parse(this.arena, MSG.GOAL_FLAGS_TYPESET,
+                    CFG.GOAL_PFLAGS_FLAGTYPE.toString()));
 
         } else if ("flageffect".equalsIgnoreCase(args[0])) {
 
             // /pa [arena] flageffect SLOW 2
             if (args.length < 2) {
-                arena.msg(
+                this.arena.msg(
                         sender,
-                        Language.parse(arena, MSG.ERROR_INVALID_ARGUMENT_COUNT,
+                        Language.parse(this.arena, MSG.ERROR_INVALID_ARGUMENT_COUNT,
                                 String.valueOf(args.length), "2"));
                 return;
             }
 
             if ("none".equalsIgnoreCase(args[1])) {
-                arena.getArenaConfig().set(CFG.GOAL_FLAGS_FLAGEFFECT, args[1]);
+                this.arena.getArenaConfig().set(CFG.GOAL_PFLAGS_FLAGEFFECT, args[1]);
 
-                arena.getArenaConfig().save();
-                arena.msg(
+                this.arena.getArenaConfig().save();
+                this.arena.msg(
                         sender,
-                        Language.parse(arena, MSG.SET_DONE,
-                                CFG.GOAL_FLAGS_FLAGEFFECT.getNode(), args[1]));
+                        Language.parse(this.arena, MSG.SET_DONE,
+                                CFG.GOAL_PFLAGS_FLAGEFFECT.getNode(), args[1]));
                 return;
             }
 
@@ -489,7 +477,7 @@ public void commitCommand(final CommandSender sender, final String[] args) {
             }
 
             if (pet == null) {
-                arena.msg(sender, Language.parse(arena,
+                this.arena.msg(sender, Language.parse(this.arena,
                         MSG.ERROR_POTIONEFFECTTYPE_NOTFOUND, args[1]));
                 return;
             }
@@ -500,52 +488,52 @@ public void commitCommand(final CommandSender sender, final String[] args) {
                 try {
                     amp = Integer.parseInt(args[2]);
                 } catch (final Exception e) {
-                    arena.msg(sender,
-                            Language.parse(arena, MSG.ERROR_NOT_NUMERIC, args[2]));
+                    this.arena.msg(sender,
+                            Language.parse(this.arena, MSG.ERROR_NOT_NUMERIC, args[2]));
                     return;
                 }
             }
             final String value = args[1] + 'x' + amp;
-            arena.getArenaConfig().set(CFG.GOAL_FLAGS_FLAGEFFECT, value);
+            this.arena.getArenaConfig().set(CFG.GOAL_PFLAGS_FLAGEFFECT, value);
 
-            arena.getArenaConfig().save();
-            arena.msg(
+            this.arena.getArenaConfig().save();
+            this.arena.msg(
                     sender,
-                    Language.parse(arena, MSG.SET_DONE,
-                            CFG.GOAL_FLAGS_FLAGEFFECT.getNode(), value));
+                    Language.parse(this.arena, MSG.SET_DONE,
+                            CFG.GOAL_PFLAGS_FLAGEFFECT.getNode(), value));
 
         } else if (args[0].contains("flag")) {
-            for (final ArenaTeam team : arena.getTeams()) {
+            for (final ArenaTeam team : this.arena.getTeams()) {
                 final String sTeam = team.getName();
                 if (args[0].contains(sTeam + "flag")) {
-                    flagName = args[0];
-                    PAA_Region.activeSelections.put(sender.getName(), arena);
+                    this.flagName = args[0];
+                    PAA_Region.activeSelections.put(sender.getName(), this.arena);
 
-                    arena.msg(sender,
-                            Language.parse(arena, MSG.GOAL_FLAGS_TOSET, flagName));
+                    this.arena.msg(sender,
+                            Language.parse(this.arena, MSG.GOAL_FLAGS_TOSET, this.flagName));
                 }
             }
-        } else if ("touchdown".equalsIgnoreCase(args[0])) {
-            flagName = args[0] + "flag";
-            PAA_Region.activeSelections.put(sender.getName(), arena);
+        } else if (TOUCHDOWN.equalsIgnoreCase(args[0])) {
+            this.flagName = args[0] + "flag";
+            PAA_Region.activeSelections.put(sender.getName(), this.arena);
 
-            arena.msg(sender, Language.parse(arena, MSG.GOAL_FLAGS_TOSET, flagName));
+            this.arena.msg(sender, Language.parse(this.arena, MSG.GOAL_FLAGS_TOSET, this.flagName));
         }
     }
 
     @Override
     public void commitEnd(final boolean force) {
-        if (arena.realEndRunner != null) {
-            arena.getDebugger().i("[FLAGS] already ending");
+        if (this.arena.realEndRunner != null) {
+            this.arena.getDebugger().i("[FLAGS] already ending");
             return;
         }
-        arena.getDebugger().i("[FLAGS]");
+        this.arena.getDebugger().i("[FLAGS]");
 
-        final PAGoalEvent gEvent = new PAGoalEvent(arena, this, "");
+        final PAGoalEvent gEvent = new PAGoalEvent(this.arena, this, "");
         Bukkit.getPluginManager().callEvent(gEvent);
         ArenaTeam aTeam = null;
 
-        for (final ArenaTeam team : arena.getTeams()) {
+        for (final ArenaTeam team : this.arena.getTeams()) {
             for (final ArenaPlayer ap : team.getTeamMembers()) {
                 if (ap.getStatus() == Status.FIGHT) {
                     aTeam = team;
@@ -556,40 +544,38 @@ public void commitEnd(final boolean force) {
 
         if (aTeam != null && !force) {
             ArenaModuleManager.announce(
-                    arena,
-                    Language.parse(arena, MSG.TEAM_HAS_WON, aTeam.getColor()
+                    this.arena,
+                    Language.parse(this.arena, MSG.TEAM_HAS_WON, aTeam.getColor()
                             + aTeam.getName() + ChatColor.YELLOW), "END");
 
             ArenaModuleManager.announce(
-                    arena,
-                    Language.parse(arena, MSG.TEAM_HAS_WON, aTeam.getColor()
+                    this.arena,
+                    Language.parse(this.arena, MSG.TEAM_HAS_WON, aTeam.getColor()
                             + aTeam.getName() + ChatColor.YELLOW), "WINNER");
-            arena.broadcast(Language.parse(arena, MSG.TEAM_HAS_WON, aTeam.getColor()
+            this.arena.broadcast(Language.parse(this.arena, MSG.TEAM_HAS_WON, aTeam.getColor()
                     + aTeam.getName() + ChatColor.YELLOW));
         }
 
-        if (ArenaModuleManager.commitEnd(arena, aTeam)) {
+        if (ArenaModuleManager.commitEnd(this.arena, aTeam)) {
             return;
         }
-        new EndRunnable(arena, arena.getArenaConfig().getInt(
-                CFG.TIME_ENDCOUNTDOWN));
+        new EndRunnable(this.arena, this.arena.getArenaConfig().getInt(CFG.TIME_ENDCOUNTDOWN));
     }
 
     @Override
     public boolean commitSetFlag(final Player player, final Block block) {
 
-        arena.getDebugger().i("trying to set a flag", player);
+        this.arena.getDebugger().i("trying to set a flag", player);
 
         // command : /pa redflag1
         // location: red1flag:
 
-        SpawnManager.setBlock(arena, new PABlockLocation(block.getLocation()),
-                flagName);
+        SpawnManager.setBlock(this.arena, new PABlockLocation(block.getLocation()), this.flagName);
 
-        arena.msg(player, Language.parse(arena, MSG.GOAL_FLAGS_SET, flagName));
+        this.arena.msg(player, Language.parse(this.arena, MSG.GOAL_FLAGS_SET, this.flagName));
 
         PAA_Region.activeSelections.remove(player.getName());
-        flagName = "";
+        this.flagName = "";
 
         return true;
     }
@@ -605,74 +591,75 @@ public void configParse(final YamlConfiguration config) {
 
     @Override
     public void disconnect(final ArenaPlayer aPlayer) {
-        if (getFlagMap() == null) {
+        if (this.getFlagMap().isEmpty()) {
             return;
         }
-        final String sTeam = getHeldFlagTeam(aPlayer.getName());
-        final ArenaTeam flagTeam = arena.getTeam(sTeam);
+        final String sTeam = this.getHeldFlagTeam(aPlayer.getName());
+        final ArenaTeam flagTeam = this.arena.getTeam(sTeam);
 
         if (flagTeam == null) {
             if (sTeam != null) {
-                arena.broadcast(Language.parse(arena, MSG.GOAL_FLAGS_DROPPEDTOUCH, aPlayer
+                this.arena.broadcast(Language.parse(this.arena, MSG.GOAL_FLAGS_DROPPEDTOUCH, aPlayer
                         .getArenaTeam().getColorCodeString()
                         + aPlayer.getName()
                         + ChatColor.YELLOW));
 
-                getFlagMap().remove("touchdown");
-                if (getHeadGearMap() != null && getHeadGearMap().get(aPlayer.getName()) != null) {
+                this.getFlagMap().remove(TOUCHDOWN);
+                if (this.getHeadGearMap() != null && this.getHeadGearMap().get(aPlayer.getName()) != null) {
                     if (aPlayer.get() != null) {
                         aPlayer.get().getInventory()
-                                .setHelmet(getHeadGearMap().get(aPlayer.getName()).clone());
+                                .setHelmet(this.getHeadGearMap().get(aPlayer.getName()).clone());
                     }
-                    getHeadGearMap().remove(aPlayer.getName());
+                    this.getHeadGearMap().remove(aPlayer.getName());
                 }
 
-                takeFlag(ChatColor.BLACK, false,
-                        SpawnManager.getBlockByExactName(arena, "touchdownflag"));
+                this.releaseFlag(TOUCHDOWN);
             }
         } else {
-            arena.broadcast(Language.parse(arena, MSG.GOAL_FLAGS_DROPPED, aPlayer
+            this.arena.broadcast(Language.parse(this.arena, MSG.GOAL_FLAGS_DROPPED, aPlayer
                     .getArenaTeam().getColorCodeString()
                     + aPlayer.getName()
                     + ChatColor.YELLOW, flagTeam.getName() + ChatColor.YELLOW));
-            getFlagMap().remove(flagTeam.getName());
-            if (getHeadGearMap() != null && getHeadGearMap().get(aPlayer.getName()) != null) {
+            this.getFlagMap().remove(flagTeam.getName());
+            if (this.getHeadGearMap() != null && this.getHeadGearMap().get(aPlayer.getName()) != null) {
                 if (aPlayer.get() != null) {
                     aPlayer.get().getInventory()
-                            .setHelmet(getHeadGearMap().get(aPlayer.getName()).clone());
+                            .setHelmet(this.getHeadGearMap().get(aPlayer.getName()).clone());
                 }
-                getHeadGearMap().remove(aPlayer.getName());
+                this.getHeadGearMap().remove(aPlayer.getName());
             }
 
-            takeFlag(flagTeam.getColor(), false,
-                    SpawnManager.getBlockByExactName(arena, flagTeam.getName() + "flag"));
+            this.releaseFlag(flagTeam.getName());
         }
     }
 
     @Override
     public void displayInfo(final CommandSender sender) {
-        sender.sendMessage("flageffect: " +
-                arena.getArenaConfig().getString(CFG.GOAL_FLAGS_FLAGEFFECT));
-        sender.sendMessage("flagtype: " +
-                arena.getArenaConfig().getString(CFG.GOAL_FLAGS_FLAGTYPE));
-        sender.sendMessage("lives: " +
-                arena.getArenaConfig().getInt(CFG.GOAL_FLAGS_LIVES));
-        sender.sendMessage(StringParser.colorVar("mustbesafe",
-                arena.getArenaConfig().getBoolean(CFG.GOAL_FLAGS_MUSTBESAFE)) +
-                " | " + StringParser.colorVar("flaghead",
-                arena.getArenaConfig().getBoolean(CFG.GOAL_FLAGS_WOOLFLAGHEAD)));
+        Config cfg = this.arena.getArenaConfig();
+        sender.sendMessage("flageffect: " + cfg.getString(CFG.GOAL_PFLAGS_FLAGEFFECT));
+        sender.sendMessage("flagtype: " + cfg.getString(CFG.GOAL_PFLAGS_FLAGTYPE));
+        sender.sendMessage("lives: " + cfg.getInt(CFG.GOAL_PFLAGS_LIVES));
+        sender.sendMessage(StringParser.colorVar("mustbesafe", cfg.getBoolean(CFG.GOAL_PFLAGS_MUSTBESAFE))
+                + " | " + StringParser.colorVar("flaghead", cfg.getBoolean(CFG.GOAL_PFLAGS_WOOLFLAGHEAD)));
     }
 
     private Map getFlagMap() {
-        if (flagMap == null) {
-            flagMap = new HashMap<>();
+        if (this.flagMap == null) {
+            this.flagMap = new HashMap<>();
+        }
+        return this.flagMap;
+    }
+
+    private Map getFlagDataMap() {
+        if (this.flagDataMap == null) {
+            this.flagDataMap = new HashMap<>();
         }
-        return flagMap;
+        return this.flagDataMap;
     }
 
     private Material getFlagOverrideTeamMaterial(final Arena arena, final String team) {
         if (arena.getArenaConfig().getUnsafe("flagColors." + team) == null) {
-            if ("touchdown".equals(team)) {
+            if (TOUCHDOWN.equals(team)) {
                 return ColorUtils.getWoolMaterialFromChatColor(ChatColor.BLACK);
             }
             return ColorUtils.getWoolMaterialFromChatColor(arena.getTeam(team).getColor());
@@ -686,17 +673,17 @@ public PACheck getLives(final PACheck res, final ArenaPlayer aPlayer) {
         if (res.getPriority() <= PRIORITY + 1000) {
             res.setError(
                     this,
-                    String.valueOf(getLifeMap().getOrDefault(aPlayer.getArenaTeam().getName(), 0))
+                    String.valueOf(this.getLifeMap().getOrDefault(aPlayer.getArenaTeam().getName(), 0))
             );
         }
         return res;
     }
 
     private Map getHeadGearMap() {
-        if (headGearMap == null) {
-            headGearMap = new HashMap<>();
+        if (this.headGearMap == null) {
+            this.headGearMap = new HashMap<>();
         }
-        return headGearMap;
+        return this.headGearMap;
     }
 
     /**
@@ -706,15 +693,14 @@ private Map getHeadGearMap() {
      * @return a team name
      */
     private String getHeldFlagTeam(final String player) {
-        if (getFlagMap().size() < 1) {
+        if (this.getFlagMap().isEmpty()) {
             return null;
         }
 
-        arena.getDebugger().i("getting held FLAG of player " + player, player);
-        for (final String sTeam : getFlagMap().keySet()) {
-            arena.getDebugger().i("team " + sTeam + " is in " + getFlagMap().get(sTeam)
-                    + "s hands", player);
-            if (player.equals(getFlagMap().get(sTeam))) {
+        this.arena.getDebugger().i("getting held FLAG of player " + player, player);
+        for (final String sTeam : this.getFlagMap().keySet()) {
+            this.arena.getDebugger().i("team " + sTeam + " is in " + this.getFlagMap().get(sTeam) + "s hands", player);
+            if (player.equals(this.getFlagMap().get(sTeam))) {
                 return sTeam;
             }
         }
@@ -723,7 +709,7 @@ private String getHeldFlagTeam(final String player) {
 
     @Override
     public boolean hasSpawn(final String string) {
-        for (final String teamName : arena.getTeamNames()) {
+        for (final String teamName : this.arena.getTeamNames()) {
             if (string.toLowerCase().equals(teamName.toLowerCase() + "flag")) {
                 return true;
             }
@@ -732,8 +718,8 @@ public boolean hasSpawn(final String string) {
                 return true;
             }
 
-            if (arena.getArenaConfig().getBoolean(CFG.GENERAL_CLASSSPAWN)) {
-                for (final ArenaClass aClass : arena.getClasses()) {
+            if (this.arena.getArenaConfig().getBoolean(CFG.GENERAL_CLASSSPAWN)) {
+                for (final ArenaClass aClass : this.arena.getClasses()) {
                     if (string.toLowerCase().startsWith(teamName.toLowerCase() +
                             aClass.getName().toLowerCase() + "spawn")) {
                         return true;
@@ -748,14 +734,8 @@ public boolean hasSpawn(final String string) {
     public void initate(final Player player) {
         final ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(player.getName());
         final ArenaTeam team = aPlayer.getArenaTeam();
-        if (!getLifeMap().containsKey(team.getName())) {
-            getLifeMap().put(aPlayer.getArenaTeam().getName(), arena.getArenaConfig()
-                    .getInt(CFG.GOAL_FLAGS_LIVES));
-
-            takeFlag(team.getColor(), false,
-                    SpawnManager.getBlockByExactName(arena, team.getName() + "flag"));
-            takeFlag(ChatColor.BLACK, false,
-                    SpawnManager.getBlockByExactName(arena, "touchdownflag"));
+        if (!this.getLifeMap().containsKey(team.getName())) {
+            this.getLifeMap().put(aPlayer.getArenaTeam().getName(), this.arena.getArenaConfig().getInt(CFG.GOAL_PFLAGS_LIVES));
         }
     }
 
@@ -768,101 +748,94 @@ public boolean isInternal() {
     public void parsePlayerDeath(final Player player,
                                  final EntityDamageEvent lastDamageCause) {
 
-        if (getFlagMap() == null) {
-            arena.getDebugger().i("no flags set!!", player);
+        if (this.getFlagMap().isEmpty()) {
+            this.arena.getDebugger().i("no flags set!!", player);
             return;
         }
-        final String sTeam = getHeldFlagTeam(player.getName());
-        final ArenaTeam flagTeam = arena.getTeam(sTeam);
+        final String sTeam = this.getHeldFlagTeam(player.getName());
+        final ArenaTeam flagTeam = this.arena.getTeam(sTeam);
         final ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(player.getName());
 
         if (flagTeam == null) {
             if (sTeam != null) {
-                arena.broadcast(Language.parse(arena, MSG.GOAL_FLAGS_DROPPEDTOUCH, aPlayer
+                this.arena.broadcast(Language.parse(this.arena, MSG.GOAL_FLAGS_DROPPEDTOUCH, aPlayer
                         .getArenaTeam().getColorCodeString()
                         + aPlayer.getName()
                         + ChatColor.YELLOW));
 
-                getFlagMap().remove("touchdown");
-                if (getHeadGearMap() != null && getHeadGearMap().get(aPlayer.getName()) != null) {
+                this.getFlagMap().remove(TOUCHDOWN);
+                if (this.getHeadGearMap() != null && this.getHeadGearMap().get(aPlayer.getName()) != null) {
                     if (aPlayer.get() != null) {
-                        aPlayer.get().getInventory()
-                                .setHelmet(getHeadGearMap().get(aPlayer.getName()).clone());
+                        aPlayer.get().getInventory().setHelmet(this.getHeadGearMap().get(aPlayer.getName()).clone());
                     }
-                    getHeadGearMap().remove(aPlayer.getName());
+                    this.getHeadGearMap().remove(aPlayer.getName());
                 }
 
-                takeFlag(ChatColor.BLACK, false,
-                        SpawnManager.getBlockByExactName(arena, "touchdownflag"));
+                this.releaseFlag(TOUCHDOWN);
             }
         } else {
-            arena.broadcast(Language.parse(arena, MSG.GOAL_FLAGS_DROPPED, aPlayer
+            this.arena.broadcast(Language.parse(this.arena, MSG.GOAL_FLAGS_DROPPED, aPlayer
                             .getArenaTeam().colorizePlayer(player) + ChatColor.YELLOW,
                     flagTeam.getColoredName() + ChatColor.YELLOW));
-            getFlagMap().remove(flagTeam.getName());
-            if (getHeadGearMap() != null
-                    && getHeadGearMap().get(player.getName()) != null) {
-                player.getInventory().setHelmet(
-                        getHeadGearMap().get(player.getName()).clone());
-                getHeadGearMap().remove(player.getName());
+            this.getFlagMap().remove(flagTeam.getName());
+            if (this.getHeadGearMap() != null && this.getHeadGearMap().get(player.getName()) != null) {
+                player.getInventory().setHelmet(this.getHeadGearMap().get(player.getName()).clone());
+                this.getHeadGearMap().remove(player.getName());
             }
 
-            takeFlag(flagTeam.getColor(), false,
-                    SpawnManager.getBlockByExactName(arena, flagTeam.getName() + "flag"));
+            this.releaseFlag(flagTeam.getName());
         }
     }
 
     @Override
     public void parseStart() {
-        getLifeMap().clear();
-        for (final ArenaTeam team : arena.getTeams()) {
+        this.getLifeMap().clear();
+        this.getFlagDataMap().clear();
+        for (final ArenaTeam team : this.arena.getTeams()) {
             if (!team.getTeamMembers().isEmpty()) {
-                arena.getDebugger().i("adding team " + team.getName());
+                this.arena.getDebugger().i("adding team " + team.getName());
                 // team is active
-                getLifeMap().put(team.getName(),
-                        arena.getArenaConfig().getInt(CFG.GOAL_FLAGS_LIVES, 3));
+                this.getLifeMap().put(team.getName(), this.arena.getArenaConfig().getInt(CFG.GOAL_PFLAGS_LIVES, 3));
+                Block flagBlock = this.getTeamFlagLoc(team.getName()).toLocation().getBlock();
+                this.getFlagDataMap().put(team.getName(), flagBlock.getBlockData().clone());
             }
-            takeFlag(team.getColor(), false,
-                    SpawnManager.getBlockByExactName(arena, team.getName() + "flag"));
         }
-        takeFlag(ChatColor.BLACK, false,
-                SpawnManager.getBlockByExactName(arena, "touchdownflag"));
+        ofNullable(this.getTeamFlagLoc(TOUCHDOWN)).ifPresent(paBlockLocation -> {
+            Block touchdownFlagBlock = paBlockLocation.toLocation().getBlock();
+            this.getFlagDataMap().put(TOUCHDOWN, touchdownFlagBlock.getBlockData().clone());
+        });
     }
 
-    private boolean reduceLivesCheckEndAndCommit(final Arena arena, final String team) {
+    private void reduceLivesCheckEndAndCommit(final Arena arena, final String team) {
 
         arena.getDebugger().i("reducing lives of team " + team);
-        if (getLifeMap().get(team) == null) {
+        if (this.getLifeMap().get(team) == null) {
             if (team.contains(":")) {
                 final String realTeam = team.split(":")[1];
-                final int iLives = getLifeMap().get(realTeam) - 1;
+                final int iLives = this.getLifeMap().get(realTeam) - 1;
                 if (iLives > 0) {
-                    getLifeMap().put(realTeam, iLives);
+                    this.getLifeMap().put(realTeam, iLives);
                 } else {
-                    getLifeMap().remove(realTeam);
-                    commit(arena, realTeam, true);
-                    return true;
+                    this.getLifeMap().remove(realTeam);
+                    this.commit(arena, realTeam, true);
                 }
             }
         } else {
-            if (getLifeMap().get(team) != null) {
-                final int iLives = getLifeMap().get(team) - 1;
+            if (this.getLifeMap().get(team) != null) {
+                final int iLives = this.getLifeMap().get(team) - 1;
                 if (iLives > 0) {
-                    getLifeMap().put(team, iLives);
+                    this.getLifeMap().put(team, iLives);
                 } else {
-                    getLifeMap().remove(team);
-                    commit(arena, team, false);
-                    return true;
+                    this.getLifeMap().remove(team);
+                    this.commit(arena, team, false);
                 }
             }
         }
-
-        return false;
     }
 
     private void removeEffects(final Player player) {
-        final String value = arena.getArenaConfig().getString(
-                CFG.GOAL_FLAGS_FLAGEFFECT);
+        final String value = this.arena.getArenaConfig().getString(
+                CFG.GOAL_PFLAGS_FLAGEFFECT);
 
         if ("none".equalsIgnoreCase(value)) {
             return;
@@ -883,8 +856,7 @@ private void removeEffects(final Player player) {
         }
 
         if (pet == null) {
-            PVPArena.instance.getLogger().warning(
-                    "Invalid Potion Effect Definition: " + value);
+            PVPArena.instance.getLogger().warning("Invalid Potion Effect Definition: " + value);
             return;
         }
 
@@ -894,14 +866,21 @@ private void removeEffects(final Player player) {
 
     @Override
     public void reset(final boolean force) {
-        getFlagMap().clear();
-        getHeadGearMap().clear();
-        getLifeMap().clear();
+        this.getHeadGearMap().clear();
+        this.getLifeMap().clear();
+        this.getFlagMap().clear();
+        if(!this.getFlagDataMap().isEmpty()) {
+            for (final ArenaTeam team : this.arena.getTeams()) {
+                this.releaseFlag(team.getName());
+            }
+            this.releaseFlag(TOUCHDOWN);
+        }
+        this.getFlagDataMap().clear();
     }
 
     @Override
     public void setDefaults(final YamlConfiguration config) {
-        if (arena.isFreeForAll()) {
+        if (this.arena.isFreeForAll()) {
             return;
         }
 
@@ -909,63 +888,42 @@ public void setDefaults(final YamlConfiguration config) {
             config.set("teams", null);
         }
         if (config.get("teams") == null) {
-            arena.getDebugger().i("no teams defined, adding custom red and blue!");
+            this.arena.getDebugger().i("no teams defined, adding custom red and blue!");
             config.addDefault("teams.red", ChatColor.RED.name());
             config.addDefault("teams.blue", ChatColor.BLUE.name());
         }
-        if (arena.getArenaConfig().getBoolean(CFG.GOAL_FLAGS_WOOLFLAGHEAD)
+        if (this.arena.getArenaConfig().getBoolean(CFG.GOAL_PFLAGS_WOOLFLAGHEAD)
                 && config.get("flagColors") == null) {
-            arena.getDebugger().i("no flagheads defined, adding white and black!");
+            this.arena.getDebugger().i("no flagheads defined, adding white and black!");
             config.addDefault("flagColors.red", "WHITE");
             config.addDefault("flagColors.blue", "BLACK");
         }
     }
 
     /**
-     * take/reset an arena flag
+     * reset an arena flag
      *
-     * @param flagColor       the teamcolor to reset
-     * @param take            true if take, else reset
-     * @param paBlockLocation the location to take/reset
+     * @param teamName  team whose flag needs to be reset
      */
-    void takeFlag(final ChatColor flagColor, final boolean take, final PABlockLocation paBlockLocation) {
+    private void releaseFlag(final String teamName) {
+        PABlockLocation paBlockLocation = this.getTeamFlagLoc(teamName);
         if (paBlockLocation == null) {
             return;
         }
-        if (!ColorUtils.isSubType(Material.valueOf(arena.getArenaConfig().getString(CFG.GOAL_FLAGS_FLAGTYPE)), Material.WHITE_WOOL)) {
-            paBlockLocation.toLocation()
-                    .getBlock()
-                    .setType(
-                            take ? Material.BEDROCK : Material.valueOf(arena
-                                    .getArenaConfig().getString(
-                                            CFG.GOAL_FLAGS_FLAGTYPE)));
-            return;
-        }
-        if (take) {
-            paBlockLocation.toLocation().getBlock()
-                    .setType(Material.WHITE_WOOL);
-        } else {
-            Material attempt = Material.getMaterial(flagColor+"_"+arena.getArenaConfig().getString(
-                    CFG.GOAL_FLAGS_FLAGTYPE));
-            if (attempt == null) {
-                attempt = Material.valueOf(
-                        arena.getArenaConfig().getString(
-                                CFG.GOAL_FLAGS_FLAGTYPE));
-
-                if (attempt == null) {
-                    attempt = ColorUtils.getWoolMaterialFromChatColor(flagColor);
-                }
-            }
-            paBlockLocation.toLocation().getBlock().setType(attempt);
+
+        Block flagBlock = paBlockLocation.toLocation().getBlock();
+        try {
+            flagBlock.setBlockData(this.getFlagDataMap().get(teamName));
+        } catch (Exception e) {
+            PVPArena.instance.getLogger().warning("Impossible to reset flag data ! You may recreate arena flags.");
         }
     }
 
     @Override
     public Map timedEnd(final Map scores) {
 
-        for (final ArenaTeam team : arena.getTeams()) {
-            double score = getLifeMap().containsKey(team.getName()) ? getLifeMap()
-                    .get(team.getName()) : 0;
+        for (final ArenaTeam team : this.arena.getTeams()) {
+            double score = this.getLifeMap().getOrDefault(team.getName(), 0);
             if (scores.containsKey(team.getName())) {
                 scores.put(team.getName(), scores.get(team.getName()) + score);
             } else {
@@ -978,111 +936,97 @@ public Map timedEnd(final Map scores) {
 
     @Override
     public void unload(final Player player) {
-        disconnect(ArenaPlayer.parsePlayer(player.getName()));
-        if (allowsJoinInBattle()) {
-            arena.hasNotPlayed(ArenaPlayer.parsePlayer(player.getName()));
+        this.disconnect(ArenaPlayer.parsePlayer(player.getName()));
+        if (this.allowsJoinInBattle()) {
+            this.arena.hasNotPlayed(ArenaPlayer.parsePlayer(player.getName()));
         }
     }
 
-    @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
+    @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = false)
     public void onFlagClaim(final BlockBreakEvent event) {
         final Player player = event.getPlayer();
-        if (!arena.hasPlayer(event.getPlayer())
-                || !event
-                .getBlock()
-                .getType()
-                .name()
-                .equals(arena.getArenaConfig().getString(
-                        CFG.GOAL_FLAGS_FLAGTYPE))) {
-
-            arena.getDebugger().i("block destroy, ignoring", player);
-            arena.getDebugger().i(String.valueOf(arena.hasPlayer(event.getPlayer())), player);
-            arena.getDebugger().i(event.getBlock().getType().name(), player);
+        Material brokenMaterial = event.getBlock().getType();
+        if (!this.arena.hasPlayer(event.getPlayer()) ||
+                !ColorUtils.isSubType(brokenMaterial, this.arena.getArenaConfig().getMaterial(CFG.GOAL_PFLAGS_FLAGTYPE))) {
+
+            this.arena.getDebugger().i("block destroy, ignoring", player);
+            this.arena.getDebugger().i(String.valueOf(this.arena.hasPlayer(event.getPlayer())), player);
+            this.arena.getDebugger().i(event.getBlock().getType().name(), player);
             return;
         }
 
         final Block block = event.getBlock();
 
-        arena.getDebugger().i("flag destroy!", player);
+        this.arena.getDebugger().i("flag destroy!", player);
 
         final ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(player.getName());
 
-        if (getFlagMap().containsValue(player.getName())) {
-            arena.getDebugger().i("already carries a flag!", player);
+        if (this.getFlagMap().containsValue(player.getName())) {
+            this.arena.getDebugger().i("already carries a flag!", player);
             return;
         }
         final ArenaTeam pTeam = aPlayer.getArenaTeam();
         if (pTeam == null) {
             return;
         }
-        final Set setTeam = new HashSet<>();
 
-        for (final ArenaTeam team : arena.getTeams()) {
-            setTeam.add(team);
-        }
-        setTeam.add(new ArenaTeam("touchdown", "BLACK"));
+        final Set setTeam = new HashSet<>(this.arena.getTeams());
+
+        setTeam.add(new ArenaTeam(TOUCHDOWN, "BLACK"));
         Vector vFlag = null;
         for (final ArenaTeam team : setTeam) {
-            final String aTeam = team.getName();
+            final String teamName = team.getName();
+            final PABlockLocation teamFlagLoc = this.getTeamFlagLoc(teamName);
 
-            if (aTeam.equals(pTeam.getName())) {
-                arena.getDebugger().i("equals!OUT! ", player);
+            if (teamName.equals(pTeam.getName())) {
+                this.arena.getDebugger().i("equals!OUT! ", player);
                 continue;
             }
-            if (team.getTeamMembers().size() < 1
-                    && !"touchdown".equals(team.getName())) {
-                arena.getDebugger().i("size!OUT! ", player);
+            if (team.getTeamMembers().size() < 1 && !TOUCHDOWN.equals(team.getName())) {
+                this.arena.getDebugger().i("size!OUT! ", player);
                 continue; // dont check for inactive teams
             }
-            if (getFlagMap() != null && getFlagMap().containsKey(aTeam)) {
-                arena.getDebugger().i("taken!OUT! ", player);
+            if (this.getFlagMap().containsKey(teamName)) {
+                this.arena.getDebugger().i("taken!OUT! ", player);
                 continue; // already taken
             }
-            arena.getDebugger().i("checking for flag of team " + aTeam, player);
+            this.arena.getDebugger().i("checking for flag of team " + teamName, player);
             Vector vLoc = block.getLocation().toVector();
-            arena.getDebugger().i("block: " + vLoc, player);
-            if (!SpawnManager.getBlocksStartingWith(arena, aTeam + "flag").isEmpty()) {
-                vFlag = SpawnManager
-                        .getBlockNearest(
-                                SpawnManager.getBlocksStartingWith(arena, aTeam
-                                        + "flag"),
-                                new PABlockLocation(player.getLocation()))
-                        .toLocation().toVector();
-            }
-            if (vFlag != null && vLoc.distance(vFlag) < 2) {
-                arena.getDebugger().i("flag found!", player);
-                arena.getDebugger().i("vFlag: " + vFlag, player);
+            this.arena.getDebugger().i("block: " + vLoc, player);
+
+            if(teamFlagLoc != null && vLoc.equals(teamFlagLoc.toLocation().toVector())) {
+                this.arena.getDebugger().i("flag found!", player);
+                this.arena.getDebugger().i("vFlag: " + vFlag, player);
 
-                if ("touchdown".equals(team.getName())) {
+                if (TOUCHDOWN.equals(team.getName())) {
 
-                    arena.broadcast(Language.parse(arena,
+                    this.arena.broadcast(Language.parse(this.arena,
                             MSG.GOAL_FLAGS_GRABBEDTOUCH,
                             pTeam.colorizePlayer(player) + ChatColor.YELLOW));
                 } else {
 
-                    arena.broadcast(Language
-                            .parse(arena, MSG.GOAL_FLAGS_GRABBED,
+                    this.arena.broadcast(Language
+                            .parse(this.arena, MSG.GOAL_FLAGS_GRABBED,
                                     pTeam.colorizePlayer(player)
                                             + ChatColor.YELLOW,
                                     team.getColoredName()
                                             + ChatColor.YELLOW));
                 }
                 try {
-                    getHeadGearMap().put(player.getName(), player.getInventory()
-                            .getHelmet().clone());
-                } catch (final Exception e) {
+                    this.getHeadGearMap().put(player.getName(), player.getInventory().getHelmet().clone());
+                } catch (final Exception ignored) {
 
                 }
 
-                if (arena.getArenaConfig().getBoolean(CFG.GOAL_FLAGS_WOOLFLAGHEAD)) {
-                    final ItemStack itemStack = new ItemStack(getFlagOverrideTeamMaterial(arena, aTeam));
+                if (this.arena.getArenaConfig().getBoolean(CFG.GOAL_PFLAGS_WOOLFLAGHEAD)) {
+                    final ItemStack itemStack = new ItemStack(this.getFlagOverrideTeamMaterial(this.arena, teamName));
                     player.getInventory().setHelmet(itemStack);
                 }
-                applyEffects(player);
-
-                takeFlag(team.getColor(), true, new PABlockLocation(block.getLocation()));
-                getFlagMap().put(aTeam, player.getName());
-
+                this.applyEffects(player);
+                this.getFlagMap().put(teamName, player.getName());
+                player.getInventory().addItem(new ItemStack(block.getType()));
+                block.setType(Material.AIR);;
+                event.setCancelled(true);
                 return;
             }
         }
@@ -1098,13 +1042,11 @@ public void onInventoryClick(final InventoryClickEvent event) {
             return;
         }
 
-        if (event.isCancelled()
-                || getHeldFlagTeam(player.getName()) == null) {
+        if (event.isCancelled() || this.getHeldFlagTeam(player.getName()) == null) {
             return;
         }
 
-        if (event.getInventory().getType() == InventoryType.CRAFTING
-                && event.getRawSlot() != 5) {
+        if (event.getInventory().getType() == InventoryType.CRAFTING && event.getRawSlot() != 5) {
             return;
         }
 
diff --git a/src/net/slipcor/pvparena/loadables/ArenaRegion.java b/src/net/slipcor/pvparena/loadables/ArenaRegion.java
index a352371dd..aa62de5aa 100644
--- a/src/net/slipcor/pvparena/loadables/ArenaRegion.java
+++ b/src/net/slipcor/pvparena/loadables/ArenaRegion.java
@@ -1,6 +1,5 @@
 package net.slipcor.pvparena.loadables;
 
-import com.google.common.collect.ImmutableMap;
 import net.slipcor.pvparena.PVPArena;
 import net.slipcor.pvparena.arena.Arena;
 import net.slipcor.pvparena.arena.ArenaPlayer;
@@ -452,11 +451,7 @@ public void removeEntities() {
         }
 
         for (final Entity entity : getWorld().getEntities()) {
-            if (entity instanceof Player
-                    || !shape.contains(new PABlockLocation(entity.getLocation()
-                    .getWorld().getName(), entity.getLocation().getBlockX(),
-                    entity.getLocation().getBlockY(), entity.getLocation()
-                    .getBlockZ()))) {
+            if (entity instanceof Player || !shape.contains(new PABlockLocation(entity.getLocation()))) {
                 continue;
             }
 
diff --git a/src/net/slipcor/pvparena/runnables/CircleParticleRunnable.java b/src/net/slipcor/pvparena/runnables/CircleParticleRunnable.java
index 36d66125f..aa604c6ea 100644
--- a/src/net/slipcor/pvparena/runnables/CircleParticleRunnable.java
+++ b/src/net/slipcor/pvparena/runnables/CircleParticleRunnable.java
@@ -7,11 +7,10 @@
 import net.slipcor.pvparena.core.Utils;
 import org.bukkit.*;
 
-import java.util.HashMap;
 import java.util.Map;
 
 public class CircleParticleRunnable implements Runnable {
-    private Map flagMap = new HashMap<>();
+    private Map flagMap;
     private final Arena arena;
     private double radius;
     private int i = 0;
@@ -24,7 +23,7 @@ public CircleParticleRunnable(Arena arena, Config.CFG config, Map= 360) {
-            i = 0;
+        if (this.i >= 360) {
+            this.i = 0;
         }
     }
 }

From 7beea5ce40fe33df73702bafa193eb1f92c195a6 Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Mon, 11 May 2020 19:22:18 +0200
Subject: [PATCH 07/43] v1.15 - avoid self respawn with death screen - issue
 #36

---
 src/net/slipcor/pvparena/managers/SpawnManager.java | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/src/net/slipcor/pvparena/managers/SpawnManager.java b/src/net/slipcor/pvparena/managers/SpawnManager.java
index bed26950a..a0ecc29b2 100644
--- a/src/net/slipcor/pvparena/managers/SpawnManager.java
+++ b/src/net/slipcor/pvparena/managers/SpawnManager.java
@@ -622,6 +622,9 @@ public static void respawn(final Arena arena, final ArenaPlayer aPlayer, final S
             return;
         }
 
+        // Trick to avoid death screen
+        Bukkit.getScheduler().scheduleSyncDelayedTask(PVPArena.instance, () -> aPlayer.get().closeInventory(), 1);
+
         if (overrideSpawn == null) {
 
 
@@ -634,7 +637,7 @@ public static void respawn(final Arena arena, final ArenaPlayer aPlayer, final S
                 int pos = new Random().nextInt(spawns.size());
                 for (final PASpawn spawn : spawns) {
                     if (--pos <= 0) {
-                        Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RespawnRunnable(arena, aPlayer, spawn.getName()), 1L);
+                        Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RespawnRunnable(arena, aPlayer, spawn.getName()), 2);
                         aPlayer.setStatus(Status.FIGHT);
                         return;
                     }
@@ -676,7 +679,7 @@ public static void respawn(final Arena arena, final ArenaPlayer aPlayer, final S
                     int pos = new Random().nextInt(spawns.size());
                     for (final PASpawn spawn : spawns) {
                         if (--pos <= 0) {
-                            Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RespawnRunnable(arena, aPlayer, spawn.getName()), 1L);
+                            Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RespawnRunnable(arena, aPlayer, spawn.getName()), 2);
                             aPlayer.setStatus(Status.FIGHT);
                             return;
                         }
@@ -723,7 +726,7 @@ public static void respawn(final Arena arena, final ArenaPlayer aPlayer, final S
                     if (paLocationDoubleEntry.getValue() == max) {
                         for (final PASpawn spawn : spawns) {
                             if (spawn.getLocation().equals(paLocationDoubleEntry.getKey())) {
-                                Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RespawnRunnable(arena, aPlayer, spawn.getName()), 1L);
+                                Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RespawnRunnable(arena, aPlayer, spawn.getName()), 2);
                                 return;
                             }
                         }
@@ -738,7 +741,7 @@ public static void respawn(final Arena arena, final ArenaPlayer aPlayer, final S
             int pos = new Random().nextInt(spawns.size());
             for (final PASpawn spawn : spawns) {
                 if (--pos <= 0) {
-                    Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RespawnRunnable(arena, aPlayer, spawn.getName()), 1L);
+                    Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RespawnRunnable(arena, aPlayer, spawn.getName()), 2);
                     aPlayer.setStatus(Status.FIGHT);
                     return;
                 }
@@ -746,7 +749,7 @@ public static void respawn(final Arena arena, final ArenaPlayer aPlayer, final S
 
         }
 
-        Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RespawnRunnable(arena, aPlayer, overrideSpawn), 1L);
+        Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RespawnRunnable(arena, aPlayer, overrideSpawn), 2);
         if (overrideSpawn == null || !overrideSpawn.toLowerCase().endsWith("relay")) {
             aPlayer.setStatus(Status.FIGHT);
         }

From 8d218c4677f861fce09462c8dceedb99c8379e78 Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Mon, 11 May 2020 20:09:11 +0200
Subject: [PATCH 08/43] v1.15 - repair scoreboard init - issue #35

---
 src/net/slipcor/pvparena/arena/Arena.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/net/slipcor/pvparena/arena/Arena.java b/src/net/slipcor/pvparena/arena/Arena.java
index 5dc69a780..f35a1c1ce 100644
--- a/src/net/slipcor/pvparena/arena/Arena.java
+++ b/src/net/slipcor/pvparena/arena/Arena.java
@@ -1660,7 +1660,7 @@ public void run() {
                 }
 
             }
-            Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RunLater(), 1L);
+            Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RunLater(), 3L);
         } else {
             final Scoreboard board = getStandardScoreboard();
             ArenaPlayer ap = ArenaPlayer.parsePlayer(player.getName());

From bc4527a3bb59e8bba430895baa8bb0b74d54962d Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Thu, 14 May 2020 20:01:44 +0200
Subject: [PATCH 09/43] v1.15 - fix move checking for "checkpoint" goal - issue
 #32

---
 doc/goals/checkpoints.md                      |   6 +-
 .../pvparena/goals/GoalCheckPoints.java       | 168 +++++++++---------
 2 files changed, 88 insertions(+), 86 deletions(-)

diff --git a/doc/goals/checkpoints.md b/doc/goals/checkpoints.md
index ac3792bd3..49cffcaf3 100644
--- a/doc/goals/checkpoints.md
+++ b/doc/goals/checkpoints.md
@@ -11,12 +11,12 @@ First player to reach every checkpoint up to the last (in order) wins!
 ## Setup
 
 Spawns have to be added. In order to do that, use `/pa [arenaname] checkpoint [number]`. This sets checkpoint number [number].
-Make sure you start with 0 and don't forget to add every single number, or else it will not be possible to win :P
+Make sure you start with 1 and don't forget to add every single number, or else it will not be possible to win :P
 
 ## Config Settings  
 
 - cpclaimrange => how near need players to be? (default: 5)
-- cplives => goal checkpoint index [0, 1, 2, ...] to reach
+- cplives => number of checkpoints to reach
 - cptickinterval => the amount of ticks to wait before checking for position (default: 20 = 1 second)
 
 ## Warnings
@@ -25,4 +25,4 @@ This game mode has to check for player's position. Based on the player and check
 
 ## Supported Game Modes
 
-Free for all - Teams might work but.... no idea
+Free for all
diff --git a/src/net/slipcor/pvparena/goals/GoalCheckPoints.java b/src/net/slipcor/pvparena/goals/GoalCheckPoints.java
index 2ff7d5334..4162d3068 100644
--- a/src/net/slipcor/pvparena/goals/GoalCheckPoints.java
+++ b/src/net/slipcor/pvparena/goals/GoalCheckPoints.java
@@ -24,6 +24,7 @@
 import org.bukkit.Location;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
+import org.bukkit.scheduler.BukkitRunnable;
 
 import java.util.*;
 
@@ -39,7 +40,7 @@ public class GoalCheckPoints extends ArenaGoal {
 
     public GoalCheckPoints() {
         super("CheckPoints");
-        debug = new Debug(99);
+        this.debug = new Debug(99);
     }
 
     @Override
@@ -51,7 +52,7 @@ public String version() {
 
     @Override
     public boolean allowsJoinInBattle() {
-        return arena.getArenaConfig().getBoolean(CFG.PERMS_JOININBATTLE);
+        return this.arena.getArenaConfig().getBoolean(CFG.PERMS_JOININBATTLE);
     }
 
     @Override
@@ -95,10 +96,10 @@ public PACheck checkJoin(final CommandSender sender, final PACheck res, final St
             return res;
         }
 
-        final int maxPlayers = arena.getArenaConfig().getInt(CFG.READY_MAXPLAYERS);
+        final int maxPlayers = this.arena.getArenaConfig().getInt(CFG.READY_MAXPLAYERS);
 
-        if (maxPlayers > 0 && arena.getFighters().size() >= maxPlayers) {
-            res.setError(this, Language.parse(arena, MSG.ERROR_JOIN_ARENA_FULL));
+        if (maxPlayers > 0 && this.arena.getFighters().size() >= maxPlayers) {
+            res.setError(this, Language.parse(this.arena, MSG.ERROR_JOIN_ARENA_FULL));
             return res;
         }
 
@@ -115,7 +116,7 @@ public PACheck checkJoin(final CommandSender sender, final PACheck res, final St
     private Set checkLocationPresentPlayers(final Location loc, final int distance) {
         final Set result = new HashSet<>();
 
-        for (final ArenaPlayer p : arena.getFighters()) {
+        for (final ArenaPlayer p : this.arena.getFighters()) {
             if (p.get().getLocation().getWorld().getName().equals(loc.getWorld().getName())) {
                 if (p.get().getLocation().distance(loc) > distance) {
                     continue;
@@ -128,21 +129,20 @@ private Set checkLocationPresentPlayers(final Location loc, final int di
         return result;
     }
 
-    void checkMove() {
+    private void checkMove() {
 
-        arena.getDebugger().i("------------------");
-        arena.getDebugger().i("  GCP checkMove();");
-        arena.getDebugger().i("------------------");
+        this.arena.getDebugger().i("------------------");
+        this.arena.getDebugger().i("  GCP checkMove();");
+        this.arena.getDebugger().i("------------------");
 
-        final int checkDistance = arena.getArenaConfig().getInt(
-                CFG.GOAL_DOM_CLAIMRANGE);
+        final int checkDistance = this.arena.getArenaConfig().getInt(CFG.GOAL_CHECKPOINTS_CLAIMRANGE);
 
-        for (final PASpawn spawn : SpawnManager.getPASpawnsStartingWith(arena, "checkpoint")) {
+        for (final PASpawn spawn : SpawnManager.getPASpawnsStartingWith(this.arena, "checkpoint")) {
             final PALocation paLoc = spawn.getLocation();
-            final Set players = checkLocationPresentPlayers(paLoc.toLocation(),
+            final Set players = this.checkLocationPresentPlayers(paLoc.toLocation(),
                     checkDistance);
 
-            arena.getDebugger().i("players: " + StringParser.joinSet(players, ", "));
+            this.arena.getDebugger().i("players: " + StringParser.joinSet(players, ", "));
 
             // players now contains all players near the checkpoint
 
@@ -151,7 +151,7 @@ void checkMove() {
             }
             int value = Integer.parseInt(spawn.getName().substring(10));
             for (String playerName : players) {
-                maybeAddScoreAndBroadCast(playerName, value);
+                this.maybeAddScoreAndBroadCast(playerName, value);
             }
 
         }
@@ -159,22 +159,22 @@ void checkMove() {
 
     private void maybeAddScoreAndBroadCast(final String playerName, int checkpoint) {
 
-        if (!getLifeMap().containsKey(playerName)) {
+        if (!this.getLifeMap().containsKey(playerName)) {
             return;
         }
 
 
-        final int max = arena.getArenaConfig().getInt(CFG.GOAL_CHECKPOINTS_LIVES);
+        final int max = this.arena.getArenaConfig().getInt(CFG.GOAL_CHECKPOINTS_LIVES);
 
-        final int position = max - getLifeMap().get(playerName);
+        final int position = max - this.getLifeMap().get(playerName) + 1;
 
-        if (checkpoint <= position+1) {
-            arena.broadcast(Language.parse(arena, MSG.GOAL_CHECKPOINTS_SCORE,
-                    playerName, position+1 + "/" + max));
-            reduceLivesCheckEndAndCommit(arena, playerName);
+        if (checkpoint == position) {
+            this.arena.broadcast(Language.parse(this.arena, MSG.GOAL_CHECKPOINTS_SCORE,
+                    playerName, position + "/" + max));
+            this.reduceLivesCheckEndAndCommit(this.arena, playerName);
         } else if (checkpoint > position) {
-            arena.broadcast(Language.parse(arena, MSG.GOAL_CHECKPOINTS_YOUMISSED,
-                    String.valueOf(position + 1), String.valueOf(checkpoint)));
+            this.arena.broadcast(Language.parse(this.arena, MSG.GOAL_CHECKPOINTS_YOUMISSED,
+                    String.valueOf(position), String.valueOf(checkpoint)));
         }
 
     }
@@ -207,7 +207,7 @@ private void commitWin(final Arena arena, final String playerName) {
                     winner.getName()));
         }
 
-        getLifeMap().clear();
+        this.getLifeMap().clear();
         new EndRunnable(arena, arena.getArenaConfig().getInt(
                 CFG.TIME_ENDCOUNTDOWN));
     }
@@ -217,51 +217,59 @@ public void commitCommand(final CommandSender sender, final String[] args) {
         // 0 = checkpoint , [1 = number]
 
         if (!(sender instanceof Player)) {
-            Arena.pmsg(sender, Language.parse(arena, MSG.ERROR_ONLY_PLAYERS));
+            Arena.pmsg(sender, Language.parse(this.arena, MSG.ERROR_ONLY_PLAYERS));
             return;
         }
 
         ArenaPlayer ap = ArenaPlayer.parsePlayer(sender.getName());
+        int cpLives = this.arena.getArenaConfig().getInt(CFG.GOAL_CHECKPOINTS_LIVES);
 
-        if (args.length < 2 && arena.getFighters().contains(ap)) {
+        if (args.length < 2 && this.arena.getFighters().contains(ap)) {
             ap.setTelePass(true);
-            int value = arena.getArenaConfig().getInt(CFG.GOAL_CHECKPOINTS_LIVES) - getLifeMap().get(ap.getName());
-            ap.get().teleport(SpawnManager.getSpawnByExactName(arena, "checkpoint"+value).toLocation());
+            int value = cpLives - this.getLifeMap().get(ap.getName());
+            if(value == 0) {
+                ap.get().teleport(SpawnManager.getSpawnByExactName(this.arena, "spawn").toLocation());
+            } else {
+                ap.get().teleport(SpawnManager.getSpawnByExactName(this.arena, "checkpoint"+value).toLocation());
+            }
             ap.setTelePass(false);
             return;
         }
 
-        if (!AbstractArenaCommand.argCountValid(sender, arena, args, new Integer[]{2})) {
+        if (!AbstractArenaCommand.argCountValid(sender, this.arena, args, new Integer[]{2})) {
             return;
         }
         int value;
         try {
             value = Integer.parseInt(args[1]);
-            Math.sqrt(value);
         } catch (Exception e) {
-            arena.msg(sender, Language.parse(arena, MSG.ERROR_NOT_NUMERIC, args[1]));
+            this.arena.msg(sender, Language.parse(this.arena, MSG.ERROR_NOT_NUMERIC, args[1]));
             return;
         }
         Player player = (Player) sender;
         String spawnName = "checkpoint"+value;
-        arena.spawnSet(spawnName, new PALocation(player.getLocation()));
-        arena.msg(sender, Language.parse(arena, MSG.SPAWN_SET, spawnName));
+        if(value > 0 && value <= cpLives) {
+            this.arena.spawnSet(spawnName, new PALocation(player.getLocation()));
+            this.arena.msg(sender, Language.parse(this.arena, MSG.SPAWN_SET, spawnName));
+        } else {
+            this.arena.msg(sender, Language.parse(this.arena, MSG.SPAWN_UNKNOWN, spawnName));
+        }
     }
 
     @Override
     public void commitEnd(final boolean force) {
-        if (arena.realEndRunner != null) {
-            arena.getDebugger().i("[CP] already ending");
+        if (this.arena.realEndRunner != null) {
+            this.arena.getDebugger().i("[CP] already ending");
             return;
         }
-        arena.getDebugger().i("[CP]");
+        this.arena.getDebugger().i("[CP]");
 
-        final PAGoalEvent gEvent = new PAGoalEvent(arena, this, "");
+        final PAGoalEvent gEvent = new PAGoalEvent(this.arena, this, "");
         Bukkit.getPluginManager().callEvent(gEvent);
 
         ArenaPlayer ap = null;
 
-        for (ArenaPlayer aPlayer : arena.getFighters()) {
+        for (ArenaPlayer aPlayer : this.arena.getFighters()) {
             if (aPlayer.getStatus() == Status.FIGHT) {
                 ap = aPlayer;
                 break;
@@ -270,30 +278,29 @@ public void commitEnd(final boolean force) {
 
         if (ap != null && !force) {
             ArenaModuleManager.announce(
-                    arena,
-                    Language.parse(arena, MSG.PLAYER_HAS_WON, ap.getName()), "END");
+                    this.arena,
+                    Language.parse(this.arena, MSG.PLAYER_HAS_WON, ap.getName()), "END");
 
             ArenaModuleManager.announce(
-                    arena,
-                    Language.parse(arena, MSG.PLAYER_HAS_WON, ap.getName()), "WINNER");
-            arena.broadcast(Language.parse(arena, MSG.PLAYER_HAS_WON, ap.getName()));
+                    this.arena,
+                    Language.parse(this.arena, MSG.PLAYER_HAS_WON, ap.getName()), "WINNER");
+            this.arena.broadcast(Language.parse(this.arena, MSG.PLAYER_HAS_WON, ap.getName()));
         }
 
-        if (ArenaModuleManager.commitEnd(arena, ap.getArenaTeam())) {
+        if (ArenaModuleManager.commitEnd(this.arena, ap.getArenaTeam())) {
             return;
         }
-        new EndRunnable(arena, arena.getArenaConfig().getInt(
-                CFG.TIME_ENDCOUNTDOWN));
+        new EndRunnable(this.arena, this.arena.getArenaConfig().getInt(CFG.TIME_ENDCOUNTDOWN));
     }
 
     @Override
     public void displayInfo(final CommandSender sender) {
         sender.sendMessage("needed points: " +
-                arena.getArenaConfig().getInt(CFG.GOAL_CHECKPOINTS_LIVES));
+                this.arena.getArenaConfig().getInt(CFG.GOAL_CHECKPOINTS_LIVES));
         sender.sendMessage("claim range: " +
-                arena.getArenaConfig().getInt(CFG.GOAL_CHECKPOINTS_CLAIMRANGE));
+                this.arena.getArenaConfig().getInt(CFG.GOAL_CHECKPOINTS_CLAIMRANGE));
         sender.sendMessage("tick interval (ticks): " +
-                arena.getArenaConfig().getInt(CFG.GOAL_CHECKPOINTS_TICKINTERVAL));
+                this.arena.getArenaConfig().getInt(CFG.GOAL_CHECKPOINTS_TICKINTERVAL));
     }
 
     @Override
@@ -301,7 +308,7 @@ public PACheck getLives(final PACheck res, final ArenaPlayer aPlayer) {
         if (res.getPriority() <= PRIORITY + 1000) {
             res.setError(
                     this,
-                    String.valueOf(getLifeMap().getOrDefault(aPlayer.getArenaTeam().getName(), 0))
+                    String.valueOf(this.getLifeMap().getOrDefault(aPlayer.getArenaTeam().getName(), 0))
             );
         }
         return res;
@@ -312,8 +319,8 @@ public boolean hasSpawn(final String string) {
         if (string.startsWith("checkpoint") || string.startsWith("spawn")) {
             return true;
         }
-        if (arena.getArenaConfig().getBoolean(CFG.GENERAL_CLASSSPAWN)) {
-            for (final ArenaClass aClass : arena.getClasses()) {
+        if (this.arena.getArenaConfig().getBoolean(CFG.GENERAL_CLASSSPAWN)) {
+            for (final ArenaClass aClass : this.arena.getClasses()) {
                 if (string.toLowerCase().contains(aClass.getName().toLowerCase() + "spawn")) {
                     return true;
                 }
@@ -325,8 +332,8 @@ public boolean hasSpawn(final String string) {
     @Override
     public void initate(final Player player) {
         final ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(player.getName());
-        if (!getLifeMap().containsKey(aPlayer.getName())) {
-            getLifeMap().put(aPlayer.getName(), arena.getArenaConfig()
+        if (!this.getLifeMap().containsKey(aPlayer.getName())) {
+            this.getLifeMap().put(aPlayer.getName(), this.arena.getArenaConfig()
                     .getInt(CFG.GOAL_CHECKPOINTS_LIVES));
         }
     }
@@ -338,51 +345,47 @@ public boolean isInternal() {
 
     @Override
     public void lateJoin(final Player player) {
-        initate(player);
+        this.initate(player);
     }
 
     @Override
     public void parseStart() {
-        getLifeMap().clear();
-        for (final ArenaPlayer player : arena.getFighters()) {
-            arena.getDebugger().i("adding player " + player.getName());
-            getLifeMap().put(player.getName(),
-                    arena.getArenaConfig().getInt(CFG.GOAL_CHECKPOINTS_LIVES, 3));
+        this.getLifeMap().clear();
+        for (final ArenaPlayer player : this.arena.getFighters()) {
+            this.arena.getDebugger().i("adding player " + player.getName());
+            this.getLifeMap().put(player.getName(),
+                    this.arena.getArenaConfig().getInt(CFG.GOAL_CHECKPOINTS_LIVES, 3));
         }
 
-        final CheckPointsMainRunnable cpMainRunner = new CheckPointsMainRunnable(arena, this);
-        final int tickInterval = arena.getArenaConfig().getInt(CFG.GOAL_CHECKPOINTS_TICKINTERVAL);
-        cpMainRunner.rID = Bukkit.getScheduler().scheduleSyncRepeatingTask(
-                PVPArena.instance, cpMainRunner, tickInterval, tickInterval);
+        final CheckPointsMainRunnable cpMainRunner = new CheckPointsMainRunnable(this.arena, this);
+        final int tickInterval = this.arena.getArenaConfig().getInt(CFG.GOAL_CHECKPOINTS_TICKINTERVAL);
+        cpMainRunner.runTaskTimer(PVPArena.instance, tickInterval, tickInterval);
     }
 
-    private boolean reduceLivesCheckEndAndCommit(final Arena arena, final String player) {
+    private void reduceLivesCheckEndAndCommit(final Arena arena, final String player) {
 
         arena.getDebugger().i("reducing lives of player " + player);
-        if (getLifeMap().get(player) != null) {
-            final int iLives = getLifeMap().get(player) - 1;
+        if (this.getLifeMap().get(player) != null) {
+            final int iLives = this.getLifeMap().get(player) - 1;
             if (iLives > 0) {
-                getLifeMap().put(player, iLives);
+                this.getLifeMap().put(player, iLives);
             } else {
-                getLifeMap().remove(player);
-                commitWin(arena, player);
-                return true;
+                this.getLifeMap().remove(player);
+                this.commitWin(arena, player);
             }
         }
-        return false;
     }
 
     @Override
     public void reset(final boolean force) {
-        getLifeMap().clear();
+        this.getLifeMap().clear();
     }
 
     @Override
     public Map timedEnd(final Map scores) {
 
-        for (final ArenaTeam team : arena.getTeams()) {
-            double score = getLifeMap().containsKey(team.getName()) ? getLifeMap()
-                    .get(team.getName()) : 0;
+        for (final ArenaTeam team : this.arena.getTeams()) {
+            double score = this.getLifeMap().getOrDefault(team.getName(), 0);
             if (scores.containsKey(team.getName())) {
                 scores.put(team.getName(), scores.get(team.getName()) + score);
             } else {
@@ -393,8 +396,7 @@ public Map timedEnd(final Map scores) {
         return scores;
     }
 
-    class CheckPointsMainRunnable implements Runnable {
-        public int rID = -1;
+    private class CheckPointsMainRunnable extends BukkitRunnable {
         private final Arena arena;
         //private final Debug debug = new Debug(39);
         private final GoalCheckPoints goal;
@@ -410,10 +412,10 @@ public CheckPointsMainRunnable(final Arena arena, final GoalCheckPoints goal) {
          */
         @Override
         public void run() {
-            if (!arena.isFightInProgress() || arena.realEndRunner != null) {
-                Bukkit.getScheduler().cancelTask(rID);
+            if (!this.arena.isFightInProgress() || this.arena.realEndRunner != null) {
+                this.cancel();
             }
-            goal.checkMove();
+            this.goal.checkMove();
         }
     }
 }

From f67abcd79846b524d3568fb645d6f4936209ec61 Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Thu, 14 May 2020 21:39:46 +0200
Subject: [PATCH 10/43] v1.15 - fix "loungeinteract" parameter not working -
 issue #27

---
 .../slipcor/pvparena/listeners/PlayerListener.java    | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/src/net/slipcor/pvparena/listeners/PlayerListener.java b/src/net/slipcor/pvparena/listeners/PlayerListener.java
index 1bec57349..6f38f42f0 100644
--- a/src/net/slipcor/pvparena/listeners/PlayerListener.java
+++ b/src/net/slipcor/pvparena/listeners/PlayerListener.java
@@ -46,6 +46,8 @@
 
 import java.util.*;
 
+import static java.util.Arrays.asList;
+
 /**
  * 
  * Player Listener class
@@ -526,7 +528,11 @@ public void onPlayerInteract(final PlayerInteractEvent event) {
             if (whyMe) {
                 arena.getDebugger().i("exiting! fight in progress AND no INBATTLEJOIN arena!", player); return;
             }
-            if (aPlayer.getStatus() != Status.LOUNGE && aPlayer.getStatus() != Status.READY) {
+            if (asList(Status.LOUNGE, Status.READY).contains(aPlayer.getStatus()) &&
+                    arena.getArenaConfig().getBoolean(CFG.PERMS_LOUNGEINTERACT)) {
+                arena.getDebugger().i("allowing lounge interaction due to config setting!");
+                event.setCancelled(false);
+            } else if (aPlayer.getStatus() != Status.LOUNGE && aPlayer.getStatus() != Status.READY) {
                 arena.getDebugger().i("cancelling: not fighting nor in the lounge", player);
                 event.setCancelled(true);
             } else if (aPlayer.getArena() != null && team != null) {
@@ -570,7 +576,8 @@ public void onPlayerInteract(final PlayerInteractEvent event) {
             }
 
             if (whyMe) {
-                arena.getDebugger().i("exiting! fight in progress AND no INBATTLEJOIN arena!", player); return;
+                arena.getDebugger().i("exiting! fight in progress AND no INBATTLEJOIN arena!", player);
+                return;
             }
             arena.getDebugger().i("block click!", player);
 

From 568dbe89e261cf7316d252995b8a10e15ceaf772 Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Sat, 16 May 2020 19:50:54 +0200
Subject: [PATCH 11/43] v1.15 - add update documentation for this version

---
 doc/update-from-1-3-x.md | 23 ---------------
 doc/update-version.md    | 62 ++++++++++++++++++++++++++++++++++++++++
 readme.md                |  4 +--
 3 files changed, 64 insertions(+), 25 deletions(-)
 delete mode 100644 doc/update-from-1-3-x.md
 create mode 100644 doc/update-version.md

diff --git a/doc/update-from-1-3-x.md b/doc/update-from-1-3-x.md
deleted file mode 100644
index 53ea8d859..000000000
--- a/doc/update-from-1-3-x.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Upgrading from 1.3.x
-
-If you want to upgrade your arena configurations to PVPArena 1.13 version or above, you have
-to update two things : Item Lists and Schematics
-
-## Item lists
-
-Probably the worst thing to upgrade, just clear the inventories of your arena classes and
-re-create them. Be also careful to remove items list of pvparena modules like **chestfiller** 
-or **blockdissolve**.
-
-## WorldEdit
-
-You have to remove Worldedit schematics too. A big part of blocks will not be pasted if you
-keep it as it is and chest orientation will be broken.
-
-So just remove your schematics files and re-create them with `/pa [arena] regsave [regionname]`
-
-
-## Miscellaneous
-
-**In "flags" goal :** Just replace `WOOL` block name by `WHITE_WOOL`. The color will be
-automatically defined with the color of the team.
\ No newline at end of file
diff --git a/doc/update-version.md b/doc/update-version.md
new file mode 100644
index 000000000..d9385b332
--- /dev/null
+++ b/doc/update-version.md
@@ -0,0 +1,62 @@
+# Upgrading from 1.14.x
+
+If you want to upgrade your arena configurations to PVPArena 1.15 version or above, please update
+these two things :
+
+## Goal PhysicalFlags
+
+If you use *physicalFlags* goal for your arenas, just rename `flags` block to `physicalFlags` in
+your config file.
+
+Example : 
+
+*Replace this*
+```yaml
+goal:
+  endCountDown: 5
+  flags:
+    flives: 3
+    mustBeSafe: true
+    woolFlagHead: true
+    effect: none
+    flagType: WHITE_WOOL
+```
+*with this*
+```yaml
+goal:
+  endCountDown: 5
+  physicalFlags:
+    flives: 3
+    mustBeSafe: true
+    woolFlagHead: true
+    effect: none
+    flagType: WHITE_WOOL
+```
+
+## Goal checkpoints
+
+In checkpoint goal, checkpoint indexes started at 0, now they start at 1. Just edit your config
+file and decrease all checkpoints number by one in `spawns` block.
+
+Example : 
+
+*Replace this*
+```yaml
+spawns:
+  checkpoint0: world,299,64,1276,-357.7568359375,4.2000017166137695
+  checkpoint1: world,299,64,1276,11.695333480834961,22.20012664794922
+  checkpoint2: world,300,64,1281,-5.704666614532471,23.700136184692383
+  checkpoint3: world,297,64,1285,14.695302963256836,50.40021514892578
+  checkpoint4: world,298,64,1289,53.69533920288086,54.75028610229492
+  checkpoint5: world,295,64,1292,1.795335054397583,46.80023193359375
+```
+*with this*
+```yaml
+spawns:
+  checkpoint1: world,299,64,1276,-357.7568359375,4.2000017166137695
+  checkpoint2: world,299,64,1276,11.695333480834961,22.20012664794922
+  checkpoint3: world,300,64,1281,-5.704666614532471,23.700136184692383
+  checkpoint4: world,297,64,1285,14.695302963256836,50.40021514892578
+  checkpoint5: world,298,64,1289,53.69533920288086,54.75028610229492
+  checkpoint6: world,295,64,1292,1.795335054397583,46.80023193359375
+```
\ No newline at end of file
diff --git a/readme.md b/readme.md
index 086970c9b..1165b3c39 100644
--- a/readme.md
+++ b/readme.md
@@ -1,7 +1,7 @@
 ![PVP-Arena](/doc/images/logo.png)
 
 ***
-**IF YOU'RE UPGRADING FROM 1.3.x VERSION OR BELOW, PLEASE READ [UPGRADE DOCUMENTATION](doc/update-from-1-3-x.md)**
+**IF YOU'RE UPGRADING FROM 1.14.x VERSION OR BELOW, PLEASE READ [UPGRADE DOCUMENTATION](doc/update-version.md)**
 ***
 
 **Enhance your server by adding a new dimension of PVP battles!**
@@ -33,7 +33,7 @@ This flexibility is achieved on the one hand by a module loader created by Nodin
 
 ## Dependencies
 
-- Spigot 1.13
+- Spigot 1.13+
 
 ***
 

From ef3aa9e017074fc6ed48a9373c9cbd55bece40b3 Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Fri, 22 May 2020 02:07:05 +0200
Subject: [PATCH 12/43] v1.15 - fix handling of colorable items

---
 src/net/slipcor/pvparena/core/ColorUtils.java | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/net/slipcor/pvparena/core/ColorUtils.java b/src/net/slipcor/pvparena/core/ColorUtils.java
index 3c2ac1507..3d409c14f 100644
--- a/src/net/slipcor/pvparena/core/ColorUtils.java
+++ b/src/net/slipcor/pvparena/core/ColorUtils.java
@@ -14,8 +14,6 @@
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import static net.slipcor.pvparena.core.StringParser.joinArray;
-
 public final class ColorUtils {
 
     private static final Debug DEBUG = new Debug(18);
@@ -101,9 +99,8 @@ public static boolean isColorableMaterial(Material type) {
      */
     public static Material getColoredMaterial(DyeColor dyeColor, Material typeMaterial) {
         String color = dyeColor.name();
-        String[] typeNameArr = typeMaterial.name().split("_");
-        String uncoloredMaterial = joinArray(Arrays.copyOfRange(typeNameArr, 1, typeNameArr.length), "_");
-        return Material.valueOf(color + "_" + uncoloredMaterial);
+        String materialSuffix = getMaterialSuffix(typeMaterial);
+        return Material.valueOf(color + "_" + materialSuffix);
     }
 
     public static boolean isSubType(Material type, Material check) {
@@ -111,7 +108,10 @@ public static boolean isSubType(Material type, Material check) {
     }
 
     private static String getMaterialSuffix(Material material) {
-        return material.name().contains("_") ? material.name().split("_", 2)[1] : "";
+        return getColorableSuffixes().stream()
+                .filter(suffix -> material.name().endsWith(suffix))
+                .findFirst()
+                .orElse("");
     }
 
     /**
@@ -121,7 +121,7 @@ private static List getColorableSuffixes() {
         return Stream.of(Material.values())
                 .filter(m -> m.name().startsWith("MAGENTA_"))
                 .filter(Material::isBlock)
-                .map(ColorUtils::getMaterialSuffix)
+                .map(m -> m.name().split("MAGENTA_", 2)[1])
                 .collect(Collectors.toList());
     }
 

From 43de715fe4530e144f94a055512c190617d8cd0d Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Tue, 26 May 2020 14:47:19 +0200
Subject: [PATCH 13/43] v1.15 - delay scoreboard reset

---
 src/net/slipcor/pvparena/arena/Arena.java | 26 ++++++++++-------------
 1 file changed, 11 insertions(+), 15 deletions(-)

diff --git a/src/net/slipcor/pvparena/arena/Arena.java b/src/net/slipcor/pvparena/arena/Arena.java
index f35a1c1ce..9bd6a7ac5 100644
--- a/src/net/slipcor/pvparena/arena/Arena.java
+++ b/src/net/slipcor/pvparena/arena/Arena.java
@@ -1346,8 +1346,8 @@ public void run() {
                     new RunLater().run();
                 } else {
                     try {
-                        Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RunLater(), 2L);
-                    } catch (IllegalStateException e) {
+                        Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RunLater(), 4L);
+                    } catch (IllegalStateException ignored) {
 
                     }
                 }
@@ -1365,21 +1365,17 @@ public void run() {
             }
             final ArenaPlayer ap = ArenaPlayer.parsePlayer(player.getName());
             try {
-                Bukkit.getScheduler().runTaskLater(PVPArena.instance, new Runnable() {
-                    @Override
-                    public void run() {
-
-                        if (ap.hasBackupScoreboard()) {
-                            player.setScoreboard(ap.getBackupScoreboard());
-                            if (ap.getBackupScoreboardTeam() != null) {
-                                ap.getBackupScoreboardTeam().addEntry(ap.getName());
-                            }
-                            ap.setBackupScoreboardTeam(null);
-                            ap.setBackupScoreboard(null);
+                Bukkit.getScheduler().runTaskLater(PVPArena.instance, () -> {
+                    if (ap.hasBackupScoreboard()) {
+                        player.setScoreboard(ap.getBackupScoreboard());
+                        if (ap.getBackupScoreboardTeam() != null) {
+                            ap.getBackupScoreboardTeam().addEntry(ap.getName());
                         }
+                        ap.setBackupScoreboardTeam(null);
+                        ap.setBackupScoreboard(null);
                     }
-                }, 3L);
-            } catch (IllegalPluginAccessException e) {
+                }, 5L);
+            } catch (IllegalPluginAccessException ignored) {
 
             }
         }

From cea80e6cc458a939512eef8f871fc1247576067c Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Wed, 27 May 2020 18:56:48 +0200
Subject: [PATCH 14/43] v1.15 - delay scoreboard init (once again) - issue #35

---
 src/net/slipcor/pvparena/arena/Arena.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/net/slipcor/pvparena/arena/Arena.java b/src/net/slipcor/pvparena/arena/Arena.java
index 9bd6a7ac5..783265661 100644
--- a/src/net/slipcor/pvparena/arena/Arena.java
+++ b/src/net/slipcor/pvparena/arena/Arena.java
@@ -1656,7 +1656,7 @@ public void run() {
                 }
 
             }
-            Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RunLater(), 3L);
+            Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RunLater(), 5L);
         } else {
             final Scoreboard board = getStandardScoreboard();
             ArenaPlayer ap = ArenaPlayer.parsePlayer(player.getName());

From 67393d596c333b74a126f03961279955ce8605cd Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Wed, 27 May 2020 21:03:07 +0200
Subject: [PATCH 15/43] v1.15 - fix worldguard sofdepend warning on load

---
 src/plugin.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/plugin.yml b/src/plugin.yml
index 637ee047c..a85f83219 100644
--- a/src/plugin.yml
+++ b/src/plugin.yml
@@ -5,7 +5,7 @@ prefix: PVP Arena
 main: net.slipcor.pvparena.PVPArena
 version: ${project.version}${buildVersion}
 api-version: 1.13
-softdepend: [Spout,Multiverse-Core,MultiWorld,WormholeXTreme,Vault,WorldEdit,LibsDisguises,DisguiseCraft,TagAPI,My Worlds,CrackShot]
+softdepend: [Spout,Multiverse-Core,MultiWorld,WormholeXTreme,Vault,WorldEdit,WorldGuard,LibsDisguises,DisguiseCraft,My Worlds,CrackShot]
 description: create, manage and enhance PvP arenas
 website: http://dev.bukkit.org/server-mods/pvparena
 dev-url: http://dev.bukkit.org/server-mods/pvparena

From 980a9129997464071d0a018817df56d49bc95d8c Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Wed, 27 May 2020 21:04:04 +0200
Subject: [PATCH 16/43] v1.15 - fix "/pa class load" error appearing with some
 mods

---
 src/net/slipcor/pvparena/arena/ArenaPlayer.java  | 6 +++---
 src/net/slipcor/pvparena/commands/PAA_Class.java | 7 ++++++-
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/net/slipcor/pvparena/arena/ArenaPlayer.java b/src/net/slipcor/pvparena/arena/ArenaPlayer.java
index 037fe7053..f7f415db9 100644
--- a/src/net/slipcor/pvparena/arena/ArenaPlayer.java
+++ b/src/net/slipcor/pvparena/arena/ArenaPlayer.java
@@ -768,11 +768,11 @@ public final void setArena(final Arena arena) {
      * @param aClass the arena class to set
      */
     public void setArenaClass(final ArenaClass aClass) {
-        final PAPlayerClassChangeEvent event = new PAPlayerClassChangeEvent(arena, get(), aClass);
+        final PAPlayerClassChangeEvent event = new PAPlayerClassChangeEvent(this.arena, this.get(), aClass);
         Bukkit.getServer().getPluginManager().callEvent(event);
         this.aClass = event.getArenaClass();
-        if (arena != null) {
-            ArenaModuleManager.parseClassChange(arena, get(), this.aClass);
+        if (this.arena != null && this.getStatus() != Status.NULL) {
+            ArenaModuleManager.parseClassChange(this.arena, this.get(), this.aClass);
         }
     }
 
diff --git a/src/net/slipcor/pvparena/commands/PAA_Class.java b/src/net/slipcor/pvparena/commands/PAA_Class.java
index 8b13862a9..c6769c098 100644
--- a/src/net/slipcor/pvparena/commands/PAA_Class.java
+++ b/src/net/slipcor/pvparena/commands/PAA_Class.java
@@ -8,6 +8,7 @@
 import net.slipcor.pvparena.core.Help.HELP;
 import net.slipcor.pvparena.core.Language;
 import net.slipcor.pvparena.core.Language.MSG;
+import net.slipcor.pvparena.managers.InventoryManager;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 import org.bukkit.inventory.ItemStack;
@@ -79,7 +80,11 @@ public void commit(final Arena arena, final CommandSender sender, final String[]
             Arena.pmsg(player, Language.parse(arena, MSG.CLASS_SAVED, args[1]));
         } else if ("load".equalsIgnoreCase(args[0])) {
             final ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(sender.getName());
-            ArenaPlayer.backupAndClearInventory(arena, aPlayer.get());
+            if(aPlayer.getArenaClass() == null) {
+                ArenaPlayer.backupAndClearInventory(arena, aPlayer.get());
+            } else {
+                InventoryManager.clearInventory(aPlayer.get());
+            }
             arena.selectClass(aPlayer, args[1]);
         } else if ("remove".equalsIgnoreCase(args[0])) {
             final Player player = (Player) sender;

From 962df4e2958984a70ce03743f95679406b6edcc6 Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Fri, 29 May 2020 00:44:17 +0200
Subject: [PATCH 17/43] v1.15 - add special leave hook for mods and leave
 command for LateLounge

---
 lang/lang_en.yml                                    |  1 +
 lang/lang_fr.yml                                    |  1 +
 src/net/slipcor/pvparena/commands/PAG_Leave.java    |  8 ++++++++
 src/net/slipcor/pvparena/core/Language.java         |  1 +
 src/net/slipcor/pvparena/loadables/ArenaModule.java | 10 ++++++++++
 5 files changed, 21 insertions(+)

diff --git a/lang/lang_en.yml b/lang/lang_en.yml
index b7cd3d217..86a69781b 100644
--- a/lang/lang_en.yml
+++ b/lang/lang_en.yml
@@ -544,6 +544,7 @@ nulang:
       llposition: You are on queue position %1%!
       llrejoin: Ready check has caught you not being able to join. Rejoin when you can!
       llwait: Arena will be starting soon, please wait!
+      llleave: You have left the queue of the %1% arena.
     playerfinder:
       near: 'Nearest player: %1% blocks!'
       point: Compass pointing to nearest player!
diff --git a/lang/lang_fr.yml b/lang/lang_fr.yml
index a913bd22a..c4c4c7990 100644
--- a/lang/lang_fr.yml
+++ b/lang/lang_fr.yml
@@ -595,6 +595,7 @@ nulang:
       llrejoin: Vous n'êtes pas en mesure de rejoindre les joueurs prêts. Rejoignez-les
         quand vous pouvez !
       llwait: L'arène va ouvrir prochainement, veuillez être patient !
+      llleave: Vous venez de quitter la file d'attente de l'arène %1%.
     playerfinder:
       near: 'Joueur le plus proche: %1% blocs!'
       point: La boussole pointe sur le joueur le plus proche !
diff --git a/src/net/slipcor/pvparena/commands/PAG_Leave.java b/src/net/slipcor/pvparena/commands/PAG_Leave.java
index da8e053b5..1cef43aa1 100644
--- a/src/net/slipcor/pvparena/commands/PAG_Leave.java
+++ b/src/net/slipcor/pvparena/commands/PAG_Leave.java
@@ -7,6 +7,7 @@
 import net.slipcor.pvparena.core.Help.HELP;
 import net.slipcor.pvparena.core.Language;
 import net.slipcor.pvparena.core.Language.MSG;
+import net.slipcor.pvparena.loadables.ArenaModule;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 
@@ -45,6 +46,13 @@ public void commit(final Arena arena, final CommandSender sender, final String[]
 
         final ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(sender.getName());
 
+        // Handle modules which need to leave even if players aren't in an arena
+        for (final ArenaModule mod : arena.getMods()) {
+            if(mod.handleSpecialLeave(aPlayer)) {
+                return;
+            }
+        }
+
         if (!arena.hasPlayer(aPlayer.get())) {
 
             arena.msg(sender, Language.parse(arena, MSG.ERROR_NOT_IN_ARENA));
diff --git a/src/net/slipcor/pvparena/core/Language.java b/src/net/slipcor/pvparena/core/Language.java
index e76b9ef6b..ce7753037 100644
--- a/src/net/slipcor/pvparena/core/Language.java
+++ b/src/net/slipcor/pvparena/core/Language.java
@@ -648,6 +648,7 @@ public enum MSG {
         MODULE_LATELOUNGE_POSITION("nulang.mod.latelounge.llposition", "You are in queue. Position: #%1%"),
         MODULE_LATELOUNGE_REJOIN("nulang.mod.latelounge.llrejoin", "Ready check has caught you not being able to join. Rejoin when you can!"),
         MODULE_LATELOUNGE_WAIT("nulang.mod.latelounge.llwait", "Arena will be starting soon, please wait!"),
+        MODULE_LATELOUNGE_LEAVE("nulang.mod.latelounge.llleave", "You have left the queue of the %1% arena."),
 
         MODULE_PLAYERFINDER_NEAR("nulang.mod.playerfinder.near", "Nearest player: %1% blocks!"),
         MODULE_PLAYERFINDER_POINT("nulang.mod.playerfinder.point", "Compass pointing to nearest player!"),
diff --git a/src/net/slipcor/pvparena/loadables/ArenaModule.java b/src/net/slipcor/pvparena/loadables/ArenaModule.java
index fd7149667..965827374 100644
--- a/src/net/slipcor/pvparena/loadables/ArenaModule.java
+++ b/src/net/slipcor/pvparena/loadables/ArenaModule.java
@@ -493,6 +493,16 @@ public boolean tryDeathOverride(final ArenaPlayer aPlayer,
         return false;
     }
 
+    /**
+     * Call a special leave directly from the module
+     *
+     * @param aPlayer the player who leaves
+     * @return true if a module cares
+     */
+    public boolean handleSpecialLeave(final ArenaPlayer aPlayer) {
+        return false;
+    }
+
     /**
      * hook into a player removal
      *

From d52d04444a637503d3ac8f00be7f10412eeebe07 Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Fri, 5 Jun 2020 01:58:03 +0200
Subject: [PATCH 18/43] v1.15 - simplify scoreboard management

---
 src/net/slipcor/pvparena/arena/Arena.java     | 402 +++++++-----------
 .../slipcor/pvparena/arena/ArenaPlayer.java   |   9 +-
 2 files changed, 153 insertions(+), 258 deletions(-)

diff --git a/src/net/slipcor/pvparena/arena/Arena.java b/src/net/slipcor/pvparena/arena/Arena.java
index 783265661..f178a07ec 100644
--- a/src/net/slipcor/pvparena/arena/Arena.java
+++ b/src/net/slipcor/pvparena/arena/Arena.java
@@ -41,6 +41,9 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.*;
+import java.util.stream.Collectors;
+
+import static java.util.Optional.ofNullable;
 
 /**
  * 
@@ -410,15 +413,9 @@ public Player getEntityOwner(final Entity entity) {
      * hand over everyone being part of the arena
      */
     public Set getEveryone() {
-
-        final Set players = new HashSet<>();
-
-        for (final ArenaPlayer ap : ArenaPlayer.getAllArenaPlayers()) {
-            if (equals(ap.getArena())) {
-                players.add(ap);
-            }
-        }
-        return players;
+        return ArenaPlayer.getAllArenaPlayers().stream()
+                .filter(ap -> this.equals(ap.getArena()))
+                .collect(Collectors.toSet());
     }
 
     /**
@@ -529,90 +526,63 @@ public Set getSpawns() {
     }
 
     private Scoreboard getSpecialScoreboard() {
-        if (scoreboard == null) {
-            scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
-/*
-            Objective oBM = Bukkit.getScoreboardManager().getMainScoreboard().getObjective(DisplaySlot.BELOW_NAME);
-            if (oBM != null) {
-                oBM = scoreboard.registerNewObjective(oBM.getCriteria(), oBM.getDisplayName());
-                oBM.setDisplaySlot(DisplaySlot.BELOW_NAME);
+        if (this.scoreboard == null) {
+            this.scoreboard = this.getCommonScoreboard(true);
 
-            }
-
-            Objective oTB = Bukkit.getScoreboardManager().getMainScoreboard().getObjective(DisplaySlot.PLAYER_LIST);
-            if (oTB != null) {
-                oTB = scoreboard.registerNewObjective(oTB.getCriteria(), oTB.getDisplayName());
-                oTB.setDisplaySlot(DisplaySlot.PLAYER_LIST);
-            }
-*/
-            for (final ArenaTeam team : getTeams()) {
+            // length = 18 without arena name
+            String sbHeaderPrefix = ChatColor.GREEN + "PVP Arena" + ChatColor.RESET + " - " + ChatColor.YELLOW;
+            String sbHeaderName = sbHeaderPrefix + this.getName();
 
-                try {
-                    scoreboard.registerNewTeam(team.getName());
-                    final Team bukkitTeam = scoreboard.getTeam(team.getName());
-                    if (!getArenaConfig().getBoolean(CFG.PLAYER_COLLISION)) {
-                        bukkitTeam.setOption(Team.Option.COLLISION_RULE, Team.OptionStatus.NEVER);
-                    }
-                    bukkitTeam.setPrefix(team.getColor().toString());
-                    bukkitTeam.setSuffix(ChatColor.RESET.toString());
-                    bukkitTeam.setColor(team.getColor());
-                    bukkitTeam.addEntry(team.getName());
-                    bukkitTeam.setAllowFriendlyFire(getArenaConfig().getBoolean(CFG.PERMS_TEAMKILL));
-
-                    bukkitTeam.setCanSeeFriendlyInvisibles(!isFreeForAll());
-                } catch (final Exception e) {
-                    e.printStackTrace();
-                }
-            }
-
-            if (scoreboard.getObjective("lives") != null) {
-                scoreboard.getObjective("lives").unregister();
-                if (scoreboard.getObjective(DisplaySlot.SIDEBAR) != null) {
-                    scoreboard.getObjective(DisplaySlot.SIDEBAR).unregister();
+            if (sbHeaderName.length() > 32) {
+                if (this.prefix.length() <= 14) {
+                    sbHeaderName = sbHeaderPrefix + this.prefix;
+                } else {
+                    sbHeaderName = sbHeaderName.substring(0, 32);
                 }
             }
 
-
-
-            String name = ChatColor.GREEN + "PVP Arena" + ChatColor.RESET + " - " + ChatColor.YELLOW + getName();
-
-            if (name.length() > 32) {
-                if (prefix.length() < getName().length()) {
-                    name = ChatColor.GREEN + "PVP Arena" + ChatColor.RESET + " - " + ChatColor.YELLOW + prefix;
-                } else {
-                    name = name.substring(0, 32);
+            if (this.scoreboard.getObjective("lives") != null) {
+                this.scoreboard.getObjective("lives").unregister();
+                if (this.scoreboard.getObjective(DisplaySlot.SIDEBAR) != null) {
+                    this.scoreboard.getObjective(DisplaySlot.SIDEBAR).unregister();
                 }
             }
-            Objective obj = scoreboard.registerNewObjective("lives", "dummy", name); //deathCount
+            Objective obj = this.scoreboard.registerNewObjective("lives", "dummy", sbHeaderName); //deathCount
 
             if (this.isFightInProgress()) {
                 obj.setDisplaySlot(DisplaySlot.SIDEBAR);
             }
         }
-        return scoreboard;
+        return this.scoreboard;
     }
 
     private Scoreboard getStandardScoreboard() {
-        if (scoreboard == null) {
-            scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
-            for (final ArenaTeam team : getTeams()) {
-                final Team sTeam = scoreboard.registerNewTeam(team.getName());
-                sTeam.setPrefix(team.getColor().toString());
-                sTeam.setSuffix(ChatColor.RESET.toString());
-                sTeam.setColor(team.getColor());
-                sTeam.setCanSeeFriendlyInvisibles(!isFreeForAll());
-                if (!getArenaConfig().getBoolean(CFG.PLAYER_COLLISION)) {
-                    sTeam.setOption(Team.Option.COLLISION_RULE, Team.OptionStatus.NEVER);
+        if (this.scoreboard == null) {
+            return this.getCommonScoreboard(false);
+        }
+        return this.scoreboard;
+    }
+
+    private Scoreboard getCommonScoreboard(boolean addTeamEntry) {
+        if (this.scoreboard == null) {
+            this.scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
+            for (final ArenaTeam team : this.getTeams()) {
+                final Team sbTeam = this.scoreboard.registerNewTeam(team.getName());
+                sbTeam.setPrefix(team.getColor().toString());
+                sbTeam.setSuffix(ChatColor.RESET.toString());
+                sbTeam.setColor(team.getColor());
+                sbTeam.setCanSeeFriendlyInvisibles(!this.isFreeForAll());
+                sbTeam.setAllowFriendlyFire(this.getArenaConfig().getBoolean(CFG.PERMS_TEAMKILL));
+                if (!this.getArenaConfig().getBoolean(CFG.PLAYER_COLLISION)) {
+                    sbTeam.setOption(Team.Option.COLLISION_RULE, Team.OptionStatus.NEVER);
                 }
-                for (final ArenaPlayer aPlayer : team.getTeamMembers()) {
-                    sTeam.addEntry(aPlayer.getName());
+
+                if(addTeamEntry) {
+                    sbTeam.addEntry(team.getName());
                 }
-            } /*
-            for (Objective o : scoreboard.getObjectives()) {
-                o.setDisplaySlot(DisplaySlot.PLAYER_LIST);
-            } */
+            }
         }
-        return scoreboard;
+        return this.scoreboard;
     }
 
     public ArenaTeam getTeam(final String name) {
@@ -1309,46 +1279,50 @@ public void resetPlayers(final boolean force) {
     }
 
     private void resetScoreboard(final Player player, final boolean force, final boolean soft) {
-        if (getArenaConfig().getBoolean(CFG.USES_SCOREBOARD)) {
-            getDebugger().i("ScoreBoards: "+(soft?"(soft) ":"")+"remove: " + player.getName(), player);
+        if (this.getArenaConfig().getBoolean(CFG.USES_SCOREBOARD)) {
+            this.getDebugger().i("ScoreBoards: "+(soft?"(soft) ":"")+"remove: " + player.getName(), player);
             try {
-                if (scoreboard != null) {
-                    for (final Team team : scoreboard.getTeams()) {
+                if (this.scoreboard != null) {
+                    for (final Team team : this.scoreboard.getTeams()) {
                         if (team.hasEntry(player.getName())) {
                             team.removeEntry(player.getName());
                             if (soft) {
-                                updateScoreboards();
+                                this.updateScoreboards();
                                 return;
                             }
-                            scoreboard.resetScores(player.getName());
+                            this.scoreboard.resetScores(player.getName());
                         }
                     }
                 } else {
-                    getDebugger().i("ScoreBoards: scoreboard is null!");
+                    this.getDebugger().i("ScoreBoards: scoreboard is null!");
                     return;
                 }
+
                 final ArenaPlayer ap = ArenaPlayer.parsePlayer(player.getName());
-                class RunLater implements Runnable {
-                    @Override
-                    public void run() {
-                        if (ap.hasBackupScoreboard()) {
-                            player.setScoreboard(ap.getBackupScoreboard());
+                if (ap.hasBackupScoreboard()) {
+                    this.getDebugger().i("ScoreBoards: restoring " + ap.get());
+
+                    class RunLater extends BukkitRunnable {
+                        @Override
+                        public void run() {
+                            Scoreboard backupScoreboard = ap.getBackupScoreboard();
                             if (ap.getBackupScoreboardTeam() != null && !force) {
-                                ap.getBackupScoreboardTeam().addEntry(ap.getName());
+                                backupScoreboard.getTeam(ap.getBackupScoreboardTeam()).addEntry(ap.getName());
                             }
+                            player.setScoreboard(backupScoreboard);
                             ap.setBackupScoreboardTeam(null);
                             ap.setBackupScoreboard(null);
                         }
                     }
-                }
-                getDebugger().i("ScoreBoards: maybe restoring " + ap.get());
-                if (force) {
-                    new RunLater().run();
-                } else {
-                    try {
-                        Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RunLater(), 4L);
-                    } catch (IllegalStateException ignored) {
 
+                    if (force) {
+                        new RunLater().run();
+                    } else {
+                        try {
+                            new RunLater().runTaskLater(PVPArena.instance, 2L);
+                        } catch (IllegalStateException ignored) {
+
+                        }
                     }
                 }
 
@@ -1356,7 +1330,7 @@ public void run() {
                 e.printStackTrace();
             }
         } else {
-            Team team = getStandardScoreboard().getEntryTeam(player.getName());
+            Team team = this.getStandardScoreboard().getEntryTeam(player.getName());
             if (team != null) {
                 team.removeEntry(player.getName());
                 if (soft) {
@@ -1364,19 +1338,19 @@ public void run() {
                 }
             }
             final ArenaPlayer ap = ArenaPlayer.parsePlayer(player.getName());
-            try {
-                Bukkit.getScheduler().runTaskLater(PVPArena.instance, () -> {
-                    if (ap.hasBackupScoreboard()) {
-                        player.setScoreboard(ap.getBackupScoreboard());
+            if (ap.hasBackupScoreboard()) {
+                try {
+                    Bukkit.getScheduler().runTaskLater(PVPArena.instance, () -> {
+                        Scoreboard backupScoreboard = ap.getBackupScoreboard();
                         if (ap.getBackupScoreboardTeam() != null) {
-                            ap.getBackupScoreboardTeam().addEntry(ap.getName());
+                            backupScoreboard.getTeam(ap.getBackupScoreboardTeam()).addEntry(ap.getName());
                         }
+                        player.setScoreboard(backupScoreboard);
                         ap.setBackupScoreboardTeam(null);
-                        ap.setBackupScoreboard(null);
-                    }
-                }, 5L);
-            } catch (IllegalPluginAccessException ignored) {
+                    }, 3L);
+                } catch (IllegalPluginAccessException ignored) {
 
+                }
             }
         }
     }
@@ -1526,7 +1500,7 @@ private void resetPlayer(final Player player, final String destination, final bo
         if (aPlayer.getState() != null) {
             aPlayer.getState().unload(soft);
         }
-        resetScoreboard(player, force, soft);
+        this.resetScoreboard(player, force, soft);
 
         //noinspection deprecation
         ArenaModuleManager.resetPlayer(this, player, soft, force);
@@ -1600,88 +1574,40 @@ public void run() {
     }
 
     public void setupScoreboard(final Player player) {
-        if (getArenaConfig().getBoolean(CFG.USES_SCOREBOARD)) {
-            final ArenaPlayer ap = ArenaPlayer.parsePlayer(player.getName());
-            getDebugger().i("ScoreBoards: Initiating scoreboard for player " + player.getName());
-            if (!ap.hasBackupScoreboard() && player.getScoreboard() != null) {
-                ap.setBackupScoreboard(player.getScoreboard());
-                ap.setBackupScoreboardTeam(player.getScoreboard().getEntryTeam(ap.getName()));
-            } else if (ap.hasBackupScoreboard()) {
-                getDebugger().i("ScoreBoards: has backup: " + ap.hasBackupScoreboard());
-                getDebugger().i("ScoreBoards: player.getScoreboard == null: " + (player.getScoreboard() == null));
-            } else {
-                getDebugger().i("ScoreBoards: has backup: false");
-                getDebugger().i("ScoreBoards: player.getScoreboard == null: " + (player.getScoreboard() == null));
-            }
+        final ArenaPlayer ap = ArenaPlayer.parsePlayer(player.getName());
 
-            // first, check if the scoreboard exists
-            class RunLater implements Runnable {
-                final Scoreboard board = getSpecialScoreboard();
-                @Override
-                public void run() {
+        this.getDebugger().i("ScoreBoards: Initiating scoreboard for player " + player.getName());
+        this.getDebugger().i("ScoreBoards: has backup: " + ap.hasBackupScoreboard());
+        this.getDebugger().i("ScoreBoards: player.getScoreboard == null: " + (player.getScoreboard() == null));
+        if (!ap.hasBackupScoreboard() && player.getScoreboard() != null) {
+            ap.setBackupScoreboard(player.getScoreboard());
+            ofNullable(player.getScoreboard().getEntryTeam(ap.getName())).ifPresent(team ->
+                    ap.setBackupScoreboardTeam(team.getName())
+            );
+        }
 
+        if (this.getArenaConfig().getBoolean(CFG.USES_SCOREBOARD)) {
+            Bukkit.getScheduler().runTaskLater(PVPArena.instance, () -> {
+                final Scoreboard board = this.getSpecialScoreboard();
 
-                    for (final ArenaTeam team : getTeams()) {
+                Optional optBoardTeam = ofNullable(ap.getArenaTeam()).map(team -> board.getTeam(team.getName()));
+                optBoardTeam.ifPresent(boardTeam -> boardTeam.addEntry(player.getName()));
 
-                        if (team == ArenaPlayer.parsePlayer(player.getName()).getArenaTeam()) {
-                            board.getTeam(team.getName()).addEntry(player.getName());
-                            updateScoreboard(player);
-                            return;
-                        }
-                    }
-                    try {
-                        ArenaTeam team = ap.getArenaTeam();
-                        if (team == null) {
-                            updateScoreboard(player);
-                            return;
-                        }
-                        scoreboard.registerNewTeam(team.getName());
-                        final Team bukkitTeam = scoreboard.getTeam(team.getName());
-                        bukkitTeam.setPrefix(team.getColor().toString());
-                        bukkitTeam.setSuffix(ChatColor.RESET.toString());
-                        bukkitTeam.setColor(team.getColor());
-                        bukkitTeam.addEntry(team.getName());
-                        bukkitTeam.setAllowFriendlyFire(getArenaConfig().getBoolean(CFG.PERMS_TEAMKILL));
-                        bukkitTeam.setCanSeeFriendlyInvisibles(!isFreeForAll());
-                    } catch (final Exception e) {
-                        e.printStackTrace();
-                    }
+                this.updateScoreboard(player);
 
-                    if (getArenaConfig().getBoolean(CFG.USES_SCOREBOARDROUNDDISPLAY)) {
-                        addCustomScoreBoardEntry(null, Language.parse(MSG.ROUNDS_DISPLAY,
-                                String.valueOf(getRound()),
-                                String.valueOf(getRoundCount())),  199);
-                        addCustomScoreBoardEntry(null, Language.parse(MSG.ROUNDS_DISPLAYSEPARATOR), 198);
-                    }
+                if (this.getArenaConfig().getBoolean(CFG.USES_SCOREBOARDROUNDDISPLAY)) {
+                    this.addCustomScoreBoardEntry(null, Language.parse(MSG.ROUNDS_DISPLAY,
+                            String.valueOf(this.getRound()),
+                            String.valueOf(this.getRoundCount())),  199);
+                    this.addCustomScoreBoardEntry(null, Language.parse(MSG.ROUNDS_DISPLAYSEPARATOR), 198);
                 }
-
-            }
-            Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RunLater(), 5L);
+            }, 1L);
         } else {
-            final Scoreboard board = getStandardScoreboard();
-            ArenaPlayer ap = ArenaPlayer.parsePlayer(player.getName());
-            final ArenaTeam team = ap.getArenaTeam();
-            if (!ap.hasBackupScoreboard() && player.getScoreboard() != null) {
-                ap.setBackupScoreboard(player.getScoreboard());
-                ap.setBackupScoreboardTeam(player.getScoreboard().getEntryTeam(ap.getName()));
-            }
+            final Scoreboard board = this.getStandardScoreboard();
 
             player.setScoreboard(board);
-            if (team == null) {
-                return;
-            }
-            for (final Team sTeam : board.getTeams()) {
-                if (sTeam.getName().equals(team.getName())) {
-                    sTeam.addEntry(player.getName());
-                    return;
-                }
-            }
-            final Team sTeam = board.registerNewTeam(team.getName());
-            sTeam.setPrefix(team.getColor().toString());
-            sTeam.setColor(team.getColor());
-            sTeam.setSuffix(ChatColor.RESET.toString());
-            sTeam.addEntry(player.getName());
-            sTeam.setCanSeeFriendlyInvisibles(!isFreeForAll());
+            Optional optBoardTeam = ofNullable(ap.getArenaTeam()).map(team -> board.getTeam(team.getName()));
+            optBoardTeam.ifPresent(boardTeam -> boardTeam.addEntry(player.getName()));
         }
     }
 
@@ -2391,34 +2317,31 @@ public void updateRounds() {
     }
 
     public void updateScoreboards() {
-        if (getArenaConfig().getBoolean(CFG.USES_SCOREBOARD)) {
-            Bukkit.getScheduler().runTaskLater(PVPArena.instance, new Runnable() {
-                @Override
-                public void run() {
-                    if (isFreeForAll()) {
-                        for (ArenaPlayer ap : getEveryone()) {
-                            int value = PACheck.handleGetLives(Arena.this, ap);
-                            if (value >= 0) {
-                                getSpecialScoreboard().getObjective("lives").getScore(ap.getName()).setScore(value);
-                            }
-                            Player player = ap.get();
-                            if (player != null && (player.getScoreboard() == null || !player.getScoreboard().equals(getSpecialScoreboard()))) {
-                                player.setScoreboard(getSpecialScoreboard());
-                            }
+        if (this.getArenaConfig().getBoolean(CFG.USES_SCOREBOARD)) {
+            Bukkit.getScheduler().runTaskLater(PVPArena.instance, () -> {
+                final Scoreboard currentScoreboard = this.getSpecialScoreboard();
+                if (this.isFreeForAll()) {
+                    for (ArenaPlayer ap : this.getEveryone()) {
+                        int value = PACheck.handleGetLives(this, ap);
+                        if (value >= 0) {
+                            currentScoreboard.getObjective("lives").getScore(ap.getName()).setScore(value);
                         }
-                    } else {
-                        for (ArenaTeam team : getTeams()) {
-                            for (ArenaPlayer ap : team.getTeamMembers()) {
-                                getSpecialScoreboard().getObjective("lives").getScore(team.getName()).setScore(
-                                        PACheck.handleGetLives(Arena.this, ap));
-                                break;
-                            }
+                        Player player = ap.get();
+                        if (player != null && !currentScoreboard.equals(player.getScoreboard())) {
+                            player.setScoreboard(currentScoreboard);
                         }
-                        for (ArenaPlayer ap : getEveryone()) {
-                            Player player = ap.get();
-                            if (player != null && (player.getScoreboard() == null || !player.getScoreboard().equals(getSpecialScoreboard()))) {
-                                player.setScoreboard(getSpecialScoreboard());
-                            }
+                    }
+                } else {
+                    for (ArenaTeam team : this.getTeams()) {
+                        ArenaPlayer randomTeamPlayer = team.getTeamMembers().iterator().next();
+                        currentScoreboard.getObjective("lives")
+                                .getScore(team.getName())
+                                .setScore(PACheck.handleGetLives(this, randomTeamPlayer));
+                    }
+                    for (ArenaPlayer ap : this.getEveryone()) {
+                        Player player = ap.get();
+                        if (player != null && !currentScoreboard.equals(player.getScoreboard())) {
+                            player.setScoreboard(currentScoreboard);
                         }
                     }
                 }
@@ -2427,59 +2350,38 @@ public void run() {
     }
 
     private void updateScoreboard(final Player player) {
-        if (getArenaConfig().getBoolean(CFG.USES_SCOREBOARD)) {
+        if (this.getArenaConfig().getBoolean(CFG.USES_SCOREBOARD)) {
+            Scoreboard currentScoreboard = this.getSpecialScoreboard();
             final ArenaPlayer ap = ArenaPlayer.parsePlayer(player.getName());
-            if (ap.getArenaTeam() == null) {
-                // a spectator, special case. Just update and do not add to the scores
-                if (player.getScoreboard() == null || !player.getScoreboard().equals(getSpecialScoreboard())) {
-                    player.setScoreboard(getSpecialScoreboard());
-                }
-                return;
-            }
-            if (isFreeForAll()) {
-                final Score score = getSpecialScoreboard().getObjective("lives").getScore(player.getName());
-                score.setScore(PACheck.handleGetLives(this, ArenaPlayer.parsePlayer(player.getName())));
-            } else {
-                getSpecialScoreboard().getObjective("lives").getScore(ap.getArenaTeam().getName()).setScore(PACheck.handleGetLives(this, ap));
-            }
-            if (player.getScoreboard() == null || !player.getScoreboard().equals(getSpecialScoreboard())) {
-                player.setScoreboard(getSpecialScoreboard());
+
+            // if player is a spectator, special case. Just update and do not add to the scores
+            if (ap.getArenaTeam() != null) {
+                currentScoreboard.getObjective("lives")
+                        .getScore(this.isFreeForAll() ? player.getName() : ap.getArenaTeam().getName())
+                        .setScore(PACheck.handleGetLives(this, ap));
             }
+
+            player.setScoreboard(currentScoreboard);
         }
     }
 
     public void updateScoreboardTeam(final Player player, final ArenaTeam oldTeam, final ArenaTeam newTeam) {
-        if (getArenaConfig().getBoolean(CFG.USES_SCOREBOARD)) {
-            final Scoreboard board = getSpecialScoreboard();
-            class RunLater implements Runnable {
-
-                @Override
-                public void run() {
+        if (this.getArenaConfig().getBoolean(CFG.USES_SCOREBOARD)) {
+            final Scoreboard board = this.getSpecialScoreboard();
 
-                    final ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(player.getName());
-                    if (aPlayer.getArenaTeam() != null) {
-                        board.getTeam(oldTeam.getName()).removeEntry(player.getName());
+            Bukkit.getScheduler().runTaskLater(PVPArena.instance, () -> {
+                board.getTeam(oldTeam.getName()).removeEntry(player.getName());
 
-                        for (final Team sTeam : board.getTeams()) {
-                            if (sTeam.getName().equals(newTeam.getName())) {
-                                sTeam.addEntry(player.getName());
-                                return;
-                            }
-                        }
-                        final Team sTeam = board.registerNewTeam(newTeam.getName());
-                        sTeam.setPrefix(newTeam.getColor().toString());
-                        sTeam.setSuffix(ChatColor.RESET.toString());
-                        sTeam.setColor(newTeam.getColor());
+                for (final Team sTeam : board.getTeams()) {
+                    if (sTeam.getName().equals(newTeam.getName())) {
                         sTeam.addEntry(player.getName());
-                        sTeam.setCanSeeFriendlyInvisibles(!isFreeForAll());
+                        return;
                     }
-                    updateScoreboard(player);
                 }
-
-            }
-            Bukkit.getScheduler().runTaskLater(PVPArena.instance, new RunLater(), 1L);
+                this.updateScoreboard(player);
+            }, 1L);
         } else {
-            Scoreboard board = getStandardScoreboard();
+            Scoreboard board = this.getStandardScoreboard();
             board.getTeam(oldTeam.getName()).removeEntry(player.getName());
 
             for (final Team sTeam : board.getTeams()) {
@@ -2488,12 +2390,6 @@ public void run() {
                     return;
                 }
             }
-            final Team sTeam = board.registerNewTeam(newTeam.getName());
-            sTeam.setPrefix(newTeam.getColor().toString());
-            sTeam.setSuffix(ChatColor.RESET.toString());
-            sTeam.setColor(newTeam.getColor());
-            sTeam.setCanSeeFriendlyInvisibles(!isFreeForAll());
-            sTeam.addEntry(player.getName());
         }
     }
 
diff --git a/src/net/slipcor/pvparena/arena/ArenaPlayer.java b/src/net/slipcor/pvparena/arena/ArenaPlayer.java
index f7f415db9..8bdf1f713 100644
--- a/src/net/slipcor/pvparena/arena/ArenaPlayer.java
+++ b/src/net/slipcor/pvparena/arena/ArenaPlayer.java
@@ -24,7 +24,6 @@
 import org.bukkit.permissions.PermissionAttachment;
 import org.bukkit.projectiles.ProjectileSource;
 import org.bukkit.scoreboard.Scoreboard;
-import org.bukkit.scoreboard.Team;
 
 import java.io.File;
 import java.util.*;
@@ -64,7 +63,7 @@ public class ArenaPlayer {
     private final Map statistics = new HashMap<>();
 
     private Scoreboard backupBoard;
-    private Team backupBoardTeam;
+    private String backupBoardTeam;
 
     /**
      * Status
@@ -516,7 +515,7 @@ public Scoreboard getBackupScoreboard() {
         return backupBoard;
     }
 
-    public Team getBackupScoreboardTeam() {
+    public String getBackupScoreboardTeam() {
         return backupBoardTeam;
     }
 
@@ -798,8 +797,8 @@ public void setBackupScoreboard(Scoreboard board) {
         backupBoard = board;
     }
 
-    public void setBackupScoreboardTeam(Team team) {
-        backupBoardTeam = team;
+    public void setBackupScoreboardTeam(String sbTeamName) {
+        this.backupBoardTeam = sbTeamName;
     }
 
     public void setMayDropInventory(boolean value) {

From 04626ae708b9cd861672933c47686bde30e1d407 Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Mon, 15 Jun 2020 21:41:08 +0200
Subject: [PATCH 19/43] v1.15 - init scoreboard after teleportation

---
 src/net/slipcor/pvparena/arena/Arena.java     | 52 +++++++++++--------
 .../slipcor/pvparena/commands/PAG_Join.java   |  4 +-
 .../pvparena/commands/PAG_Spectate.java       |  4 +-
 .../slipcor/pvparena/goals/GoalInfect.java    |  2 +-
 src/net/slipcor/pvparena/goals/GoalTank.java  |  2 +-
 .../pvparena/listeners/PlayerListener.java    |  2 +-
 .../pvparena/managers/SpawnManager.java       | 12 ++---
 .../pvparena/modules/BattlefieldJoin.java     |  2 +-
 .../pvparena/modules/StandardLounge.java      |  8 +--
 .../pvparena/modules/StandardSpectate.java    |  6 +--
 .../pvparena/runnables/RespawnRunnable.java   |  4 +-
 11 files changed, 52 insertions(+), 46 deletions(-)

diff --git a/src/net/slipcor/pvparena/arena/Arena.java b/src/net/slipcor/pvparena/arena/Arena.java
index f178a07ec..6fcac2249 100644
--- a/src/net/slipcor/pvparena/arena/Arena.java
+++ b/src/net/slipcor/pvparena/arena/Arena.java
@@ -35,7 +35,10 @@
 import org.bukkit.plugin.IllegalPluginAccessException;
 import org.bukkit.projectiles.ProjectileSource;
 import org.bukkit.scheduler.BukkitRunnable;
-import org.bukkit.scoreboard.*;
+import org.bukkit.scoreboard.DisplaySlot;
+import org.bukkit.scoreboard.Objective;
+import org.bukkit.scoreboard.Scoreboard;
+import org.bukkit.scoreboard.Team;
 import org.bukkit.util.Vector;
 
 import java.io.File;
@@ -1573,8 +1576,8 @@ public void run() {
         }
     }
 
-    public void setupScoreboard(final Player player) {
-        final ArenaPlayer ap = ArenaPlayer.parsePlayer(player.getName());
+    public void setupScoreboard(final ArenaPlayer ap) {
+        Player player = ap.get();
 
         this.getDebugger().i("ScoreBoards: Initiating scoreboard for player " + player.getName());
         this.getDebugger().i("ScoreBoards: has backup: " + ap.hasBackupScoreboard());
@@ -1930,8 +1933,10 @@ public String toString() {
         return name;
     }
 
-    public void tpPlayerToCoordName(Player player, String place) {
-        this.tpPlayerToCoordName(player, place, false);
+    public void tpPlayerToCoordName(ArenaPlayer player, String place) {
+        Location destination = this.prepareTeleportation(player, place);
+        this.teleportPlayer(place, player, destination);
+        this.execPostTeleportationFixes(player);
     }
 
     /**
@@ -1940,12 +1945,23 @@ public void tpPlayerToCoordName(Player player, String place) {
      * @param player the player to teleport
      * @param place  the coord string
      */
-    public void tpPlayerToCoordName(final Player player, final String place, final boolean runAsync) {
+    public void tpPlayerToCoordNameForJoin(final ArenaPlayer player, final String place, boolean async) {
+        Location destination = this.prepareTeleportation(player, place);
+        int delay = async ? 2 : 0;
+        Bukkit.getScheduler().runTaskLater(PVPArena.instance, () -> {
+            teleportPlayer(place, player, destination);
+            setupScoreboard(player);
+        }, delay);
+        this.execPostTeleportationFixes(player);
+    }
+
+    private Location prepareTeleportation(ArenaPlayer aPlayer, String place) {
+        Player player = aPlayer.get();
         getDebugger().i("teleporting " + player + " to coord " + place, player);
 
         if (player == null) {
             PVPArena.instance.getLogger().severe("Player null!");
-            return;
+            throw new RuntimeException("Player null!");
         }
 
         if (player.isInsideVehicle()) {
@@ -1954,8 +1970,6 @@ public void tpPlayerToCoordName(final Player player, final String place, final b
 
         ArenaModuleManager.tpPlayerToCoordName(this, player, place);
 
-        final ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(player.getName());
-
         if ("spectator".equals(place)) {
             if (getFighters().contains(aPlayer)) {
                 aPlayer.setStatus(Status.LOST);
@@ -1968,8 +1982,7 @@ public void tpPlayerToCoordName(final Player player, final String place, final b
             loc = aPlayer.getSavedLocation();
         }
         if (loc == null) {
-            new Exception("TP Spawn null: " + name + "->" + place).printStackTrace();
-            return;
+            throw new RuntimeException("TP Spawn null: " + name + "->" + place);
         }
 
         debug.i("raw location: " + loc.toString());
@@ -1982,16 +1995,13 @@ public void tpPlayerToCoordName(final Player player, final String place, final b
 
         aPlayer.setTeleporting(true);
         aPlayer.setTelePass(true);
-        final Location destination = loc.toLocation().add(offset.getX(), offset.getY(), offset.getZ());
-        if(runAsync) {
-            Bukkit.getScheduler().runTaskLater(PVPArena.instance, () -> teleportPlayer(place, aPlayer, destination), 2);
-        } else {
-            this.teleportPlayer(place, aPlayer, destination);
-        }
+        return loc.toLocation().add(offset.getX(), offset.getY(), offset.getZ());
+    }
 
+    private void execPostTeleportationFixes(ArenaPlayer aPlayer) {
         if (cfg.getBoolean(CFG.PLAYER_REMOVEARROWS)) {
             try {
-                new ArrowHack(player);
+                new ArrowHack(aPlayer.get());
             } catch (final Exception e) {
             }
         }
@@ -2016,8 +2026,8 @@ public void run() {
             Bukkit.getScheduler().runTaskLater(PVPArena.instance, new Runnable() {
                 @Override
                 public void run() {
-                    player.setAllowFlight(false);
-                    player.setFlying(false);
+                    aPlayer.get().setAllowFlight(false);
+                    aPlayer.get().setFlying(false);
                 }
             }, 5L);
         }
@@ -2142,7 +2152,7 @@ && getClass(autoClass) == null) {
 
         for (final PASpawn spawn : spawns) {
             if (--pos < 0) {
-                tpPlayerToCoordName(player, spawn.getName());
+                this.tpPlayerToCoordName(aPlayer, spawn.getName());
                 break;
             }
         }
diff --git a/src/net/slipcor/pvparena/commands/PAG_Join.java b/src/net/slipcor/pvparena/commands/PAG_Join.java
index 8b495367b..94f1c61dc 100644
--- a/src/net/slipcor/pvparena/commands/PAG_Join.java
+++ b/src/net/slipcor/pvparena/commands/PAG_Join.java
@@ -86,9 +86,7 @@ public void commit(final Arena arena, final CommandSender sender, final String[]
                 arena.getDebugger().i("Join_2", sender);
                 arena.msg(sender, Language.parse(arena, MSG.ERROR_ARENA_ALREADY_PART_OF, ArenaManager.getIndirectArenaName(arena)));
             } else {
-                if (PACheck.handleJoin(arena, sender, args)) {
-                    arena.setupScoreboard(aPlayer.get());
-                }
+                PACheck.handleJoin(arena, sender, args);
             }
         } else {
             final Arena pArena = aPlayer.getArena();
diff --git a/src/net/slipcor/pvparena/commands/PAG_Spectate.java b/src/net/slipcor/pvparena/commands/PAG_Spectate.java
index 40082880a..a46415d67 100644
--- a/src/net/slipcor/pvparena/commands/PAG_Spectate.java
+++ b/src/net/slipcor/pvparena/commands/PAG_Spectate.java
@@ -49,9 +49,7 @@ public void commit(final Arena arena, final CommandSender sender, final String[]
             return;
         }
 
-        if (PACheck.handleSpectate(arena, sender)) {
-            arena.setupScoreboard((Player) sender);
-        }
+        PACheck.handleSpectate(arena, sender);
     }
 
     @Override
diff --git a/src/net/slipcor/pvparena/goals/GoalInfect.java b/src/net/slipcor/pvparena/goals/GoalInfect.java
index 03b6b2058..1479994d4 100644
--- a/src/net/slipcor/pvparena/goals/GoalInfect.java
+++ b/src/net/slipcor/pvparena/goals/GoalInfect.java
@@ -701,7 +701,7 @@ public void parseStart() {
 
         for (final PASpawn spawn : spawns) {
             if (pos-- < 0) {
-                arena.tpPlayerToCoordName(infected.get(), spawn.getName());
+                this.arena.tpPlayerToCoordName(infected, spawn.getName());
                 break;
             }
         }
diff --git a/src/net/slipcor/pvparena/goals/GoalTank.java b/src/net/slipcor/pvparena/goals/GoalTank.java
index ec2b41483..9cc37e0ed 100644
--- a/src/net/slipcor/pvparena/goals/GoalTank.java
+++ b/src/net/slipcor/pvparena/goals/GoalTank.java
@@ -376,7 +376,7 @@ public void parseStart() {
 
         for (final PASpawn spawn : spawns) {
             if (--pos < 0) {
-                arena.tpPlayerToCoordName(tank.get(), spawn.getName());
+                this.arena.tpPlayerToCoordName(tank, spawn.getName());
                 break;
             }
         }
diff --git a/src/net/slipcor/pvparena/listeners/PlayerListener.java b/src/net/slipcor/pvparena/listeners/PlayerListener.java
index 6f38f42f0..c096b4e92 100644
--- a/src/net/slipcor/pvparena/listeners/PlayerListener.java
+++ b/src/net/slipcor/pvparena/listeners/PlayerListener.java
@@ -672,7 +672,7 @@ public void run() {
                 for (final PASpawn spawn : spawns) {
 
                     if (--pos < 0) {
-                        arena.tpPlayerToCoordName(player, spawn.getName());
+                        arena.tpPlayerToCoordName(aPlayer, spawn.getName());
                         break;
                     }
                 }
diff --git a/src/net/slipcor/pvparena/managers/SpawnManager.java b/src/net/slipcor/pvparena/managers/SpawnManager.java
index a0ecc29b2..528cd1f09 100644
--- a/src/net/slipcor/pvparena/managers/SpawnManager.java
+++ b/src/net/slipcor/pvparena/managers/SpawnManager.java
@@ -137,13 +137,13 @@ public void run() {
                             int pos = new Random().nextInt(spawns.size());
                             for (final PASpawn spawn : spawns) {
                                 if (--pos < 0) {
-                                    arena.tpPlayerToCoordName(ap.get(), spawn.getName());
+                                    arena.tpPlayerToCoordName(ap, spawn.getName());
                                     break;
                                 }
                             }
 
                         } else {
-                            arena.tpPlayerToCoordName(ap.get(), locations[pos++ % locations.length].getName());
+                            arena.tpPlayerToCoordName(ap, locations[pos++ % locations.length].getName());
                         }
                         ap.setStatus(Status.FIGHT);
                         teamMembers.remove(ap);
@@ -210,14 +210,14 @@ public void run() {
                         int pos = new Random().nextInt(spawns.size());
                         for (final PASpawn spawn : spawns) {
                             if (--pos < 0) {
-                                arena.tpPlayerToCoordName(ap.get(), spawn.getName());
+                                arena.tpPlayerToCoordName(ap, spawn.getName());
                                 break;
                             }
                         }
 
                     } else {
                         for (final PASpawn s : spawns) {
-                            arena.tpPlayerToCoordName(ap.get(), s.getName());
+                            arena.tpPlayerToCoordName(ap, s.getName());
                             if (spawns.size() > 1) {
                                 spawns.remove(s);
                             }
@@ -307,7 +307,7 @@ public void run() {
                     if (spawnName == null) {
                         PVPArena.instance.getLogger().warning("Element #" + pos + " is null: [" + StringParser.joinArray(iteratings, ",") + ']');
                     }
-                    arena.tpPlayerToCoordName(ap.get(), spawnName);
+                    arena.tpPlayerToCoordName(ap, spawnName);
                     set.remove(ap);
                     return;
                 }
@@ -518,7 +518,7 @@ public void run() {
 
                 aPlayer.setStatus(Status.FIGHT);
 
-                arena.tpPlayerToCoordName(aPlayer.get(), "old");
+                arena.tpPlayerToCoordName(aPlayer, "old");
                 Bukkit.getScheduler().runTaskLater(PVPArena.instance, new Runnable() {
                             @Override
                             public void run() {
diff --git a/src/net/slipcor/pvparena/modules/BattlefieldJoin.java b/src/net/slipcor/pvparena/modules/BattlefieldJoin.java
index 4a9b8bf1d..dc342c798 100644
--- a/src/net/slipcor/pvparena/modules/BattlefieldJoin.java
+++ b/src/net/slipcor/pvparena/modules/BattlefieldJoin.java
@@ -113,7 +113,7 @@ public void commitJoin(final Player sender, final ArenaTeam team) {
 
         for (final PASpawn spawn : spawns) {
             if (--pos < 0) {
-                arena.tpPlayerToCoordName(player.get(), spawn.getName(), true);
+                this.arena.tpPlayerToCoordNameForJoin(player, spawn.getName(), true);
                 break;
             }
         }
diff --git a/src/net/slipcor/pvparena/modules/StandardLounge.java b/src/net/slipcor/pvparena/modules/StandardLounge.java
index 2dcf98c11..f6d77e668 100644
--- a/src/net/slipcor/pvparena/modules/StandardLounge.java
+++ b/src/net/slipcor/pvparena/modules/StandardLounge.java
@@ -175,13 +175,13 @@ public void commitJoin(final Player sender, final ArenaTeam team) {
         player.setLocation(new PALocation(player.get().getLocation()));
 
         // ArenaPlayer.prepareInventory(arena, ap.get());
-        player.setArena(arena);
+        player.setArena(this.arena);
         team.add(player);
 
-        if (arena.isFreeForAll()) {
-            arena.tpPlayerToCoordName(player.get(), "lounge", true);
+        if (this.arena.isFreeForAll()) {
+            this.arena.tpPlayerToCoordNameForJoin(player, "lounge", true);
         } else {
-            arena.tpPlayerToCoordName(player.get(), team.getName() + "lounge", true);
+            this.arena.tpPlayerToCoordNameForJoin(player, team.getName() + "lounge", true);
         }
 
         player.setStatus(Status.LOUNGE);
diff --git a/src/net/slipcor/pvparena/modules/StandardSpectate.java b/src/net/slipcor/pvparena/modules/StandardSpectate.java
index f7f03ffe9..746e3a73e 100644
--- a/src/net/slipcor/pvparena/modules/StandardSpectate.java
+++ b/src/net/slipcor/pvparena/modules/StandardSpectate.java
@@ -68,11 +68,11 @@ public void commitSpectate(final Player player) {
         final ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(player.getName());
         aPlayer.setLocation(new PALocation(player.getLocation()));
 
-        aPlayer.setArena(arena);
+        aPlayer.setArena(this.arena);
         aPlayer.setStatus(Status.WATCH);
 
-        arena.tpPlayerToCoordName(player, "spectator", true);
-        arena.msg(player, Language.parse(arena, MSG.NOTICE_WELCOME_SPECTATOR));
+        this.arena.tpPlayerToCoordNameForJoin(aPlayer, "spectator", true);
+        this.arena.msg(player, Language.parse(this.arena, MSG.NOTICE_WELCOME_SPECTATOR));
 
         if (aPlayer.getState() == null) {
 
diff --git a/src/net/slipcor/pvparena/runnables/RespawnRunnable.java b/src/net/slipcor/pvparena/runnables/RespawnRunnable.java
index 64d01b23e..5c4fa4f19 100644
--- a/src/net/slipcor/pvparena/runnables/RespawnRunnable.java
+++ b/src/net/slipcor/pvparena/runnables/RespawnRunnable.java
@@ -55,12 +55,12 @@ public void run() {
 
             for (final PASpawn spawn : spawns) {
                 if (--pos < 0) {
-                    arena.tpPlayerToCoordName(player.get(), spawn.getName());
+                    this.arena.tpPlayerToCoordName(player, spawn.getName());
                     break;
                 }
             }
         } else {
-            arena.tpPlayerToCoordName(player.get(), coordName);
+            this.arena.tpPlayerToCoordName(player, coordName);
         }
     }
 

From 27901f2d7fe077ae92214900521cabba95e38d95 Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Mon, 22 Jun 2020 14:07:24 +0200
Subject: [PATCH 20/43] v1.15 - prettify empty flag error - issue #47

---
 src/net/slipcor/pvparena/goals/GoalFlags.java | 20 ++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/src/net/slipcor/pvparena/goals/GoalFlags.java b/src/net/slipcor/pvparena/goals/GoalFlags.java
index 764dc332d..1e5f0281b 100644
--- a/src/net/slipcor/pvparena/goals/GoalFlags.java
+++ b/src/net/slipcor/pvparena/goals/GoalFlags.java
@@ -20,7 +20,9 @@
 import net.slipcor.pvparena.managers.StatisticsManager.type;
 import net.slipcor.pvparena.managers.TeamManager;
 import net.slipcor.pvparena.runnables.EndRunnable;
-import org.bukkit.*;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
 import org.bukkit.block.Block;
 import org.bukkit.block.data.BlockData;
 import org.bukkit.block.data.Directional;
@@ -416,8 +418,7 @@ public PACheck checkJoin(final CommandSender sender, final PACheck res, final St
     @Override
     public PACheck checkSetBlock(final PACheck res, final Player player, final Block block) {
 
-        if (res.getPriority() > PRIORITY
-                || !PAA_Region.activeSelections.containsKey(player.getName())) {
+        if (res.getPriority() > PRIORITY || !PAA_Region.activeSelections.containsKey(player.getName())) {
             return res;
         }
 
@@ -426,8 +427,7 @@ public PACheck checkSetBlock(final PACheck res, final Player player, final Block
             return res;
         }
 
-        if (!PVPArena.hasAdminPerms(player)
-                && !PVPArena.hasCreatePerms(player, this.arena)) {
+        if (!PVPArena.hasAdminPerms(player) && !PVPArena.hasCreatePerms(player, this.arena)) {
             return res;
         }
         res.setPriority(this, PRIORITY); // success :)
@@ -642,10 +642,12 @@ public boolean commitSetFlag(final Player player, final Block block) {
         // command : /pa redflag1
         // location: red1flag:
 
-        SpawnManager.setBlock(this.arena, new PABlockLocation(block.getLocation()),
-                this.flagName);
-
-        this.arena.msg(player, Language.parse(this.arena, MSG.GOAL_FLAGS_SET, this.flagName));
+        if(this.flagName == null || this.flagName.isEmpty()) {
+            this.arena.msg(player, Language.parse(this.arena, MSG.ERROR_ERROR, "Flag you are trying to set has no name."));
+        } else {
+            SpawnManager.setBlock(this.arena, new PABlockLocation(block.getLocation()), this.flagName);
+            this.arena.msg(player, Language.parse(this.arena, MSG.GOAL_FLAGS_SET, this.flagName));
+        }
 
         PAA_Region.activeSelections.remove(player.getName());
         this.flagName = "";

From 2d107c926effd6766b06ea14ba497d9acf5bb408 Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Tue, 23 Jun 2020 16:41:48 +0200
Subject: [PATCH 21/43] v1.15 - refactor arena stats system - fix issue #46

---
 src/net/slipcor/pvparena/PVPArena.java        |   1 -
 .../slipcor/pvparena/arena/ArenaPlayer.java   | 121 ++++----
 .../slipcor/pvparena/classes/PAStatMap.java   |  14 +-
 .../slipcor/pvparena/commands/PAI_Stats.java  |  23 +-
 src/net/slipcor/pvparena/core/Language.java   |  18 +-
 src/net/slipcor/pvparena/goals/GoalFlags.java |   4 +-
 .../slipcor/pvparena/goals/GoalSabotage.java  |   4 +-
 .../pvparena/managers/StatisticsManager.java  | 266 ++++++------------
 8 files changed, 165 insertions(+), 286 deletions(-)

diff --git a/src/net/slipcor/pvparena/PVPArena.java b/src/net/slipcor/pvparena/PVPArena.java
index f97708276..7817e8f47 100644
--- a/src/net/slipcor/pvparena/PVPArena.java
+++ b/src/net/slipcor/pvparena/PVPArena.java
@@ -479,7 +479,6 @@ public void onEnable() {
         Help.init(getConfig().getString("language", "en"));
 
         StatisticsManager.initialize();
-        ArenaPlayer.initiate();
 
         getServer().getPluginManager()
                 .registerEvents(new BlockListener(), this);
diff --git a/src/net/slipcor/pvparena/arena/ArenaPlayer.java b/src/net/slipcor/pvparena/arena/ArenaPlayer.java
index 8bdf1f713..056ad46aa 100644
--- a/src/net/slipcor/pvparena/arena/ArenaPlayer.java
+++ b/src/net/slipcor/pvparena/arena/ArenaPlayer.java
@@ -13,7 +13,7 @@
 import net.slipcor.pvparena.managers.ArenaManager;
 import net.slipcor.pvparena.managers.InventoryManager;
 import net.slipcor.pvparena.managers.SpawnManager;
-import net.slipcor.pvparena.managers.StatisticsManager.type;
+import net.slipcor.pvparena.managers.StatisticsManager.Type;
 import org.bukkit.*;
 import org.bukkit.configuration.file.YamlConfiguration;
 import org.bukkit.entity.*;
@@ -109,28 +109,11 @@ public static boolean has(int value, PlayerPrevention s) {
     private final PABlockLocation[] selection = new PABlockLocation[2];
 
     private ArenaPlayer(final String playerName) {
-        name = playerName;
-
-        totalPlayers.put(name, this);
-    }
-
-    private ArenaPlayer(final Player player, final Arena arena) {
-        name = player.getName();
-        this.arena = arena;
-
-        totalPlayers.put(name, this);
-    }
-
-    public static int countPlayers() {
-        return totalPlayers.size();
+        this.name = playerName;
     }
 
     public static Set getAllArenaPlayers() {
-        final Set players = new HashSet<>();
-        for (final ArenaPlayer ap : totalPlayers.values()) {
-            players.add(ap);
-        }
-        return players;
+        return new HashSet<>(totalPlayers.values());
     }
 
     public boolean getFlyState() {
@@ -214,49 +197,39 @@ public static void givePlayerFightItems(final Arena arena, final Player player)
         }
     }
 
-    public static void initiate() {
-        debug.i("creating offline arena players");
-
-        if (!PVPArena.instance.getConfig().getBoolean("stats")) {
-            return;
-        }
-
-        final YamlConfiguration cfg = new YamlConfiguration();
-        try {
-            cfg.load(PVPArena.instance.getDataFolder() + "/players.yml");
-
-            final Set arenas = cfg.getKeys(false);
-
-            for (final String arenaname : arenas) {
-
-                final Set players = cfg.getConfigurationSection(arenaname).getKeys(false);
-                for (final String player : players) {
-                    totalPlayers.put(player, ArenaPlayer.parsePlayer(player));
-                }
+    /**
+     * get an ArenaPlayer from a player name
+     *
+     * @param name the playername to use
+     * @return an ArenaPlayer instance belonging to that player
+     */
+    public static ArenaPlayer parsePlayer(final String name) {
+        synchronized (ArenaPlayer.class) {
+            Player player = Bukkit.getPlayerExact(name);
 
+            // Offline player or NPC
+            if (player == null) {
+                return new ArenaPlayer(name);
             }
 
-        } catch (final Exception e) {
-            e.printStackTrace();
+            if(!totalPlayers.containsKey(name)) {
+                ArenaPlayer ap = new ArenaPlayer(player.getName());
+                totalPlayers.putIfAbsent(name, ap);
+            }
+            return totalPlayers.get(name);
         }
     }
 
     /**
-     * get an ArenaPlayer from a player name
+     * add an ArenaPlayer (used to load statistics)
      *
      * @param name the playername to use
      * @return an ArenaPlayer instance belonging to that player
      */
-    public static ArenaPlayer parsePlayer(final String name) {
+    public static ArenaPlayer addPlayer(final String name) {
         synchronized (ArenaPlayer.class) {
-            if (totalPlayers.get(name) == null) {
-                if (Bukkit.getPlayerExact(name) == null) {
-                    totalPlayers.put(name, new ArenaPlayer(name));
-                } else {
-                    totalPlayers.put(name,
-                            new ArenaPlayer(Bukkit.getPlayerExact(name), null));
-                }
-            }
+            ArenaPlayer aPlayer = new ArenaPlayer(name);
+            totalPlayers.putIfAbsent(name, aPlayer);
             return totalPlayers.get(name);
         }
     }
@@ -362,18 +335,18 @@ public void run() {
     }
 
     public void addDeath() {
-        getStatistics(arena).incStat(type.DEATHS);
+        getStatistics(arena).incStat(Type.DEATHS);
     }
 
     public void addKill() {
-        getStatistics(arena).incStat(type.KILLS);
+        getStatistics(arena).incStat(Type.KILLS);
     }
 
     public void addLosses() {
-        getStatistics(arena).incStat(type.LOSSES);
+        getStatistics(arena).incStat(Type.LOSSES);
     }
 
-    public void addStatistic(final String arenaName, final type type,
+    public void addStatistic(final String arenaName, final Type type,
                              final int value) {
         if (!statistics.containsKey(arenaName)) {
             statistics.put(arenaName, new PAStatMap());
@@ -383,7 +356,7 @@ public void addStatistic(final String arenaName, final type type,
     }
 
     public void addWins() {
-        getStatistics(arena).incStat(type.WINS);
+        getStatistics(arena).incStat(Type.WINS);
     }
 
     private void clearDump() {
@@ -588,7 +561,7 @@ public Set getTempPermissions() {
         return tempPermissions;
     }
 
-    public int getTotalStatistics(final type statType) {
+    public int getTotalStatistics(final Type statType) {
         int sum = 0;
 
         for (final PAStatMap stat : statistics.values()) {
@@ -676,34 +649,34 @@ public void reset() {
                 if (arena != null) {
                     final String arenaName = arena.getName();
                     cfg.set(arenaName + '.' + name + ".losses", getStatistics()
-                            .getStat(type.LOSSES)
-                            + getTotalStatistics(type.LOSSES));
+                            .getStat(Type.LOSSES)
+                            + getTotalStatistics(Type.LOSSES));
                     cfg.set(arenaName + '.' + name + ".wins",
                             getStatistics()
-                                    .getStat(type.WINS)
-                                    + getTotalStatistics(type.WINS));
+                                    .getStat(Type.WINS)
+                                    + getTotalStatistics(Type.WINS));
                     cfg.set(arenaName + '.' + name + ".kills",
                             getStatistics().getStat(
-                                    type.KILLS)
-                                    + getTotalStatistics(type.KILLS));
+                                    Type.KILLS)
+                                    + getTotalStatistics(Type.KILLS));
                     cfg.set(arenaName + '.' + name + ".deaths", getStatistics()
-                            .getStat(type.DEATHS)
-                            + getTotalStatistics(type.DEATHS));
+                            .getStat(Type.DEATHS)
+                            + getTotalStatistics(Type.DEATHS));
                     cfg.set(arenaName + '.' + name + ".damage", getStatistics()
-                            .getStat(type.DAMAGE)
-                            + getTotalStatistics(type.DAMAGE));
+                            .getStat(Type.DAMAGE)
+                            + getTotalStatistics(Type.DAMAGE));
                     cfg.set(arenaName + '.' + name + ".maxdamage",
                             getStatistics().getStat(
-                                    type.MAXDAMAGE)
-                                    + getTotalStatistics(type.MAXDAMAGE));
+                                    Type.MAXDAMAGE)
+                                    + getTotalStatistics(Type.MAXDAMAGE));
                     cfg.set(arenaName + '.' + name + ".damagetake",
                             getStatistics().getStat(
-                                    type.DAMAGETAKE)
-                                    + getTotalStatistics(type.DAMAGETAKE));
+                                    Type.DAMAGETAKE)
+                                    + getTotalStatistics(Type.DAMAGETAKE));
                     cfg.set(arenaName + '.' + name + ".maxdamagetake",
                             getStatistics().getStat(
-                                    type.MAXDAMAGETAKE)
-                                    + getTotalStatistics(type.MAXDAMAGETAKE));
+                                    Type.MAXDAMAGETAKE)
+                                    + getTotalStatistics(Type.MAXDAMAGETAKE));
                 }
 
                 cfg.save(file);
@@ -833,7 +806,7 @@ public void setSelection(final Location loc, final boolean second) {
         }
     }
 
-    public void setStatistic(final String arenaName, final type type,
+    public void setStatistic(final String arenaName, final Type type,
                              final int value) {
         if (!statistics.containsKey(arenaName)) {
             statistics.put(arenaName, new PAStatMap());
diff --git a/src/net/slipcor/pvparena/classes/PAStatMap.java b/src/net/slipcor/pvparena/classes/PAStatMap.java
index 81a8b9827..070af56ae 100644
--- a/src/net/slipcor/pvparena/classes/PAStatMap.java
+++ b/src/net/slipcor/pvparena/classes/PAStatMap.java
@@ -15,29 +15,29 @@
  */
 
 public class PAStatMap {
-    private final Map map = new HashMap<>();
+    private final Map map = new HashMap<>();
 
-    public void decStat(final StatisticsManager.type type) {
+    public void decStat(final StatisticsManager.Type type) {
         decStat(type, 1);
     }
 
-    public void decStat(final StatisticsManager.type type, final int value) {
+    public void decStat(final StatisticsManager.Type type, final int value) {
         map.put(type, getStat(type) - value);
     }
 
-    public int getStat(final StatisticsManager.type type) {
+    public int getStat(final StatisticsManager.Type type) {
         return map.containsKey(type) ? map.get(type) : 0;
     }
 
-    public void incStat(final StatisticsManager.type type) {
+    public void incStat(final StatisticsManager.Type type) {
         incStat(type, 1);
     }
 
-    public void incStat(final StatisticsManager.type type, final int value) {
+    public void incStat(final StatisticsManager.Type type, final int value) {
         map.put(type, getStat(type) + value);
     }
 
-    public void setStat(final StatisticsManager.type type, final int value) {
+    public void setStat(final StatisticsManager.Type type, final int value) {
         map.put(type, value);
     }
 }
diff --git a/src/net/slipcor/pvparena/commands/PAI_Stats.java b/src/net/slipcor/pvparena/commands/PAI_Stats.java
index f2e1eab77..862e25942 100644
--- a/src/net/slipcor/pvparena/commands/PAI_Stats.java
+++ b/src/net/slipcor/pvparena/commands/PAI_Stats.java
@@ -7,11 +7,13 @@
 import net.slipcor.pvparena.core.Language.MSG;
 import net.slipcor.pvparena.core.StringParser;
 import net.slipcor.pvparena.managers.StatisticsManager;
-import net.slipcor.pvparena.managers.StatisticsManager.type;
+import net.slipcor.pvparena.managers.StatisticsManager.Type;
 import org.bukkit.command.CommandSender;
 
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
+import java.util.Map;
 
 /**
  * 
PVP Arena STATS Command class
@@ -38,23 +40,21 @@ public void commit(final Arena arena, final CommandSender sender, final String[] return; } - final type statType = type.getByString(args[0]); + final Type statType = Type.getByString(args[0]); if (statType == null) { - Arena.pmsg(sender, Language.parse(arena, MSG.STATS_TYPENOTFOUND, StringParser.joinArray(type.values(), ", ").replace("NULL, ", ""))); + Arena.pmsg(sender, Language.parse(arena, MSG.STATS_TYPENOTFOUND, StringParser.joinArray(Type.values(), ", ").replace("NULL, ", ""))); return; } - final String[] values = StatisticsManager.read(StatisticsManager.getStats(arena, statType), statType, arena == null); - final String[] names = StatisticsManager.read(StatisticsManager.getStats(arena, statType), type.NULL, arena == null); + Map playersStats = StatisticsManager.getStats(arena, statType); int max = 10; if (args.length > 1) { try { max = Integer.parseInt(args[1]); - } catch (final Exception e) { - max = 10; + } catch (NumberFormatException ignored) { } } @@ -65,9 +65,10 @@ public void commit(final Arena arena, final CommandSender sender, final String[] Arena.pmsg(sender, s1); - for (int i = 0; i < max && i < names.length && i < values.length; i++) { - Arena.pmsg(sender, names[i] + ": " + values[i]); - } + playersStats.entrySet().stream() + .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) + .limit(max) + .forEach(stat -> Arena.pmsg(sender, stat.getKey() + " : " + stat.getValue())); } @Override @@ -93,7 +94,7 @@ public List getShort() { @Override public CommandTree getSubs(final Arena arena) { final CommandTree result = new CommandTree<>(null); - for (final type val : type.values()) { + for (final Type val : Type.values()) { result.define(new String[]{val.name()}); } return result; diff --git a/src/net/slipcor/pvparena/core/Language.java b/src/net/slipcor/pvparena/core/Language.java index ce7753037..ab49dedc3 100644 --- a/src/net/slipcor/pvparena/core/Language.java +++ b/src/net/slipcor/pvparena/core/Language.java @@ -426,15 +426,15 @@ public enum MSG { STATS_HEAD("nulang.stats.head", "Statistics TOP %1% (%2%)"), STATS_TYPENOTFOUND("nulang.stats.typenotfound", "Statistics type not found! Valid values: &e%1%&r"), - STATTYPE_DAMAGE("nulang.stattype.DAMAGE", StatisticsManager.type.DAMAGE.getName()), - STATTYPE_DAMAGETAKE("nulang.stattype.DAMAGETAKE", StatisticsManager.type.DAMAGETAKE.getName()), - STATTYPE_DEATHS("nulang.stattype.DEATHS", StatisticsManager.type.DEATHS.getName()), - STATTYPE_KILLS("nulang.stattype.KILLS", StatisticsManager.type.KILLS.getName()), - STATTYPE_LOSSES("nulang.stattype.LOSSES", StatisticsManager.type.LOSSES.getName()), - STATTYPE_MAXDAMAGE("nulang.stattype.MAXDAMAGE", StatisticsManager.type.MAXDAMAGE.getName()), - STATTYPE_MAXDAMAGETAKE("nulang.stattype.MAXDAMAGETAKE", StatisticsManager.type.MAXDAMAGETAKE.getName()), - STATTYPE_NULL("nulang.stattype.NULL", StatisticsManager.type.NULL.getName()), - STATTYPE_WINS("nulang.stattype.WINS", StatisticsManager.type.WINS.getName()), + STATTYPE_DAMAGE("nulang.stattype.DAMAGE", StatisticsManager.Type.DAMAGE.getName()), + STATTYPE_DAMAGETAKE("nulang.stattype.DAMAGETAKE", StatisticsManager.Type.DAMAGETAKE.getName()), + STATTYPE_DEATHS("nulang.stattype.DEATHS", StatisticsManager.Type.DEATHS.getName()), + STATTYPE_KILLS("nulang.stattype.KILLS", StatisticsManager.Type.KILLS.getName()), + STATTYPE_LOSSES("nulang.stattype.LOSSES", StatisticsManager.Type.LOSSES.getName()), + STATTYPE_MAXDAMAGE("nulang.stattype.MAXDAMAGE", StatisticsManager.Type.MAXDAMAGE.getName()), + STATTYPE_MAXDAMAGETAKE("nulang.stattype.MAXDAMAGETAKE", StatisticsManager.Type.MAXDAMAGETAKE.getName()), + STATTYPE_NULL("nulang.stattype.NULL", StatisticsManager.Type.NULL.getName()), + STATTYPE_WINS("nulang.stattype.WINS", StatisticsManager.Type.WINS.getName()), TEAM_HAS_WON("nulang.team.haswon", "Team %1%&r are the Champions!"), TEAM_READY("nulang.team.ready", "Team %1%&r is ready!"), diff --git a/src/net/slipcor/pvparena/goals/GoalFlags.java b/src/net/slipcor/pvparena/goals/GoalFlags.java index 1e5f0281b..77f6fb580 100644 --- a/src/net/slipcor/pvparena/goals/GoalFlags.java +++ b/src/net/slipcor/pvparena/goals/GoalFlags.java @@ -17,7 +17,7 @@ import net.slipcor.pvparena.loadables.ArenaGoal; import net.slipcor.pvparena.loadables.ArenaModuleManager; import net.slipcor.pvparena.managers.SpawnManager; -import net.slipcor.pvparena.managers.StatisticsManager.type; +import net.slipcor.pvparena.managers.StatisticsManager.Type; import net.slipcor.pvparena.managers.TeamManager; import net.slipcor.pvparena.runnables.EndRunnable; import org.bukkit.Bukkit; @@ -451,7 +451,7 @@ private void commit(final Arena arena, final String sTeam, final boolean win) { } for (final ArenaPlayer ap : team.getTeamMembers()) { - ap.addStatistic(arena.getName(), type.LOSSES, 1); + ap.addStatistic(arena.getName(), Type.LOSSES, 1); /* arena.tpPlayerToCoordName(ap.get(), "spectator"); ap.setTelePass(false);*/ diff --git a/src/net/slipcor/pvparena/goals/GoalSabotage.java b/src/net/slipcor/pvparena/goals/GoalSabotage.java index e4a5b5797..e9e891f42 100644 --- a/src/net/slipcor/pvparena/goals/GoalSabotage.java +++ b/src/net/slipcor/pvparena/goals/GoalSabotage.java @@ -17,7 +17,7 @@ import net.slipcor.pvparena.loadables.ArenaGoal; import net.slipcor.pvparena.loadables.ArenaModuleManager; import net.slipcor.pvparena.managers.SpawnManager; -import net.slipcor.pvparena.managers.StatisticsManager.type; +import net.slipcor.pvparena.managers.StatisticsManager.Type; import net.slipcor.pvparena.runnables.EndRunnable; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -254,7 +254,7 @@ private void commit(final Arena arena, final String sTeam) { } for (final ArenaPlayer ap : team.getTeamMembers()) { - ap.addStatistic(arena.getName(), type.LOSSES, 1); + ap.addStatistic(arena.getName(), Type.LOSSES, 1); /* arena.tpPlayerToCoordName(ap.get(), "spectator"); ap.setTelePass(false);*/ diff --git a/src/net/slipcor/pvparena/managers/StatisticsManager.java b/src/net/slipcor/pvparena/managers/StatisticsManager.java index bd26205db..60cfdd1be 100644 --- a/src/net/slipcor/pvparena/managers/StatisticsManager.java +++ b/src/net/slipcor/pvparena/managers/StatisticsManager.java @@ -11,14 +11,16 @@ import net.slipcor.pvparena.events.PAKillEvent; import org.bukkit.Bukkit; import org.bukkit.ChatColor; -import org.bukkit.OfflinePlayer; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import java.io.File; import java.io.IOException; -import java.util.UUID; +import java.util.Map; +import java.util.stream.Collectors; + +import static java.util.Comparator.reverseOrder; /** *
Statistics Manager class
@@ -31,12 +33,12 @@ public final class StatisticsManager { private static final Debug DEBUG = new Debug(28); - private static File players; + private static File playersFile; private static YamlConfiguration config; private StatisticsManager() {} - public enum type { + public enum Type { WINS("matches won", "Wins"), LOSSES("matches lost", "Losses"), KILLS("kills", "Kills"), @@ -50,9 +52,9 @@ public enum type { private final String fullName; private final String niceDesc; - type(final String name, final String desc) { - fullName = name; - niceDesc = desc; + Type(final String name, final String desc) { + this.fullName = name; + this.niceDesc = desc; } /** @@ -61,8 +63,8 @@ public enum type { * @param tType the type * @return the next type */ - public static type next(final type tType) { - final type[] types = type.values(); + public static Type next(final Type tType) { + final Type[] types = Type.values(); final int ord = tType.ordinal(); if (ord >= types.length - 2) { return types[0]; @@ -76,8 +78,8 @@ public static type next(final type tType) { * @param tType the type * @return the previous type */ - public static type last(final type tType) { - final type[] types = type.values(); + public static Type last(final Type tType) { + final Type[] types = Type.values(); final int ord = tType.ordinal(); if (ord <= 0) { return types[types.length - 2]; @@ -89,7 +91,7 @@ public static type last(final type tType) { * return the full stat name */ public String getName() { - return fullName; + return this.fullName; } /** @@ -98,8 +100,8 @@ public String getName() { * @param string the name to find * @return the type if found, null otherwise */ - public static type getByString(final String string) { - for (final type t : type.values()) { + public static Type getByString(final String string) { + for (final Type t : Type.values()) { if (t.name().equalsIgnoreCase(string)) { return t; } @@ -108,7 +110,7 @@ public static type getByString(final String string) { } public String getNiceName() { - return niceDesc; + return this.niceDesc; } } @@ -131,87 +133,63 @@ public static void damage(final Arena arena, final Entity entity, final Player d if (arena.hasPlayer(attacker)) { arena.getDebugger().i("attacker is in the arena, adding damage!", defender); final ArenaPlayer apAttacker = ArenaPlayer.parsePlayer(attacker.getName()); - final int maxdamage = apAttacker.getStatistics(arena).getStat(type.MAXDAMAGE); - apAttacker.getStatistics(arena).incStat(type.DAMAGE, (int) dmg); + final int maxdamage = apAttacker.getStatistics(arena).getStat(Type.MAXDAMAGE); + apAttacker.getStatistics(arena).incStat(Type.DAMAGE, (int) dmg); if (dmg > maxdamage) { - apAttacker.getStatistics(arena).setStat(type.MAXDAMAGE, (int) dmg); + apAttacker.getStatistics(arena).setStat(Type.MAXDAMAGE, (int) dmg); } } } final ArenaPlayer apDefender = ArenaPlayer.parsePlayer(defender.getName()); - final int maxdamage = apDefender.getStatistics(arena).getStat(type.MAXDAMAGETAKE); - apDefender.getStatistics(arena).incStat(type.DAMAGETAKE, (int) dmg); + final int maxdamage = apDefender.getStatistics(arena).getStat(Type.MAXDAMAGETAKE); + apDefender.getStatistics(arena).incStat(Type.DAMAGETAKE, (int) dmg); if (dmg > maxdamage) { - apDefender.getStatistics(arena).setStat(type.MAXDAMAGETAKE, (int) dmg); + apDefender.getStatistics(arena).setStat(Type.MAXDAMAGETAKE, (int) dmg); } } /** - * decide if a pair has to be sorted + * get an array of stats for arena boards and with a given stats type * - * @param aps the ArenaPlayer array - * @param pos the position to check - * @param sortBy the type to sort by - * @param desc descending order? - * @param global should we read global stats instead of arena stats? - * @return true if pair has to be sorted, false otherwise + * @param arena the arena to check + * @param statType the type to sort + * @return an array of stats values */ - private static boolean decide(final ArenaPlayer[] aps, final int pos, final type sortBy, - final boolean desc, final boolean global) { + public static String[] getStatsValuesForBoard(final Arena arena, final Type statType) { + DEBUG.i("getting stats values: " + (arena == null ? "global" : arena.getName()) + " sorted by " + statType); - int iThis = aps[pos].getStatistics(aps[pos].getArena()).getStat(sortBy); - int iNext = aps[pos + 1].getStatistics(aps[pos].getArena()).getStat(sortBy); - - if (global) { - iThis = aps[pos].getTotalStatistics(sortBy); - iNext = aps[pos + 1].getTotalStatistics(sortBy); + if (arena == null) { + return ArenaPlayer.getAllArenaPlayers().stream() + .map(ap -> (statType == Type.NULL) ? ap.getName() : String.valueOf(ap.getTotalStatistics(statType))) + .sorted(reverseOrder()) + .limit(8) + .toArray(String[]::new); } - return desc ? iThis < iNext : iThis > iNext; + return arena.getFighters().stream() + .map(ap -> (statType == Type.NULL) ? ap.getName() : String.valueOf(ap.getStatistics().getStat(statType))) + .sorted(reverseOrder()) + .limit(8) + .toArray(String[]::new); } /** - * get a set of arena players sorted by type - * - * @param arena the arena to check - * @param sortBy the type to sort - * @return an array of ArenaPlayer + * Get stats map for a given stat type + * @param arena the arena to check + * @param statType the kind of stat + * @return A map with player name and stat value */ - public static ArenaPlayer[] getStats(final Arena arena, final type sortBy) { - return getStats(arena, sortBy, true); - } - - /** - * get a set of arena players sorted by type - * - * @param arena the arena to check - * @param sortBy the type to sort - * @param desc should it be sorted descending? - * @return an array of ArenaPlayer - */ - private static ArenaPlayer[] getStats(final Arena arena, final type sortBy, final boolean desc) { - DEBUG.i("getting stats: " + (arena == null ? "global" : arena.getName()) + " sorted by " + sortBy + ' ' - + (desc ? "desc" : "asc")); - - final int count = arena == null ? ArenaPlayer.countPlayers() : arena.getFighters().size(); + public static Map getStats(final Arena arena, final Type statType) { + DEBUG.i("getting stats: " + (arena == null ? "global" : arena.getName()) + " sorted by " + statType); - final ArenaPlayer[] aps = new ArenaPlayer[count]; - - int pos = 0; if (arena == null) { - for (final ArenaPlayer p : ArenaPlayer.getAllArenaPlayers()) { - aps[pos++] = p; - } - } else { - for (final ArenaPlayer p : arena.getFighters()) { - aps[pos++] = p; - } + return ArenaPlayer.getAllArenaPlayers().stream() + .collect(Collectors.toMap(ArenaPlayer::getName, ap -> ap.getTotalStatistics(statType))); } - sortBy(aps, sortBy, desc, arena == null); - - return aps; + return arena.getFighters().stream() + .collect(Collectors.toMap(ArenaPlayer::getName, ap -> ap.getStatistics().getStat(statType))); } /** @@ -220,10 +198,10 @@ private static ArenaPlayer[] getStats(final Arena arena, final type sortBy, fina * @param line the line to determine the type * @return the Statistics type */ - public static type getTypeBySignLine(final String line) { + public static Type getTypeBySignLine(final String line) { final String stripped = ChatColor.stripColor(line).replace("[PA]", "").toUpperCase(); - for (final type t : type.values()) { + for (final Type t : Type.values()) { if (t.name().equals(stripped)) { return t; } @@ -231,7 +209,7 @@ public static type getTypeBySignLine(final String line) { return t; } } - return type.NULL; + return Type.NULL; } public static void initialize() { @@ -239,10 +217,10 @@ public static void initialize() { return; } config = new YamlConfiguration(); - players = new File(PVPArena.instance.getDataFolder(), "players.yml"); - if (!players.exists()) { + playersFile = new File(PVPArena.instance.getDataFolder(), "players.yml"); + if (!playersFile.exists()) { try { - players.createNewFile(); + playersFile.createNewFile(); Arena.pmsg(Bukkit.getConsoleSender(), Language.parse(MSG.STATS_FILE_DONE)); } catch (final Exception e) { Arena.pmsg(Bukkit.getConsoleSender(), Language.parse(MSG.ERROR_STATS_FILE)); @@ -251,7 +229,7 @@ public static void initialize() { } try { - config.load(players); + config.load(playersFile); } catch (final Exception e) { Arena.pmsg(Bukkit.getConsoleSender(), Language.parse(MSG.ERROR_STATS_FILE)); e.printStackTrace(); @@ -282,79 +260,17 @@ public static void kill(final Arena arena, final Entity entity, final Player def ArenaPlayer.parsePlayer(defender.getName()).addDeath(); } - /** - * gather all type information of an array of ArenaPlayers - * - * @param players the ArenaPlayer array to check - * @param tType the type to read - * @return an Array of String - */ - public static String[] read(final ArenaPlayer[] players, final type tType, final boolean global) { - final String[] result = new String[players.length < 8 ? 8 : players.length]; - int pos = 0; - if (global) { - for (final ArenaPlayer p : players) { - if (p == null) { - continue; - } - if (tType == type.NULL) { - result[pos++] = p.getName(); - } else { - result[pos++] = String.valueOf(p.getTotalStatistics(tType)); - } - } - } else { - for (final ArenaPlayer p : players) { - if (tType == type.NULL) { - result[pos++] = p.getName(); - } else { - result[pos++] = String.valueOf(p.getStatistics(p.getArena()).getStat(tType)); - } - } - } - while (pos < 8) { - result[pos++] = ""; - } - return result; - } - public static void save() { if (config == null) { return; } try { - config.save(players); + config.save(playersFile); } catch (final IOException e) { e.printStackTrace(); } } - /** - * bubble sort an ArenaPlayer array by type - * - * @param aps the ArenaPlayer array - * @param sortBy the type to sort by - * @param desc descending order? - * @param global announce to the whole server? - */ - private static void sortBy(final ArenaPlayer[] aps, final type sortBy, final boolean desc, final boolean global) { - int pos = aps.length; - boolean doMore = true; - while (doMore) { - pos--; - doMore = false; // assume this is our last pass over the array - for (int i = 0; i < pos; i++) { - if (decide(aps, i, sortBy, desc, global)) { - // exchange elements - final ArenaPlayer temp = aps[i]; - aps[i] = aps[i + 1]; - aps[i + 1] = temp; - doMore = true; // after an exchange, must look again - } - } - } - } - public static void loadStatistics(final Arena arena) { if (!PVPArena.instance.getConfig().getBoolean("stats")) { return; @@ -371,65 +287,55 @@ public static void loadStatistics(final Arena arena) { for (final String playerID : config.getConfigurationSection(arena.getName()).getKeys(false)) { - String player = playerID; - - if (config.getConfigurationSection(arena.getName()).contains(playerID+".playerName")) { - // old broken version - final OfflinePlayer oPlayer; - try { - oPlayer = Bukkit.getOfflinePlayer(UUID.fromString(playerID)); - } catch (final NoSuchMethodError error) { - continue; - } - - player = oPlayer.getName(); - config.getConfigurationSection(arena.getName()).set(playerID+".name", player); - config.getConfigurationSection(arena.getName()).set(playerID+".playerName", null); + String playerName = null; - foundBroken = true; - } else if (config.getConfigurationSection(arena.getName()).contains(playerID+".name")) { - // new version - player = config.getConfigurationSection(arena.getName()).getString(playerID+".name"); + if (config.getConfigurationSection(arena.getName()).contains(playerID+".name")) { + playerName = config.getConfigurationSection(arena.getName()).getString(playerID+".name"); } - arena.getDebugger().i("loading stats: " + player); + arena.getDebugger().i("loading stats: " + playerName); final ArenaPlayer aPlayer; try { - aPlayer = ArenaPlayer.parsePlayer(player); + if(playerName != null) { + aPlayer = ArenaPlayer.addPlayer(playerName); + } else { + continue; + } + } catch (IllegalArgumentException e) { PVPArena.instance.getLogger().warning("invalid player ID: " + playerID); continue; } - for (final type ttt : type.values()) { + for (final Type ttt : Type.values()) { aPlayer.setStatistic(arena.getName(), ttt, 0); } final int losses = config.getInt(arena.getName() + '.' + playerID + ".losses", 0); - aPlayer.addStatistic(arena.getName(), type.LOSSES, losses); + aPlayer.addStatistic(arena.getName(), Type.LOSSES, losses); final int wins = config.getInt(arena.getName() + '.' + playerID + ".wins", 0); - aPlayer.addStatistic(arena.getName(), type.WINS, wins); + aPlayer.addStatistic(arena.getName(), Type.WINS, wins); final int kills = config.getInt(arena.getName() + '.' + playerID + ".kills", 0); - aPlayer.addStatistic(arena.getName(), type.KILLS, kills); + aPlayer.addStatistic(arena.getName(), Type.KILLS, kills); final int deaths = config.getInt(arena.getName() + '.' + playerID + ".deaths", 0); - aPlayer.addStatistic(arena.getName(), type.DEATHS, deaths); + aPlayer.addStatistic(arena.getName(), Type.DEATHS, deaths); final int damage = config.getInt(arena.getName() + '.' + playerID + ".damage", 0); - aPlayer.addStatistic(arena.getName(), type.DAMAGE, damage); + aPlayer.addStatistic(arena.getName(), Type.DAMAGE, damage); final int maxdamage = config.getInt(arena.getName() + '.' + playerID + ".maxdamage", 0); - aPlayer.addStatistic(arena.getName(), type.MAXDAMAGE, maxdamage); + aPlayer.addStatistic(arena.getName(), Type.MAXDAMAGE, maxdamage); final int damagetake = config.getInt(arena.getName() + '.' + playerID + ".damagetake", 0); - aPlayer.addStatistic(arena.getName(), type.DAMAGETAKE, damagetake); + aPlayer.addStatistic(arena.getName(), Type.DAMAGETAKE, damagetake); final int maxdamagetake = config.getInt(arena.getName() + '.' + playerID + ".maxdamagetake", 0); - aPlayer.addStatistic(arena.getName(), type.MAXDAMAGETAKE, maxdamagetake); + aPlayer.addStatistic(arena.getName(), Type.MAXDAMAGETAKE, maxdamagetake); } if (foundBroken) { save(); @@ -447,32 +353,32 @@ public static void update(final Arena arena, final ArenaPlayer aPlayer) { try { node = aPlayer.get().getUniqueId().toString(); - } catch (final Exception e) { + } catch (final Exception ignored) { } - final int losses = map.getStat(type.LOSSES); + final int losses = map.getStat(Type.LOSSES); config.set(arena.getName() + '.' + node + ".losses", losses); - final int wins = map.getStat(type.WINS); + final int wins = map.getStat(Type.WINS); config.set(arena.getName() + '.' + node + ".wins", wins); - final int kills = map.getStat(type.KILLS); + final int kills = map.getStat(Type.KILLS); config.set(arena.getName() + '.' + node + ".kills", kills); - final int deaths = map.getStat(type.DEATHS); + final int deaths = map.getStat(Type.DEATHS); config.set(arena.getName() + '.' + node + ".deaths", deaths); - final int damage = map.getStat(type.DAMAGE); + final int damage = map.getStat(Type.DAMAGE); config.set(arena.getName() + '.' + node + ".damage", damage); - final int maxdamage = map.getStat(type.MAXDAMAGE); + final int maxdamage = map.getStat(Type.MAXDAMAGE); config.set(arena.getName() + '.' + node + ".maxdamage", maxdamage); - final int damagetake = map.getStat(type.DAMAGETAKE); + final int damagetake = map.getStat(Type.DAMAGETAKE); config.set(arena.getName() + '.' + node + ".damagetake", damagetake); - final int maxdamagetake = map.getStat(type.MAXDAMAGETAKE); + final int maxdamagetake = map.getStat(Type.MAXDAMAGETAKE); config.set(arena.getName() + '.' + node + ".maxdamagetake", maxdamagetake); if (!node.equals(aPlayer.getName())) { From 262614a7a4aa71b8189f892af9f5cbc53eff6135 Mon Sep 17 00:00:00 2001 From: Eredrim Date: Tue, 23 Jun 2020 17:37:52 +0200 Subject: [PATCH 22/43] v1.15 - fix missing death causes --- lang/lang_en.yml | 4 ++++ lang/lang_fr.yml | 4 ++++ src/net/slipcor/pvparena/arena/Arena.java | 4 ++-- src/net/slipcor/pvparena/core/Language.java | 4 ++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lang/lang_en.yml b/lang/lang_en.yml index 86a69781b..d0ed6ace4 100644 --- a/lang/lang_en.yml +++ b/lang/lang_en.yml @@ -66,6 +66,10 @@ nulang: SUICIDE: self THORNS: thorns VOID: the Void + FALLING_BLOCK: a falling block + HOT_FLOOR: a magma block + CRAMMING: a collision surplus + DRAGON_BREATH: dragon breath CREEPER: a creeper SKELETON: a skeleton SPIDER: a spider diff --git a/lang/lang_fr.yml b/lang/lang_fr.yml index c4c4c7990..8a2e93178 100644 --- a/lang/lang_fr.yml +++ b/lang/lang_fr.yml @@ -70,6 +70,10 @@ nulang: SUICIDE: lui-même THORNS: thorns VOID: le vide + FALLING_BLOCK: une chute de bloc + HOT_FLOOR: un bloc de magma + CRAMMING: un surplus de collisions + DRAGON_BREATH: le souffle d'un dragon CREEPER: un creeper SKELETON: un squelette SPIDER: une araignée diff --git a/src/net/slipcor/pvparena/arena/Arena.java b/src/net/slipcor/pvparena/arena/Arena.java index 6fcac2249..2cce050da 100644 --- a/src/net/slipcor/pvparena/arena/Arena.java +++ b/src/net/slipcor/pvparena/arena/Arena.java @@ -865,6 +865,7 @@ public String parseDeathCause(final Player player, final DamageCause cause, switch (cause) { case ENTITY_ATTACK: + case ENTITY_SWEEP_ATTACK: if (damager instanceof Player && team != null) { return team.colorizePlayer(aPlayer.get()) + ChatColor.YELLOW; } @@ -917,8 +918,7 @@ public String parseDeathCause(final Player player, final DamageCause cause, default: break; } - MSG string = MSG.getByName("DEATHCAUSE_" - + cause.toString()); + MSG string = MSG.getByName("DEATHCAUSE_" + cause.toString()); if (string == null) { PVPArena.instance.getLogger().warning("Unknown cause: " + cause.toString()); string = MSG.DEATHCAUSE_VOID; diff --git a/src/net/slipcor/pvparena/core/Language.java b/src/net/slipcor/pvparena/core/Language.java index ab49dedc3..d8c4bb6c8 100644 --- a/src/net/slipcor/pvparena/core/Language.java +++ b/src/net/slipcor/pvparena/core/Language.java @@ -86,6 +86,10 @@ public enum MSG { DEATHCAUSE_SUICIDE("nulang.deathcause.SUICIDE", "self"), DEATHCAUSE_THORNS("nulang.deathcause.THORNS", "thorns"), DEATHCAUSE_VOID("nulang.deathcause.VOID", "the Void"), + DEATHCAUSE_FALLING_BLOCK("nulang.deathcause.FALLING_BLOCK", "a falling block"), + DEATHCAUSE_HOT_FLOOR("nulang.deathcause.HOT_FLOOR", "a magma block"), + DEATHCAUSE_CRAMMING("nulang.deathcause.CRAMMING", "a collision surplus"), + DEATHCAUSE_DRAGON_BREATH("nulang.deathcause.DRAGON_BREATH", "dragon breath"), DEATHCAUSE_CREEPER("nulang.deathcause.CREEPER", "a creeper"), DEATHCAUSE_SKELETON("nulang.deathcause.SKELETON", "a skeleton"), From 7a24841c7282083878e7435a585f2a867e45cf93 Mon Sep 17 00:00:00 2001 From: Eredrim Date: Tue, 23 Jun 2020 18:49:13 +0200 Subject: [PATCH 23/43] v1.15 - clear unused translations and configs, and improve french translation --- lang/lang_en.yml | 9 - lang/lang_es-es.yml | 9 - lang/lang_fr.yml | 268 +++++++++----------- src/net/slipcor/pvparena/core/Config.java | 15 -- src/net/slipcor/pvparena/core/Language.java | 21 -- 5 files changed, 121 insertions(+), 201 deletions(-) diff --git a/lang/lang_en.yml b/lang/lang_en.yml index d0ed6ace4..5adb41b8a 100644 --- a/lang/lang_en.yml +++ b/lang/lang_en.yml @@ -322,15 +322,6 @@ nulang: claimed: '[%1%] %2% claimed the pillar!' unclaimed: '[%1%] %2% unclaimed the pillar!' score: '%1% scored %2% points' - rescue: - flaghomeleft: '%1% brought home the hostage of team %2%! Rescues remaining: - %3%' - flagsave: '%1% dropped the hostage of team %2%!' - flaggrab: '%1% grabbed the hostage of team %2%!' - flagnotsafe: Your hostage is taken! Cannot bring back an enemy hostage!' - setflag: 'Rescue set: %1%' - tosetflag: 'Rescue to set: %1%' - typeset: 'Hostage type set to: &e%1%' help: head: '&e--- &aPVP Arena Help&e %1% &e---' admin: '&c%1% - help administrating' diff --git a/lang/lang_es-es.yml b/lang/lang_es-es.yml index 178366bfa..a0cc90fd8 100644 --- a/lang/lang_es-es.yml +++ b/lang/lang_es-es.yml @@ -268,15 +268,6 @@ nulang: claimed: ¡[%1%] %2% ha tomado el pilar! unclaimed: ¡[%1%] %2% esta siendo tomado! score: '%1% hizo %2% punto/s' - rescue: - flaghomeleft: '%1% brought home the hostage of team %2%! Rescues remaining: - %3%' - flagsave: '%1% dropped the hostage of team %2%!' - flaggrab: '%1% grabbed the hostage of team %2%!' - flagnotsafe: Your hostage is taken! Cannot bring back an enemy hostage!' - setflag: 'Rescue set: %1%' - tosetflag: 'Rescue to set: %1%' - typeset: 'Hostage type set to: &e%1%' help: head: '&e--- &aAyuda de PVP Arena&e %1% &e---' admin: '&c%1% - Ayuda de Administración' diff --git a/lang/lang_fr.yml b/lang/lang_fr.yml index 8a2e93178..6c65dc79f 100644 --- a/lang/lang_fr.yml +++ b/lang/lang_fr.yml @@ -17,8 +17,8 @@ nulang: remove: done: L'arène &e%1%&r vient d'être supprimée setup: - disabled: 'Disabled setup mode for arena: %1%' - enabled: 'Enabled setup mode for arena: %1%' + disabled: 'Désactivation du mode configuration pour l''arène : %1%' + enabled: 'Désactivation du mode configuration pour l''arène : %1%' startingin: Il y a assez de joueurs prêts. Le combat commence dans %1% ! start: done: Combat démarré manuellement ! @@ -36,21 +36,21 @@ nulang: added: Vous avez ajouté &a%1%&r à la liste noire de &e%2%&r ! allcleared: Toutes les listes noires ont été effacées ! cleared: La liste noire &e%1%&r a été effacée ! - help: 'Utilisation: blacklist clear | blacklist [type] [clear|add|remove] [id]' + help: 'Aide : blacklist clear | blacklist [type] [clear|add|remove] [id]' removed: Vous avez supprimé &a%1%&r de la liste noire &e%2%&r ! show: 'Liste noire &e%1%&r :' check: done: Verification faite ! Aucune erreur! class: - list: 'Available classes: %1%' + list: 'Classes disponibles : %1%' preview: Vous avez un aperçu de la classe %1% removed: La classe %1% a été supprimée saved: La classe %1% a été sauvegardée selected: Vous avez choisi la classe &e%1%&e - selectedrespawn: You will switch to the &e%1%&f class on next respawn. + selectedrespawn: Vous réapparaitrez avec la classe &e%1%&f au prochain respawn. classchest: - done: Successfully set the class items of %1% to the contents of %2%. Please reload - the arena when you are done setting chests! + done: Les items de la classe %1% proviendront dorénavant du contenu du coffre %2%. Veuillez recharger + la configuration de l'arène lorsque vous aurez fini de remplir le coffre en question. deathcause: BLOCK_EXPLOSION: une explosion CONTACT: un cactus @@ -173,10 +173,9 @@ nulang: region: beingcreated: 'Une région a déja été créée: %1%' flagnotfound: 'RegionFlag &a%1%&r inconnu! Valeurs valides: %2%' - invalid: Region selection is invalid. Region will have no volume and will be - useless! + invalid: La sélection de la région est incorrecte. Celle-ci est vide et sera par conséquent inutile. notfound: Region &a%1%&r non trouvée ! - protectionnotfound: RegionProtection &a%1%&r non trouvée ! + protectionnotfound: Protection de région &a%1%&r non trouvée ! typenotfound: 'RegionType &a%1%&r inconnu ! Valeurs valides: %2%' youselect: Vous avez déjà sélectionné une région pour l'arène ! youselect2: Retapez la commande pour annuler la sélection ! @@ -184,15 +183,15 @@ nulang: regionnotbeingcreated: Aucune région n'est en cours de création ! regionnotremoved: Il n'y a pas de configuration de région. select2: Selectionnez 2 points avant de vouloir les sauvegarder. - setupmode: setup mode! + setupmode: Mode de configuration ! spawn: unknown: 'Spawn inconnu: &a%1%&r' - spawnfree: Erreur ! Arena est de type free. Utilisez 'spawnX' où X est un chiffre + spawnfree: Erreur ! Arena est de type free (ffa). Utilisez 'spawnX' où X est un chiffre ou une lettre ! statsfile: Erreur lors de la lecture du fichier stats ! teamnotfound: 'Equipe non trouvée: &a%1%&r' - uninstall: Erreur lors de la désinstallation &a%1%&r - uninstall2: PVP Arena will try to uninstall on server restart! + uninstall: Erreur lors de la désinstallation de &a%1%&r + uninstall2: PVP Arena tentera une déinstallation au redémarrage du serveur. unknownmodule: 'Module non trouvé: %1%' whitelist: disallowed: Vous ne devriez pas %1% ça ! (non whitelisté) @@ -212,54 +211,54 @@ nulang: teleport: téléporter au spawn d'une arène user: utiliser l'arène cmds: - blacklist: use the blacklist command - check: use the check command - class: use the class command - create: use the create command - debug: use the debug command - disable: use the disable command - duty: use the duty command - edit: use the edit command - enable: use the enable command - gamemode: use the gamemode command - goal: use the goal command - install: use the install command - playerclass: use the playerclass command - playerjoin: use the playerjoin command - protection: use the protection command - region: use the region command - regionflag: use the regionflag command - regions: use the regions command - regiontype: use the regiontype command - reload: use the reload command - remove: use the remove command - round: use the round command - set: use the set command - setowner: use the setowner command - setup: use the setup command - spawn: use the spawn command - start: use the start command - stop: use the stop command - teams: use the teams command - teleport: use the teleport command - template: use the template command - togglemod: use the togglemod command - uninstall: use the uninstall command - update: use the update command - whitelist: use the whitelist command - arenaclass: use the arenaclass command - chat: use the chat command - join: use the join command - leave: use the leave command - spectate: use the spectate command - arenalist: use the arenalist command - help: use the help command - info: use the info command - list: use the list command - ready: use the ready command - shutup: use the shutup command - stats: use the stats command - version: use the version command + blacklist: d'utiliser la commande blacklist + check: d'utiliser la commande check + class: d'utiliser la commande class + create: d'utiliser la commande create + debug: d'utiliser la commande debug + disable: d'utiliser la commande disable + duty: d'utiliser la commande duty + edit: d'utiliser la commande edit + enable: d'utiliser la commande enable + gamemode: d'utiliser la commande gamemode + goal: d'utiliser la commande goal + install: d'utiliser la commande install + playerclass: d'utiliser la commande playerclass + playerjoin: d'utiliser la commande playerjoin + protection: d'utiliser la commande protection + region: d'utiliser la commande region + regionflag: d'utiliser la commande regionflag + regions: d'utiliser la commande regions + regiontype: d'utiliser la commande regiontype + reload: d'utiliser la commande reload + remove: d'utiliser la commande remove + round: d'utiliser la commande round + set: d'utiliser la commande set + setowner: d'utiliser la commande setowner + setup: d'utiliser la commande setup + spawn: d'utiliser la commande spawn + start: d'utiliser la commande start + stop: d'utiliser la commande stop + teams: d'utiliser la commande teams + teleport: d'utiliser la commande teleport + template: d'utiliser la commande template + togglemod: d'utiliser la commande togglemod + uninstall: d'utiliser la commande uninstall + update: d'utiliser la commande update + whitelist: d'utiliser la commande whitelist + arenaclass: d'utiliser la commande arenaclass + chat: d'utiliser la commande chat + join: d'utiliser la commande join + leave: d'utiliser la commande leave + spectate: d'utiliser la commande spectate + arenalist: d'utiliser la commande arenalist + help: d'utiliser la commande help + info: d'utiliser la commande info + list: d'utiliser la commande list + ready: d'utiliser la commande ready + shutup: d'utiliser la commande shutup + stats: d'utiliser la commande stats + version: d'utiliser la commande version fight: begins: Que le combat commence ! draw: Match nul ! Egalité ! @@ -283,19 +282,6 @@ nulang: added: 'Objectif ajouté: &a%1%&r' installing: 'Installez des objectifs avec la commande: &a/pa install [goalname]&r' removed: 'Objectif supprimé: &a%1%&r' - beacons: - claiming: '&eTeam %1% is claiming the beacon!' - claimed: '&eTeam %1% has claimed the beacon!' - claimed_remaining: '&eTeam %1% has claimed the beacon! %2% claims remaining!' - score: '&eTeam %1% scored %2% points by holding the beacon!' - changed: '&eA new beacon has been activated!' - contesting: '&eThe beacon claimed by team %1% is being contested!' - unclaiming: '&eThe beacon claimed by team %1% is being unclaimed!' - unclaimingby: '&eThe beacon claimed by team %1% is being unclaimed by team %2%!' - set: 'Beacon set: %1%' - setdone: Beacon setting mode deactivated. - toset: Beacon setting mode activated. Hit the glass blocks, then use the command - again to save! blockdestroy: typeset: 'Blocktype configuré en: &e%1%' setflag: 'Bloc configuré: %1%' @@ -338,14 +324,14 @@ nulang: youtnt: Vous portez maintenant le matériel de sabotage !' tank: tankdown: Le tank est H.S. ! - tankmode: TANK MODE ! Tous le monde doit tuer %1%, le tank ! + tankmode: MODE TANK ! Tous le monde doit tuer %1%, le tank ! tankwon: Le tank a gagné ! Félicitations à %1% ! tdc: - denied: '%1% denied a kill!' - remaining: '%1% kills remaining for %2%.' - scored: '%1% scored a kill!' - youdenied: You denied a kill! - youscored: You scored a kill! + denied: '%1% a refusé un kill!' + remaining: '%1% kills restants pour %2%.' + scored: '%1% a enregistré un kill!' + youdenied: Vous avez refusé un kill ! + youscored: Vous avez enregistré un kill ! pillars: msg: block_broken: '[%1%] %2% a cassé un bloc !' @@ -355,15 +341,6 @@ nulang: claimed: '[%1%] %2% a réclamé la colonne !' unclaimed: '[%1%] %2% a libéré la colonne !' score: '%1% a marqué %2% points' - rescue: - flaghomeleft: '%1% brought home the hostage of team %2%! Rescues remaining: - %3%' - flagsave: '%1% dropped the hostage of team %2%!' - flaggrab: '%1% grabbed the hostage of team %2%!' - flagnotsafe: Your hostage is taken! Cannot bring back an enemy hostage!' - setflag: 'Rescue set: %1%' - tosetflag: 'Rescue to set: %1%' - typeset: 'Hostage type set to: &e%1%' help: head: '&e--- &aAide de PVP Arena&e %1% &e---' admin: '&c%1% - aide administration' @@ -404,8 +381,7 @@ nulang: trickerdisabled: Suivi du plugin désactivé. Rendez-vous bientôt ? trackingenabled: 'Suivi du plugin activé. Configurer le suivi: false dans la configuration pricipale à désactiver.' - updatedisabled: Mises à jour désactivée. Veuillez vérifier dev.bukkit pour les - mises à jour. + updatedisabled: Mises à jour désactivée. Pensez à vérifier spigot.org pour les mises à jour. updateenabled: Recherche de mise à jour... warning: '%1%' messages: @@ -438,13 +414,13 @@ nulang: playerready: '%1%&e est prêt !' player: prevented: - break: '&cYou may not break blocks!' - place: '&cYou may not place blocks!' - tnt: '&cYou may not use TNT!' - tntbreak: '&cYou may not break TNT!' - drop: '&cYou may not drop items!' - inventory: '&cYou may not access this!' - craft: '&cYou may not craft!' + break: '&cVous n''êtes pas autorisé à casser des blocs !' + place: '&cVous n''êtes pas autorisé à poser des blocs !' + tnt: '&cVous n''êtes pas autorisé à utiliser de la TNT !' + tntbreak: '&cVous n''êtes pas autorisé à casser de la TNT !' + drop: '&cVous n''êtes pas autorisé jeter vos items !' + inventory: '&cVous n''êtes pas autorisé à accéder à cela !' + craft: '&cVous n''êtes pas autorisé à crafter !' notreadyplayers: Les joueurs ne sont pas prêts players: Joueurs ready: @@ -452,9 +428,9 @@ nulang: done: Tu viens d'être enregistré comme prêt ! region: clear: - added: 'Added to region entity clearing whitelist: &a%1%&r' - list: 'Region entity clearing whitelist: &a%1%&r' - removed: 'Removed from region entity clearing whitelist: &a%1%&r' + added: 'Région ajoutée à la whitelist de nettoyage des entités: &a%1%&r' + list: 'Liste des régions appartenant à la whitelist de nettoyage des entités: &a%1%&r' + removed: 'Région retirée de la whitelist de nettoyage des entités: &a%1%&r' flag: added: 'Flag ajouté: &a%1%&r' removed: 'Flag suppimé: &a%1%&r' @@ -466,15 +442,15 @@ nulang: radius: 'Rayon de la région: &a%1%&r' removed: 'Region supprimée: %1%' saved: Region enregistrée. - saved_notice: '&6You created a &oCUSTOM&6 region. It has no function yet! To turn - it into a battlefield region, type &r/pvparena %1% !rt %2% BATTLE' + saved_notice: '&6Vous avez créé une région &oCUSTOM&6. Celle-ci n''a aucune fonction. Pour créer une région + pour combattre, tapez &r/pvparena %1% !rt %2% BATTLE' select: Selectionne deux points avec le wand item, clic gauche pour le prmier et clic droit pour le second ! setting: Paramètrage de région activé. - typeset: 'Region Type modifié en: &e%1%' + typeset: 'Type de région modifié en: &e%1%' youselect: Vous séléctionnez maintenant une région pour &a%1%&r! regions: - flags: 'Region Flags: &a%1%&r' + flags: 'Flags de région: &a%1%&r' head: '--- &aRégion de l''arène&r [&e%1%&r]---' listhead: '--- &aRégions de l''arène&r [&e%1%&r]---' listvalue: '&a%1%&r: %2%, %3%' @@ -483,15 +459,15 @@ nulang: type: 'Type de région: &a%1%&r' reloaded: Config actualisée! ymls: - reloaded: Languages reloaded! + reloaded: Fichiers de langue rechargés ! round: - display: 'Rond #%1%: %2%' - added: 'Objectif ajouté au rond: &e%1%' - removed: 'Objectif supprimé au rond: &e%1%' + display: 'Round #%1%: %2%' + added: 'Objectif ajouté au round: &e%1%' + removed: 'Objectif supprimé du round: &e%1%' roundsdisplay: Round %1% / %2% roundsdisplayseparator: '-----------' set: - items_not: Please use either hand or inventory to set an item node! + items_not: Veuillez utiliser les mots clés "hand" ou "inventory" pour définir un item dans la configuration. done: '&a%1%&r configuré à &e%2%&r!' help: utilise /pa {arenaname} set [page] pour obtenir la liste des configurations unknown: 'Config inconnue: &e%1%&r!' @@ -506,10 +482,10 @@ nulang: set: 'Spawn configuré: &a%1%&r' setdone: 'Paramètrage du spawn terminé: &a%1%&r' setstart: 'Paramètrage du spawn: &a%1%&r' - unknown: 'Spawn not found: &a%1%&r' + unknown: 'Spawn inconnu : &a%1%&r' stats: filedone: Fichier stats chargé ! - head: Statistics TOP %1% (%2%) + head: Statistiques TOP %1% (%2%) typenotfound: 'Type de statistique non trouvé! Valeurs correctes: &e%1%&r' stattype: DAMAGE: dommages totaux accordé @@ -544,8 +520,8 @@ nulang: pvpactivating: Le PVP sera activé dans %1%! walls: Les murs disparaitront dans %1%! togglemod: - notice: '&cYou activated a module that requires a BATTLE region! Type &r/pvparena - [arena] !rt [region] BATTLE' + notice: '&cVous venez d''activer un module nécessitant une région de type BATTLE ! Pour changer le type de région + Tapez &r/pvparena [arena] !rt [region] BATTLE' uninstall: done: 'supprimé: &a%1%&r' whitelist: @@ -559,7 +535,7 @@ nulang: aftermatch: aftermatch: L'aprèsmatch a commencé ! startingin: AprèsMatch dans %1%! - spawnnotset: Spawn 'après' non configuré ! + spawnnotset: Spawn 'after' non configuré ! announcements: ignoreon: Vous ignorez maintenant les annonces ! ignoreoff: Vous recevrez maintenant les annonces ! @@ -576,21 +552,20 @@ nulang: duel: accepted: '%1% &ea accepté le challenge ! Que le jeu commence !' announce: '%1% &evous a defié! Accepte le duel avec &f/pa %2% accept.' - announcemoney: '&eThey set up a fee of &c%1%&e!' - announce2: '&eCancel the duel with &r/pa %2% decline&e.' - cancelled: '&cThe duel has been cancelled!' - busy: '%1% &eis already in a fight Please try again later.' - declineds: Your opponent did decline. The duel has been cancelled. - declinedr: You cancelled the duel! - requested: You &echallenged &f%1%&e! - requestedalready: You already have challenged someone! - requestexpireds: Your opponent did not accept the request in time. The duel - has been cancelled. - requestexpiredr: You did not accept the request in time. The duel has been cancelled. + announcemoney: '&eLe prix d''entrée est de &c%1%&e!' + announce2: '&eRefusez le duel avec &r/pa %2% decline&e.' + cancelled: '&cLe duel a été annulé!' + busy: '%1% &ecombat actuellement. Veuillez réessayer plus tard.' + declineds: Votre opposant a refusé. Le duel est annulé. + declinedr: Vous avez refusé le duel ! + requested: Vous &eavez défié &f%1%&e! + requestedalready: Vous avez déjà défié quelqu'un ! + requestexpireds: Votre opposant n'a pas accepté le duel a temps. Le duel est donc annulé. + requestexpiredr: Vous n'avez pas accepté le duel a temps. Le duel est donc annulé. starting: Le duel commence ! - nodirectjoin: 'You may not join this arena directly! Use: &e/pa %1% duel [playername]' + nodirectjoin: 'Vous pouvez rejoindre directement le combat ! Utilisez: &e/pa %1% duel [nomDuJoueur]' fixinventorylos: - gamemode: Entrez en mode survie avant de rejoindre l'arène ! + gamemode: Passez en mode survie avant de rejoindre l'arène ! invenory: Videz votre inventaire avant de rejoindre l'arène ! latelounge: llannounce: L'arène %1% est ouverte ! Le joueur %2% veut commencer. Rejoint @@ -602,13 +577,13 @@ nulang: llleave: Vous venez de quitter la file d'attente de l'arène %1%. playerfinder: near: 'Joueur le plus proche: %1% blocs!' - point: La boussole pointe sur le joueur le plus proche ! + point: La boussole indique le joueur le plus proche ! powerups: invalidpowerupeffect: 'PowerupEffect invalide: %1%' puplayer: '%1% a collecté le PowerUp %2%!' puserver: PowerUp déployé! respawnrelay: - respawning: Respawning in %1%! + respawning: Réapparition dans %1%! skins: dc: Connecté à DisguiseCraft ! ld: Hooking into LibsDisguises! @@ -658,18 +633,18 @@ nulang: killreward: Vous recevez %1% pour avoir tué %2%! refunding: Remboursement %1%! walls: - fallingin: 'Walls fall in: %1%' + fallingin: 'Les murs tomberont dans : %1%' separator: '--------------------' worldedit: - created: 'Region créée: &e%1%' - list_added: Region &e%1%&f will now be specifically saved. - list_removed: Region &e%1%&f will no longer be specifically saved. - list_show: 'These regions will be saved specifically: &e%1%&f' + created: 'Région créée: &e%1%' + list_added: La région &e%1%&f sera maintenant spécifiquement sauvegardée. + list_removed: Region &e%1%&f ne sera plus spécifiquement sauvegardée. + list_show: 'Ces régions sont spécifiquement sauvegardées : &e%1%&f' loaded: 'Region chargée: &e%1%' saved: 'Region sauvegardée: &e%1%' worldguard: - created: 'Region not found: &e%1%' - saved: Region &e%2%&f saved to &e%1% + created: 'Region non trouvée : &e%1%' + saved: La région &e%2%&f a été enregistrée sous &e%1% banvote: lang: playerbanned: 'Joueur banni: %1%' @@ -685,22 +660,21 @@ nulang: clear: Classe &e%1%&r effacée ! listhead: '--- Effets de potion pour la classe &e%1%&r ---' remove: L'effet de potion &e%2%&r a été supprimé de la classe &e%1%&r! - respawncommand_remove: Respawn command removed from ArenaClass &e%1%&r! + respawncommand_remove: La commande de respawn a été supprimée de la classe &e%1%&r! classchange: - mteam: '&cYour team has exceeded the class change limit!' - mplayer: '&cYou have exceeded the class change limit!' + mteam: '&cVotre équipe a dépassé le quota de changement de classe !' + mplayer: '&cVous avez dépassé le quota de changement de classe !' bettergears: classdone: La classe &e%1%&r a dorénavant une protection de niveau &a%2% showclass: La classe &e%1%&r a une protection de niveau &a%2% showteam: L'équipe %1% a la couleur %2% teamdone: L'équipe %1% a maintenant la couleur %2% blockrestore: - clearinvdone: Inventaires effacés ! Attendez-vous à des lag au début du prochain - combat ! + clearinvdone: Inventaires (coffres) effacés ! Attendez-vous à des lag au début du prochain combat ! chestfiller: - chest: Successfully set the items to the contents of %1%. - clear: Inventories cleared! - fillchest: 'Added to the list to be filled: %1%.' + chest: Le contenu du coffre %1% a été défini avec succès. + clear: Les contenu des coffres ont été effacés ! + fillchest: 'Ajouté à la liste des coffres devant être remplis : %1%.' announce: arena: L'arène est ouverte ! Tape /pa %1% pour rejoindre le combat ! lang: @@ -727,7 +701,7 @@ lang: votenow: |- Votez votre arène! %1% left! Votez avec /pa [arenaname] vote - Available arenas: %2% + Arènes disponibles : %2% log: tagapi: connecté à TagAPI! version: 0.9.0.0 diff --git a/src/net/slipcor/pvparena/core/Config.java b/src/net/slipcor/pvparena/core/Config.java index a67865933..51e29ea01 100644 --- a/src/net/slipcor/pvparena/core/Config.java +++ b/src/net/slipcor/pvparena/core/Config.java @@ -184,16 +184,6 @@ public enum CFG { USES_WOOLHEAD("uses.woolHead", false, null), // ---------- - - GOAL_BEACONS_ANNOUNCEOFFSET("goal.beacons.spamoffset", 3, "Beacons"), - GOAL_BEACONS_BOSSBAR("goal.beacons.beacBossBar", true, "Beacons"), - GOAL_BEACONS_CHANGESECONDS("goal.beacons.changeseconds", 30, "Beacons"), - GOAL_BEACONS_CHANGEONCLAIM("goal.beacons.changeonclaim", false, "Beacons"), - GOAL_BEACONS_CLAIMRANGE("goal.beacons.claimrange", 3, "Beacons"), - GOAL_BEACONS_LIVES("goal.beacons.blives", 10, "Beacons"), - GOAL_BEACONS_TICKINTERVAL("goal.beacons.tickinterval", 60, "Beacons"), - GOAL_BEACONS_TICKREWARD("goal.beacons.tickreward", 1, "Beacons"), - GOAL_BLOCKDESTROY_BLOCKTYPE("goal.blockdestroy.blocktype", Material.IRON_BLOCK, "BlockDestroy"), GOAL_BLOCKDESTROY_LIVES("goal.blockdestroy.bdlives", 1, "BlockDestroy"), @@ -264,11 +254,6 @@ public enum CFG { GOAL_PLAYERKILLREWARD_GRADUALLYDOWN("goal.playerkillreward.graduallyDown", false, "PlayerKillReward"), GOAL_PLAYERKILLREWARD_ONLYGIVE("goal.playerkillreward.onlyGive", false, "PlayerKillReward"), - GOAL_RESCUE_RESCUETYPE("goal.rescue.flagType", "VILLAGER", "Rescue"), - GOAL_RESCUE_LIVES("goal.rescue.rlives", 1, "Rescue"), - GOAL_RESCUE_MUSTBESAFE("goal.rescue.mustBeSafe", true, "Rescue"), - GOAL_RESCUE_RESCUEEFFECT("goal.rescue.effect", "none", "Rescue"), - // ----------- MODULES_AFTERMATCH_AFTERMATCH("modules.aftermatch.aftermatch", "off", "AfterMatch"), diff --git a/src/net/slipcor/pvparena/core/Language.java b/src/net/slipcor/pvparena/core/Language.java index d8c4bb6c8..51d1fb8c7 100644 --- a/src/net/slipcor/pvparena/core/Language.java +++ b/src/net/slipcor/pvparena/core/Language.java @@ -477,18 +477,6 @@ public enum MSG { WHITELIST_REMOVED("nulang.whitelist.removed", "Removed &a%1%&r from &e%2%&r whitelist!"), WHITELIST_SHOW("nulang.whitelist.show", "Whitelist &e%1%&r:"), - GOAL_BEACONS_CLAIMING("nulang.goal.beacons.claiming", "&eTeam %1% is claiming the beacon!"), - GOAL_BEACONS_CLAIMED("nulang.goal.beacons.claimed", "&eTeam %1% has claimed the beacon!"), - GOAL_BEACONS_CLAIMED_REMAINING("nulang.goal.beacons.claimed_remaining", "&eTeam %1% has claimed the beacon! %2% claims remaining!"), - GOAL_BEACONS_SCORE("nulang.goal.beacons.score", "&eTeam %1% scored %2% points by holding the beacon!"), - GOAL_BEACONS_CHANGED("nulang.goal.beacons.changed", "&eA new beacon has been activated!"), - GOAL_BEACONS_CONTESTING("nulang.goal.beacons.contesting", "&eThe beacon claimed by team %1% is being contested!"), - GOAL_BEACONS_UNCLAIMING("nulang.goal.beacons.unclaiming", "&eThe beacon claimed by team %1% is being unclaimed!"), - GOAL_BEACONS_UNCLAIMINGBY("nulang.goal.beacons.unclaimingby", "&eThe beacon claimed by team %1% is being unclaimed by team %2%!"), - GOAL_BEACONS_SET("nulang.goal.beacons.set", "Beacon set: %1%"), - GOAL_BEACONS_SETDONE("nulang.goal.beacons.setdone", "Beacon setting mode deactivated."), - GOAL_BEACONS_TOSET("nulang.goal.beacons.toset", "Beacon setting mode activated. Hit the glass blocks, then use the command again to save!"), - GOAL_BLOCKDESTROY_TYPESET("nulang.goal.blockdestroy.typeset", "Blocktype set to: &e%1%"), GOAL_BLOCKDESTROY_SCORE("lang.goal.blockdestroy.score", "%1% destroyed the block of team %2%! Remaining destructions: %3%"), GOAL_BLOCKDESTROY_SET("nulang.goal.blockdestroy.setflag", "Block set: %1%"), @@ -569,15 +557,6 @@ public enum MSG { GOAL_PILLARS_MSG_SCORE("nulang.goal.pillars.msg.score", "%1% scored %2% points."), - - GOAL_RESCUE_BROUGHTHOME("nulang.goal.rescue.flaghomeleft", "%1% brought home the hostage of team %2%! Rescues remaining: %3%"), - GOAL_RESCUE_DROPPED("nulang.goal.rescue.flagsave", "%1% dropped the hostage of team %2%!"), - GOAL_RESCUE_GRABBED("nulang.goal.rescue.flaggrab", "%1% grabbed the hostage of team %2%!"), - GOAL_RESCUE_NOTSAFE("nulang.goal.rescue.flagnotsafe", "Your hostage is taken! Cannot bring back an enemy hostage!'"), - GOAL_RESCUE_SET("nulang.goal.rescue.setflag", "Rescue set: %1%"), - GOAL_RESCUE_TOSET("nulang.goal.rescue.tosetflag", "Rescue to set: %1%"), - GOAL_RESCUE_TYPESET("nulang.goal.rescue.typeset", "Hostage type set to: &e%1%"), - // ----------------------------------------------- MODULE_AFTERMATCH_STARTING("nulang.mod.aftermatch.aftermatch", "The aftermatch has begun!"), From 1d6af32a1164d0275d2b44a5ae718df0fd69dd03 Mon Sep 17 00:00:00 2001 From: Eredrim Date: Tue, 23 Jun 2020 19:09:01 +0200 Subject: [PATCH 24/43] v1.15 - removing old telemetry system --- readme.md | 6 +- src/config.yml | 1 - src/net/slipcor/pvparena/PVPArena.java | 8 -- src/net/slipcor/pvparena/core/Language.java | 2 - src/net/slipcor/pvparena/core/Tracker.java | 84 --------------------- 5 files changed, 3 insertions(+), 98 deletions(-) delete mode 100644 src/net/slipcor/pvparena/core/Tracker.java diff --git a/readme.md b/readme.md index 1165b3c39..f0a3e22df 100644 --- a/readme.md +++ b/readme.md @@ -129,10 +129,10 @@ automatically download updates. *** -## Phoning home +## Telemetry -By default, the server contacts my private server for information purposes. It sends your port, IP (for proper server counting), and the plugin version. -That's it! If you want to disable that, set "tracker" to false in the config! +PVPArena uses bStats to get statistics about basic information like plugin version, java version, +kind of used Minecraft server, etc. You can disable it in the dedicated config file `plugins/bStats/config.yml` *** diff --git a/src/config.yml b/src/config.yml index 7ad58e3e9..b9c8d4cd8 100644 --- a/src/config.yml +++ b/src/config.yml @@ -1,7 +1,6 @@ debug: none server_log: false stats: true -tracker: true language: en onlyPVPinArena: false safeadmin: true diff --git a/src/net/slipcor/pvparena/PVPArena.java b/src/net/slipcor/pvparena/PVPArena.java index 7817e8f47..a7781ef19 100644 --- a/src/net/slipcor/pvparena/PVPArena.java +++ b/src/net/slipcor/pvparena/PVPArena.java @@ -407,7 +407,6 @@ public List onTabComplete(final CommandSender sender, final Command cmd, public void onDisable() { shuttingDown = true; ArenaManager.reset(true); - Tracker.stop(); Debug.destroy(); this.getUpdateChecker().runOnDisable(); Language.logInfo(MSG.LOG_PLUGIN_DISABLED, getDescription().getFullName()); @@ -506,13 +505,6 @@ public void onEnable() { updateChecker = new UpdateChecker(this.getFile()); - if (ArenaManager.count() > 0) { - if (PVPArena.instance.getConfig().getBoolean("tracker", true)) { - final Tracker trackMe = new Tracker(); - trackMe.start(); - } - } - Language.logInfo(MSG.LOG_PLUGIN_ENABLED, getDescription().getFullName()); } } diff --git a/src/net/slipcor/pvparena/core/Language.java b/src/net/slipcor/pvparena/core/Language.java index 51d1fb8c7..398c5f6b6 100644 --- a/src/net/slipcor/pvparena/core/Language.java +++ b/src/net/slipcor/pvparena/core/Language.java @@ -326,8 +326,6 @@ public enum MSG { LOG_PLUGIN_DISABLED("nulang.log.plugindisabled", "disabled (version %1%)"), LOG_PLUGIN_ENABLED("nulang.log.pluginenabled", "enabled (version %1%)"), - LOG_TRACKER_DISABLED("nulang.log.trickerdisabled", "Plugin tracking disabled. See you soon?"), - LOG_TRACKER_ENABLED("nulang.log.trackingenabled", "Plugin tracking enabled. Set 'tracker: false' inside the main config to disable."), LOG_WARNING("nulang.log.warning", "%1%"), MESSAGES_TOARENA("nulang.messages.toArena", "You are now talking to the arena!"), diff --git a/src/net/slipcor/pvparena/core/Tracker.java b/src/net/slipcor/pvparena/core/Tracker.java deleted file mode 100644 index 51afaee9d..000000000 --- a/src/net/slipcor/pvparena/core/Tracker.java +++ /dev/null @@ -1,84 +0,0 @@ -package net.slipcor.pvparena.core; - -import net.slipcor.pvparena.PVPArena; -import net.slipcor.pvparena.core.Language.MSG; -import org.bukkit.Bukkit; -import org.bukkit.scheduler.BukkitTask; - -import java.io.UnsupportedEncodingException; -import java.net.URL; -import java.net.URLEncoder; - -/** - *
Tracker class
- *

- * phones home to www.slipcor.net, saving server IP and PVP Arena version - * - * @author slipcor - * @version v0.9.5 - */ - -public class Tracker implements Runnable { - private static BukkitTask timerTask; - private static final Debug debug = new Debug(18); - - /** - * call home to save the server/plugin state - */ - private void callHome() { - if (!PVPArena.instance.getConfig().getBoolean("tracker", true)) { - stop(); - return; - } - debug.i("calling home..."); - - String url = null; - try { - url = String - .format("http://www.slipcor.net/stats/call.php?port=%s&name=%s&version=%s", - PVPArena.instance.getServer().getPort(), - URLEncoder.encode(PVPArena.instance.getDescription().getName(), "UTF-8"), - URLEncoder.encode(PVPArena.instance.getDescription().getVersion(), "UTF-8")); - } catch (final UnsupportedEncodingException e) { - e.printStackTrace(); - } - - try { - new URL(url).openConnection().getInputStream(); - } catch (final Exception e) { - PVPArena.instance.getLogger().warning("Error while connecting to www.slipcor.net"); - return; - } - debug.i("successfully called home!"); - } - - @Override - public void run() { - callHome(); - } - - /** - * start tracking - */ - public void start() { - Language.logInfo(MSG.LOG_TRACKER_ENABLED); - - timerTask = Bukkit.getScheduler().runTaskTimerAsynchronously(PVPArena.instance, this, - 0L, 72000L); - } - - /** - * stop tracking - */ - public static void stop() { - Language.logInfo(MSG.LOG_TRACKER_DISABLED); - if (timerTask != null) { - try { - timerTask.cancel(); - timerTask = null; - } catch (Exception e) { - - } - } - } -} From cb715fabb80c1e1f745cf9fc2ac7e8d40902d1c2 Mon Sep 17 00:00:00 2001 From: Eredrim Date: Wed, 24 Jun 2020 22:44:04 +0200 Subject: [PATCH 25/43] v1.15 - quick doc update for powerups mod --- doc/mods/powerups.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/mods/powerups.md b/doc/mods/powerups.md index ce75412b5..a3d5463fb 100644 --- a/doc/mods/powerups.md +++ b/doc/mods/powerups.md @@ -13,9 +13,10 @@ Unzip the module files (files tab, "PA Files v*.*.*") into the /pvparena/files f ## Setup -Sorry, but you have to add a freaking block to an arena config. An example is: +Sorry, but you have to add a freaking block to your arena config under `module.powerups.items`. Eg: -powerups: +```yaml +items: - Shield: - item: OBSIDIAN - dmg_receive: @@ -108,12 +109,13 @@ powerups: - repair: - items: helmet,chestplate,leggins,boots - factor: 0.2 +``` So the first layer defines the name, the second layer defines item and adds all the effects it has. This example features all possible ways of doing good and bad things, I hope it is clear oO ## Config settings -- dropspawn \- should the powerup spawn require defined spawns? `/pa [arena] spawn powerupX +- dropspawn \- should the powerup spawn require defined spawns? `/pa [arena] spawn powerupX` (where X is an integer) - usage \- by default it is "off", so please set this to either every X kills ("death:X") or every X seconds ("time:X") ## Commands From 6d858e3e318c08f5747c665ee92fb3f862c968b7 Mon Sep 17 00:00:00 2001 From: Eredrim Date: Thu, 25 Jun 2020 13:19:14 +0200 Subject: [PATCH 26/43] v1.15 - replace bukkit by spigot dependency --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index af3846444..ad8f4de22 100644 --- a/pom.xml +++ b/pom.xml @@ -26,8 +26,8 @@ - org.bukkit - bukkit + org.spigotmc + spigot-api 1.13.2-R0.1-SNAPSHOT jar provided From 05be1b732c86c3c83ecbd17fbabfd23cfd1c9e19 Mon Sep 17 00:00:00 2001 From: Eredrim Date: Thu, 25 Jun 2020 18:56:28 +0200 Subject: [PATCH 27/43] v1.15 - allow usage of "/pa arenaclass" command when player is in lounge --- src/net/slipcor/pvparena/commands/PAG_Arenaclass.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/net/slipcor/pvparena/commands/PAG_Arenaclass.java b/src/net/slipcor/pvparena/commands/PAG_Arenaclass.java index 6b5a0e5d9..8922c380d 100644 --- a/src/net/slipcor/pvparena/commands/PAG_Arenaclass.java +++ b/src/net/slipcor/pvparena/commands/PAG_Arenaclass.java @@ -22,6 +22,8 @@ import java.util.Set; import java.util.TreeSet; +import static net.slipcor.pvparena.arena.ArenaPlayer.Status.LOUNGE; + /** *

PVP Arena JOIN Command class
*

@@ -38,7 +40,7 @@ public PAG_Arenaclass() { @Override public void commit(final Arena arena, final CommandSender sender, final String[] args) { - if (!hasPerms(sender, arena) || !arena.getArenaConfig().getBoolean(CFG.USES_INGAMECLASSSWITCH)) { + if (!hasPerms(sender, arena)) { return; } @@ -65,6 +67,11 @@ public void commit(final Arena arena, final CommandSender sender, final String[] final ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(sender.getName()); + // Player can change arena class only in lounge or with ingameClassSwith parameter set to true + if(aPlayer.getStatus() != LOUNGE && !arena.getArenaConfig().getBoolean(CFG.USES_INGAMECLASSSWITCH)) { + return; + } + final ArenaClass aClass = arena.getClass(args[0]); if (aClass == null) { From e5c0e58e4c2af31c1f880de08a912ff4a1474213 Mon Sep 17 00:00:00 2001 From: Eredrim Date: Thu, 25 Jun 2020 19:52:31 +0200 Subject: [PATCH 28/43] v1.15 - fix players joining arenas on wrong command syntax --- src/net/slipcor/pvparena/PVPArena.java | 14 ++++---------- src/net/slipcor/pvparena/arena/Arena.java | 2 +- src/net/slipcor/pvparena/classes/PACheck.java | 14 +++++--------- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/net/slipcor/pvparena/PVPArena.java b/src/net/slipcor/pvparena/PVPArena.java index a7781ef19..d929bd324 100644 --- a/src/net/slipcor/pvparena/PVPArena.java +++ b/src/net/slipcor/pvparena/PVPArena.java @@ -367,20 +367,14 @@ public boolean onCommand(final CommandSender sender, final Command cmd, break; } } - if (paacmd == null - && PACheck.handleCommand(tempArena, sender, newArgs)) { + if (paacmd == null && PACheck.handleCommand(tempArena, sender, newArgs)) { return true; } - if (paacmd == null - && tempArena.getArenaConfig().getBoolean(CFG.CMDS_DEFAULTJOIN)) { + if (paacmd == null && tempArena.getArenaConfig().getBoolean(CFG.CMDS_DEFAULTJOIN) && args.length == 1) { paacmd = new PAG_Join(); - if (newArgs.length > 1) { - newArgs = StringParser.shiftArrayBy(newArgs, 1); - } - tempArena.getDebugger() - .i("committing: " + paacmd.getName(), sender); - paacmd.commit(tempArena, sender, newArgs); + tempArena.getDebugger().i("committing: " + paacmd.getName(), sender); + paacmd.commit(tempArena, sender, new String[0]); return true; } diff --git a/src/net/slipcor/pvparena/arena/Arena.java b/src/net/slipcor/pvparena/arena/Arena.java index 2cce050da..fb7b9a24d 100644 --- a/src/net/slipcor/pvparena/arena/Arena.java +++ b/src/net/slipcor/pvparena/arena/Arena.java @@ -794,7 +794,7 @@ public boolean isFightInProgress() { } public boolean isFreeForAll() { - return free; + return this.free; } public boolean isLocked() { diff --git a/src/net/slipcor/pvparena/classes/PACheck.java b/src/net/slipcor/pvparena/classes/PACheck.java index e3f2d5969..2cba17dd8 100644 --- a/src/net/slipcor/pvparena/classes/PACheck.java +++ b/src/net/slipcor/pvparena/classes/PACheck.java @@ -333,19 +333,20 @@ public static boolean handleJoin(final Arena arena, final ArenaTeam team; - if (args.length < 1 || arena.getTeam(args[0]) == null) { + if (args.length < 1) { // usage: /pa {arenaname} join | join an arena team = arena.getTeam(TeamManager.calcFreeTeam(arena)); + } else if(arena.getTeam(args[0]) == null) { + arena.msg(sender, Language.parse(arena, MSG.ERROR_TEAMNOTFOUND, args[0])); + return false; } else { ArenaTeam aTeam = arena.getTeam(args[0]); int maxPlayers = arena.getArenaConfig().getInt(CFG.READY_MAXPLAYERS); int maxTeamPlayers = arena.getArenaConfig().getInt(CFG.READY_MAXTEAMPLAYERS); - if (aTeam == null) { - team = aTeam; - } else if (maxPlayers > 0 && arena.getFighters().size() > maxPlayers) { + if (maxPlayers > 0 && arena.getFighters().size() > maxPlayers) { arena.msg(sender, Language.parse(arena, MSG.ERROR_JOIN_ARENA_FULL)); return false; } else if (maxTeamPlayers > 0 && aTeam.getTeamMembers().size() > maxTeamPlayers) { @@ -356,11 +357,6 @@ public static boolean handleJoin(final Arena arena, } } - if (team == null && args.length > 0) { - arena.msg(sender, - Language.parse(arena, MSG.ERROR_TEAMNOTFOUND, args[0])); - return false; - } if (team == null) { arena.msg(sender, Language.parse(arena, MSG.ERROR_JOIN_ARENA_FULL)); return false; From d0f218003ae28514867ef5b1f9651d817bad8e54 Mon Sep 17 00:00:00 2001 From: Eredrim Date: Mon, 29 Jun 2020 18:18:04 +0200 Subject: [PATCH 29/43] v1.15 - finalize tab completion system --- src/net/slipcor/pvparena/PVPArena.java | 13 ++++++--- .../pvparena/goals/GoalBlockDestroy.java | 7 ++--- src/net/slipcor/pvparena/goals/GoalFlags.java | 4 ++- src/net/slipcor/pvparena/goals/GoalFood.java | 2 +- .../pvparena/goals/GoalLiberation.java | 6 ++-- .../pvparena/goals/GoalPhysicalFlags.java | 4 ++- .../slipcor/pvparena/goals/GoalSabotage.java | 2 +- .../pvparena/managers/ArenaManager.java | 22 ++++++++++---- .../slipcor/pvparena/managers/TabManager.java | 29 +++++++++++-------- 9 files changed, 57 insertions(+), 32 deletions(-) diff --git a/src/net/slipcor/pvparena/PVPArena.java b/src/net/slipcor/pvparena/PVPArena.java index d929bd324..06898e6b8 100644 --- a/src/net/slipcor/pvparena/PVPArena.java +++ b/src/net/slipcor/pvparena/PVPArena.java @@ -6,15 +6,22 @@ import net.slipcor.pvparena.classes.PACheck; import net.slipcor.pvparena.commands.*; import net.slipcor.pvparena.core.Config.CFG; -import net.slipcor.pvparena.core.*; +import net.slipcor.pvparena.core.Debug; +import net.slipcor.pvparena.core.Help; +import net.slipcor.pvparena.core.Language; import net.slipcor.pvparena.core.Language.MSG; +import net.slipcor.pvparena.core.StringParser; import net.slipcor.pvparena.listeners.BlockListener; import net.slipcor.pvparena.listeners.EntityListener; import net.slipcor.pvparena.listeners.InventoryListener; import net.slipcor.pvparena.listeners.PlayerListener; -import net.slipcor.pvparena.loadables.*; +import net.slipcor.pvparena.loadables.ArenaGoalManager; +import net.slipcor.pvparena.loadables.ArenaModule; +import net.slipcor.pvparena.loadables.ArenaModuleManager; +import net.slipcor.pvparena.loadables.ArenaRegionShapeManager; import net.slipcor.pvparena.managers.ArenaManager; import net.slipcor.pvparena.managers.StatisticsManager; +import net.slipcor.pvparena.managers.TabManager; import net.slipcor.pvparena.updater.UpdateChecker; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; @@ -390,12 +397,10 @@ public boolean onCommand(final CommandSender sender, final Command cmd, return false; } - /* @Override public List onTabComplete(final CommandSender sender, final Command cmd, final String alias, final String[] args) { return TabManager.getMatches(sender, arenaCommands, globalCommands, args); } - */ @Override public void onDisable() { diff --git a/src/net/slipcor/pvparena/goals/GoalBlockDestroy.java b/src/net/slipcor/pvparena/goals/GoalBlockDestroy.java index 596513ec7..33da732e5 100644 --- a/src/net/slipcor/pvparena/goals/GoalBlockDestroy.java +++ b/src/net/slipcor/pvparena/goals/GoalBlockDestroy.java @@ -93,11 +93,10 @@ public PACheck checkCommand(final PACheck res, final String string) { @Override public List getMain() { - List result = Collections.singletonList("blocktype"); - if (arena != null) { - result = new ArrayList<>(); + List result = new ArrayList<>(); + if (this.arena != null) { result.add("blocktype"); - for (final ArenaTeam team : arena.getTeams()) { + for (final ArenaTeam team : this.arena.getTeams()) { final String sTeam = team.getName(); result.add(sTeam + "block"); } diff --git a/src/net/slipcor/pvparena/goals/GoalFlags.java b/src/net/slipcor/pvparena/goals/GoalFlags.java index 77f6fb580..d6f106994 100644 --- a/src/net/slipcor/pvparena/goals/GoalFlags.java +++ b/src/net/slipcor/pvparena/goals/GoalFlags.java @@ -42,6 +42,8 @@ import org.bukkit.util.Vector; import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; /** *

@@ -99,7 +101,7 @@ public PACheck checkCommand(final PACheck res, final String string) {
 
     @Override
     public List getMain() {
-        final List result = Arrays.asList("flagtype", "flageffect", TOUCHDOWN);
+        final List result = Stream.of("flagtype", "flageffect", TOUCHDOWN).collect(Collectors.toList());
         if (this.arena != null) {
             for (final ArenaTeam team : this.arena.getTeams()) {
                 final String sTeam = team.getName();
diff --git a/src/net/slipcor/pvparena/goals/GoalFood.java b/src/net/slipcor/pvparena/goals/GoalFood.java
index 1e12466e6..fc2e2c1ac 100644
--- a/src/net/slipcor/pvparena/goals/GoalFood.java
+++ b/src/net/slipcor/pvparena/goals/GoalFood.java
@@ -103,7 +103,7 @@ public PACheck checkCommand(final PACheck res, final String string) {
 
     @Override
     public List getMain() {
-        final List result = Arrays.asList(new String[0]);
+        final List result = new ArrayList<>();
         if (arena != null) {
             for (final ArenaTeam team : arena.getTeams()) {
                 final String sTeam = team.getName();
diff --git a/src/net/slipcor/pvparena/goals/GoalLiberation.java b/src/net/slipcor/pvparena/goals/GoalLiberation.java
index af4608dc7..09d751046 100644
--- a/src/net/slipcor/pvparena/goals/GoalLiberation.java
+++ b/src/net/slipcor/pvparena/goals/GoalLiberation.java
@@ -80,9 +80,9 @@ public PACheck checkCommand(final PACheck res, final String string) {
 
     @Override
     public List getMain() {
-        final List result = Arrays.asList(new String[0]);
-        if (arena != null) {
-            for (final ArenaTeam team : arena.getTeams()) {
+        final List result = new ArrayList<>();
+        if (this.arena != null) {
+            for (final ArenaTeam team : this.arena.getTeams()) {
                 final String sTeam = team.getName();
                 result.add(sTeam + "button");
             }
diff --git a/src/net/slipcor/pvparena/goals/GoalPhysicalFlags.java b/src/net/slipcor/pvparena/goals/GoalPhysicalFlags.java
index 8415fb1c2..a70793568 100644
--- a/src/net/slipcor/pvparena/goals/GoalPhysicalFlags.java
+++ b/src/net/slipcor/pvparena/goals/GoalPhysicalFlags.java
@@ -40,6 +40,8 @@
 import org.bukkit.util.Vector;
 
 import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import static java.util.Optional.ofNullable;
 
@@ -100,7 +102,7 @@ public PACheck checkCommand(final PACheck res, final String string) {
 
     @Override
     public List getMain() {
-        final List result = Arrays.asList("flagtype", "flageffect", TOUCHDOWN);
+        final List result = Stream.of("flagtype", "flageffect", TOUCHDOWN).collect(Collectors.toList());
         if (this.arena != null) {
             for (final ArenaTeam team : this.arena.getTeams()) {
                 final String sTeam = team.getName();
diff --git a/src/net/slipcor/pvparena/goals/GoalSabotage.java b/src/net/slipcor/pvparena/goals/GoalSabotage.java
index e9e891f42..81e09ee96 100644
--- a/src/net/slipcor/pvparena/goals/GoalSabotage.java
+++ b/src/net/slipcor/pvparena/goals/GoalSabotage.java
@@ -89,7 +89,7 @@ public PACheck checkCommand(final PACheck res, final String string) {
 
     @Override
     public List getMain() {
-        final List result = Arrays.asList(new String[0]);
+        final List result = new ArrayList<>();
         if (arena != null) {
             for (final ArenaTeam team : arena.getTeams()) {
                 final String sTeam = team.getName();
diff --git a/src/net/slipcor/pvparena/managers/ArenaManager.java b/src/net/slipcor/pvparena/managers/ArenaManager.java
index 5fb4c3059..cbfa8a2ae 100644
--- a/src/net/slipcor/pvparena/managers/ArenaManager.java
+++ b/src/net/slipcor/pvparena/managers/ArenaManager.java
@@ -185,6 +185,22 @@ public static Arena getArenaByName(final String name) {
         return null;
     }
 
+    public static Arena getArenaByExactName(final String name) {
+        if (name == null || name.isEmpty()) {
+            return null;
+        }
+        final String sName = name.toLowerCase();
+        final Arena arena = ARENAS.get(sName);
+        if (arena != null) {
+            return arena;
+        }
+        return ARENAS.entrySet().stream()
+                .filter(e -> name.equalsIgnoreCase(e.getKey()))
+                .findFirst()
+                .map(Map.Entry::getValue)
+                .orElse(null);
+    }
+
     /**
      * search the arenas by location
      *
@@ -243,11 +259,7 @@ public static Set getArenasByRegionLocation(
      * @return a Set of Arena
      */
     public static Set getArenas() {
-        final Set arenas = new HashSet<>();
-        for (final Arena a : ARENAS.values()) {
-            arenas.add(a);
-        }
-        return arenas;
+        return new HashSet<>(ARENAS.values());
     }
 
     /**
diff --git a/src/net/slipcor/pvparena/managers/TabManager.java b/src/net/slipcor/pvparena/managers/TabManager.java
index 32df6c243..ae18f7e0b 100644
--- a/src/net/slipcor/pvparena/managers/TabManager.java
+++ b/src/net/slipcor/pvparena/managers/TabManager.java
@@ -18,6 +18,9 @@
 import org.bukkit.potion.PotionEffectType;
 
 import java.util.*;
+import java.util.stream.Collectors;
+
+import static org.bukkit.util.StringUtil.startsWithIgnoreCase;
 
 public final class TabManager {
     private TabManager() {}
@@ -38,7 +41,7 @@ public static List getMatches(final CommandSender sender, final List getMatches(final CommandSender sender, final List(matches);
                 }
-                for (final Arena a : ArenaManager.getArenas()) {
-                    matches.add(a.getName());
-                }
-                return new ArrayList<>(matches);
+
+                final String search = args[0];
+                return ArenaManager.getArenas().stream()
+                        .filter(a -> startsWithIgnoreCase(a.getName(), search))
+                        .map(Arena::getName)
+                        .collect(Collectors.toList());
             }
         }
 
@@ -118,12 +123,12 @@ private static void addCommandsStartingWithPrefix(final Set matches, fin
         for (final IArenaCommandHandler ach : list) {
             if (ach.hasPerms(sender, arena)) {
                 for (final String value : ach.getMain()) {
-                    if (value.startsWith(prefix)) {
+                    if (startsWithIgnoreCase(value, prefix)) {
                         matches.add(value);
                     }
                 }
                 for (final String value : ach.getShort()) {
-                    if (value.startsWith(prefix)) {
+                    if (startsWithIgnoreCase(value, prefix)) {
                         matches.add(value);
                     }
                 }
@@ -140,7 +145,7 @@ private static void addCommandsStartingWithPrefix(final Set matches, fin
      */
     private static void addEnumMatchesToList(final List result, final String key, final List list) {
         for (final Enum e : list) {
-            if (e.name().startsWith(key)) {
+            if (startsWithIgnoreCase(e.name(), key)) {
                 result.add(e.name());
             }
         }
@@ -220,7 +225,7 @@ private static void addTreesMatchingValueInHandlerList(final List getKeyMatchesInsideDefinition(final String key, final String definition) {
         final List result = new ArrayList<>();
-        if (key != null && !key.isEmpty() && definition.startsWith(key) || key != null && key.isEmpty() && !definition.startsWith("{")) {
+        if (key != null && (!key.isEmpty() && startsWithIgnoreCase(definition, key) || key.isEmpty() && !definition.startsWith("{"))) {
             result.add(definition);
         }
         if (definition.startsWith("{")) {
@@ -235,7 +240,7 @@ private static List getKeyMatchesInsideDefinition(final String key, fina
                     }
                 } else if (key != null) {
                     for (final Player val : players) {
-                        if (val.getName().startsWith(key)) {
+                        if (startsWithIgnoreCase(val.getName(), key)) {
                             result.add(val.getName());
                         }
                     }
@@ -257,7 +262,7 @@ private static List getKeyMatchesInsideDefinition(final String key, fina
                     result.addAll(values);
                 } else if (key != null) {
                     for (final String val : values) {
-                        if (val.startsWith(key)) {
+                        if (startsWithIgnoreCase(val, key)) {
                             result.add(val);
                         }
                     }
@@ -270,7 +275,7 @@ private static List getKeyMatchesInsideDefinition(final String key, fina
                     }
                 } else if (key != null) {
                     for (final PotionEffectType val : pet) {
-                        if (val.getName().startsWith(key)) {
+                        if (startsWithIgnoreCase(val.getName(), key)) {
                             result.add(val.getName());
                         }
                     }

From 7ea197c7b2d5bb292b0ff1b5bef2c066d2b326c0 Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Tue, 30 Jun 2020 13:26:08 +0200
Subject: [PATCH 30/43] v1.15 - fix disabling region selector

---
 src/net/slipcor/pvparena/commands/PAA_Region.java | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/net/slipcor/pvparena/commands/PAA_Region.java b/src/net/slipcor/pvparena/commands/PAA_Region.java
index a0812ee69..39d2f297a 100644
--- a/src/net/slipcor/pvparena/commands/PAA_Region.java
+++ b/src/net/slipcor/pvparena/commands/PAA_Region.java
@@ -64,6 +64,7 @@ public void commit(final Arena arena, final CommandSender sender, final String[]
                 if (sender.getName().equals(selector)) {
                     arena.msg(sender, Language.parse(arena, MSG.ERROR_REGION_YOUSELECTEXIT));
                     selector = null;
+                    activeSelections.remove(sender.getName());
                 } else {
                     arena.msg(sender, Language.parse(arena, MSG.ERROR_REGION_YOUSELECT, arena.getName()));
                     arena.msg(sender, Language.parse(arena, MSG.ERROR_REGION_YOUSELECT2));

From 10fe613a5426b9d9668bee100a857bcc0b3889df Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Tue, 30 Jun 2020 22:27:40 +0200
Subject: [PATCH 31/43] v1.15 - centralize all mods management in one command

---
 lang/lang_en.yml                              |   8 +
 src/net/slipcor/pvparena/PVPArena.java        |   8 +-
 .../pvparena/commands/PAA_Install.java        | 173 -----------
 .../pvparena/commands/PAA_Modules.java        | 291 ++++++++++++++++++
 .../pvparena/commands/PAA_Uninstall.java      | 138 ---------
 .../slipcor/pvparena/commands/PAA_Update.java |  97 ------
 src/net/slipcor/pvparena/core/Language.java   |   5 +-
 .../pvparena/updater/ModulesUpdater.java      |  31 +-
 .../pvparena/updater/PluginUpdater.java       |   4 +-
 9 files changed, 336 insertions(+), 419 deletions(-)
 delete mode 100644 src/net/slipcor/pvparena/commands/PAA_Install.java
 create mode 100644 src/net/slipcor/pvparena/commands/PAA_Modules.java
 delete mode 100644 src/net/slipcor/pvparena/commands/PAA_Uninstall.java
 delete mode 100644 src/net/slipcor/pvparena/commands/PAA_Update.java

diff --git a/lang/lang_en.yml b/lang/lang_en.yml
index 5adb41b8a..df896e5df 100644
--- a/lang/lang_en.yml
+++ b/lang/lang_en.yml
@@ -627,6 +627,14 @@ nulang:
     clear: Inventories cleared!
   announce:
     arena: Arena is starting! Type /pa %1% to join!
+  updater:
+    plugin: PVP Arena
+    modules: PVP Arena modules pack
+    announce: '%1% %2% is now available ! Your version: %3%'
+    success: '%1% has been updated to %2%.'
+    restart: Restart your server to apply update.
+    downloading: 'Downloading %1%...'
+    downloaderror: 'Error while downloading %1%'
 lang:
   goal:
     blockdestroy:
diff --git a/src/net/slipcor/pvparena/PVPArena.java b/src/net/slipcor/pvparena/PVPArena.java
index 06898e6b8..abe7b95da 100644
--- a/src/net/slipcor/pvparena/PVPArena.java
+++ b/src/net/slipcor/pvparena/PVPArena.java
@@ -213,9 +213,7 @@ private void loadGlobalCommands() {
         globalCommands.add(new PAA_Debug());
         globalCommands.add(new PAA_Duty());
         globalCommands.add(new PAI_Help());
-        globalCommands.add(new PAA_Install());
-        globalCommands.add(new PAA_Uninstall());
-        globalCommands.add(new PAA_Update());
+        globalCommands.add(new PAA_Modules());
         globalCommands.add(new PAI_ArenaList());
         globalCommands.add(new PAI_Version());
     }
@@ -458,9 +456,9 @@ public void onEnable() {
 
         FileConfiguration cfg = getConfig();
         List toDelete = cfg.getStringList("todelete");
-        if (toDelete != null){
+        if (!toDelete.isEmpty()){
             for (String jar : toDelete) {
-                PAA_Uninstall.remove(jar);
+                PAA_Modules.remove(jar);
             }
             cfg.set("todelete", null);
             saveConfig();
diff --git a/src/net/slipcor/pvparena/commands/PAA_Install.java b/src/net/slipcor/pvparena/commands/PAA_Install.java
deleted file mode 100644
index 046539135..000000000
--- a/src/net/slipcor/pvparena/commands/PAA_Install.java
+++ /dev/null
@@ -1,173 +0,0 @@
-package net.slipcor.pvparena.commands;
-
-import net.slipcor.pvparena.PVPArena;
-import net.slipcor.pvparena.arena.Arena;
-import net.slipcor.pvparena.core.Help;
-import net.slipcor.pvparena.core.Help.HELP;
-import net.slipcor.pvparena.core.Language;
-import net.slipcor.pvparena.core.Language.MSG;
-import net.slipcor.pvparena.loadables.ArenaModule;
-import org.bukkit.Bukkit;
-import org.bukkit.ChatColor;
-import org.bukkit.command.CommandSender;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * 
- * PVP Arena INSTALL Command class
- * 
- *

- * A command to install modules - * - * @author slipcor - * @version v0.10.0 - */ - -public class PAA_Install extends AbstractGlobalCommand { - - public PAA_Install() { - super(new String[]{"pvparena.cmds.install"}); - } - - private static final File FILES_DIR = new File(PVPArena.instance.getDataFolder(),"/files/"); - - @Override - public void commit(final CommandSender sender, final String[] args) { - if (!hasPerms(sender)) { - return; - } - - if (!argCountValid(sender, args, new Integer[]{0, 1})) { - return; - } - - // pa install - // pa install ctf - - if (args.length == 0) { - listInstalled(sender); - return; - } - - Set modList = getModList(); - if (modList.size() == 0 || modList.contains(args[0].toLowerCase())) { - String modName = args[0].toLowerCase(); - if (download("pa_m_" + modName + ".jar")) { - PVPArena.instance.getAmm().reload(); - Arena.pmsg(sender, Language.parse(MSG.INSTALL_DONE, modName)); - } else { - Arena.pmsg(sender, Language.parse(MSG.ERROR_INSTALL, modName)); - } - } - } - - public static Set listInstalled(final CommandSender sender) { - Arena.pmsg(sender, "--- PVP Arena Version Update information ---"); - Arena.pmsg(sender, "[" + ChatColor.GRAY + "uninstalled" + ChatColor.RESET + " | " + ChatColor.YELLOW + "installed" + ChatColor.RESET + "]"); - Arena.pmsg(sender, ChatColor.GREEN + "--- Installed Arena Mods ---->"); - Set modList = new HashSet<>(); - - for (final String modName : getModList()) { - final ArenaModule mod = PVPArena.instance.getAmm().getModByName(modName); - Arena.pmsg(sender, (mod != null ? ChatColor.YELLOW : ChatColor.GRAY) + modName + ChatColor.RESET); - } - return modList; - } - - private static Set getModList() { - Set modList = new HashSet<>(); - for (final File file : FILES_DIR.listFiles()) { - final String fileName = file.getName(); - if (fileName.startsWith("pa_m_") && fileName.endsWith(".jar")) { - String modName = fileName.substring(5, fileName.length() - 4); - modList.add(modName); - } - } - return modList; - } - - private boolean download(final String file) { - return download(file, false); - } - - private boolean download(final String file, final boolean silent) { - - final File source = new File(FILES_DIR, file); - - if (!source.exists()) { - if (!silent) { - Arena.pmsg( - Bukkit.getConsoleSender(), - ChatColor.COLOR_CHAR + "cFile '" + ChatColor.COLOR_CHAR + 'r' - + file - + ChatColor.COLOR_CHAR + "c' not found. Please extract the file to /files before trying to install!"); - } - return false; - } - - String folder = "/mods/"; - - try { - final File destination = new File(PVPArena.instance.getDataFolder() - .getPath() + folder + '/' + file); - final FileInputStream stream = new FileInputStream(source); - - final ByteArrayOutputStream baos = new ByteArrayOutputStream(); - final byte[] buffer = new byte[8192]; - int bytesRead; - while ((bytesRead = stream.read(buffer)) > 0) { - baos.write(buffer, 0, bytesRead); - } - - final FileOutputStream fos = new FileOutputStream(destination); - fos.write(baos.toByteArray()); - fos.close(); - - PVPArena.instance.getLogger().info("Installed module " + file); - stream.close(); - return true; - } catch (final Exception e) { - e.printStackTrace(); - } - return false; - } - - @Override - public String getName() { - return getClass().getName(); - } - - @Override - public void displayHelp(final CommandSender sender) { - Arena.pmsg(sender, Help.parse(HELP.INSTALL)); - } - - @Override - public List getMain() { - return Collections.singletonList("install"); - } - - @Override - public List getShort() { - return Collections.singletonList("!i"); - } - - @Override - public CommandTree getSubs(final Arena nothing) { - final CommandTree result = new CommandTree<>(null); - - Set modList = getModList(); - for (final String key : modList) { - result.define(new String[]{key}); - } - return result; - } -} diff --git a/src/net/slipcor/pvparena/commands/PAA_Modules.java b/src/net/slipcor/pvparena/commands/PAA_Modules.java new file mode 100644 index 000000000..f2b742a63 --- /dev/null +++ b/src/net/slipcor/pvparena/commands/PAA_Modules.java @@ -0,0 +1,291 @@ +package net.slipcor.pvparena.commands; + +import net.slipcor.pvparena.PVPArena; +import net.slipcor.pvparena.arena.Arena; +import net.slipcor.pvparena.core.Help; +import net.slipcor.pvparena.core.Help.HELP; +import net.slipcor.pvparena.core.Language; +import net.slipcor.pvparena.core.Language.MSG; +import net.slipcor.pvparena.loadables.ArenaModule; +import net.slipcor.pvparena.ncloader.NCBLoadable; +import net.slipcor.pvparena.updater.ModulesUpdater; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.FileConfiguration; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.*; + +/** + *

+ * PVP Arena MODULES Command class
+ * 
+ *

+ * A command to manage modules (list, install, uninstall, update, download and upgrade) + * + * @author Eredrim + * @version v1.15 + */ + +public class PAA_Modules extends AbstractGlobalCommand { + + public PAA_Modules() { + super(new String[]{"pvparena.cmds.modules"}); + } + + private static final File FILES_DIR = new File(PVPArena.instance.getDataFolder(),"/files/"); + private static final File MODS_DIR = new File(PVPArena.instance.getDataFolder(),"/mods/"); + + @Override + public void commit(final CommandSender sender, final String[] args) { + if (!this.hasPerms(sender)) { + return; + } + + if (!argCountValid(sender, args, new Integer[]{0, 1, 2})) { + return; + } + + // pa modules + if (args.length == 0) { + listModules(sender); + } else if (args.length == 1) { + switch (args[0]) { + case "list": + listModules(sender); + break; + case "update": + updateModules(sender); + break; + case "download": + ModulesUpdater.downloadModulePack(sender); + break; + case "upgrade": + ModulesUpdater.downloadModulePack(sender); + updateModules(sender); + break; + case "install": + case "uninstall": + Arena.pmsg(sender, Language.parse(MSG.ERROR_INVALID_ARGUMENT_COUNT, "1", "2")); + break; + default: + // Show specific help + } + } else { // 2 args only (if more args, caught above) + if("install".equalsIgnoreCase(args[0])) { + installModule(sender, args[1]); + } else if ("uninstall".equalsIgnoreCase(args[0])) { + uninstallModule(sender, args[1]); + } else { + Arena.pmsg(sender, Language.parse(MSG.ERROR_INVALID_ARGUMENT_COUNT, "2", "1")); + } + } + } + + /** + * List all modules status to sender + * @param sender User who typed the command + */ + private static void listModules(final CommandSender sender) { + Arena.pmsg(sender, "--- PVP Arena Version Update information ---"); + Arena.pmsg(sender, "[" + ChatColor.GRAY + "uninstalled" + ChatColor.RESET + " | " + ChatColor.YELLOW + "installed" + ChatColor.RESET + "]"); + Arena.pmsg(sender, ChatColor.GREEN + "--- Installed Arena Mods ---->"); + + for (final String modName : getModInFilesFolder()) { + final ArenaModule mod = PVPArena.instance.getAmm().getModByName(modName); + Arena.pmsg(sender, (mod != null ? ChatColor.YELLOW : ChatColor.GRAY) + modName + ChatColor.RESET); + } + } + + /** + * Install a module (copying from /files to /mods) + * @param sender User who typed the command + * @param name Module named typed by user + */ + private static void installModule(CommandSender sender, String name) { + Set modList = getModInFilesFolder(); + String modName = name.toLowerCase(); + if (modList.size() != 0 && modList.contains(modName)) { + + if (copyFile("pa_m_" + modName + ".jar")) { + PVPArena.instance.getAmm().reload(); + Arena.pmsg(sender, Language.parse(MSG.INSTALL_DONE, modName)); + } else { + Arena.pmsg(sender, Language.parse(MSG.ERROR_INSTALL, modName)); + } + } else { + Arena.pmsg(sender, Language.parse(MSG.ERROR_UNKNOWN_MODULE, name)); + } + } + + /** + * Uninstall a module + * Unload it and remove it from /mods directory + * @param sender User who typed the command + * @param name Module named typed by user + */ + private static void uninstallModule(CommandSender sender, String name) { + final ArenaModule mod = PVPArena.instance.getAmm().getModByName(name); + if (mod != null) { + String modName = mod.getName(); + String jarName = "pa_m_" + modName.toLowerCase() + ".jar"; + if (remove(jarName)) { + PVPArena.instance.getAmm().reload(); + Arena.pmsg(sender, Language.parse(MSG.UNINSTALL_DONE, modName)); + } else { + Arena.pmsg(sender, Language.parse(MSG.ERROR_UNINSTALL, modName)); + FileConfiguration cfg = PVPArena.instance.getConfig(); + List toDelete = cfg.getStringList("todelete"); + toDelete.add(jarName); + cfg.set("todelete", toDelete); + PVPArena.instance.saveConfig(); + Arena.pmsg(sender, Language.parse(MSG.ERROR_UNINSTALL2)); + } + } + } + + /** + * Replace all modules of /mods directory by ones of /files directory + * @param sender User who typed the command + */ + private static void updateModules(CommandSender sender) { + final Set modules = new HashSet<>(PVPArena.instance.getAmm().getAllMods()); + + modules.stream() + .filter(mod -> !mod.isInternal()) + .forEach(mod -> { + final File jarFile = new File(FILES_DIR, "pa_m_" + mod.getName().toLowerCase() + ".jar"); + + if (jarFile.exists()) { + uninstallModule(sender, mod.getName()); + installModule(sender, mod.getName()); + } + }); + } + + /** + * List all mods in /files folder + * @return List of mod names + */ + private static Set getModInFilesFolder() { + Set modList = new HashSet<>(); + for (final File file : FILES_DIR.listFiles()) { + final String fileName = file.getName(); + if (fileName.startsWith("pa_m_") && fileName.endsWith(".jar")) { + String modName = fileName.substring(5, fileName.length() - 4); + modList.add(modName); + } + } + return modList; + } + + /** + * Copy a file from /files folder to /mod folder + * @param file file name + * @return true if install was successful + */ + private static boolean copyFile(final String file) { + + final File source = new File(FILES_DIR, file); + + if (!source.exists()) { + Arena.pmsg( + Bukkit.getConsoleSender(), + String.format("%sFile '%s%s%s' not found. Please extract the file to /files before trying to install!", ChatColor.RED, ChatColor.RESET, file, ChatColor.RED)); + return false; + } + + try { + final File destination = new File(MODS_DIR, file); + final FileInputStream stream = new FileInputStream(source); + + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final byte[] buffer = new byte[8192]; + int bytesRead; + while ((bytesRead = stream.read(buffer)) > 0) { + baos.write(buffer, 0, bytesRead); + } + + final FileOutputStream fos = new FileOutputStream(destination); + fos.write(baos.toByteArray()); + fos.close(); + + PVPArena.instance.getLogger().info("Installed module " + file); + stream.close(); + return true; + } catch (final Exception e) { + e.printStackTrace(); + } + return false; + } + + /** + * Remove a mod from /mods folder + * @param file module file name + * @return true if deletion was successful + */ + public static boolean remove(final String file) { + if (!MODS_DIR.exists()) { + PVPArena.instance.getLogger().severe("unable to fetch file: " + file); + return false; + } + + final File destFile = new File(MODS_DIR, file); + + boolean exists = destFile.exists(); + boolean deleted = false; + if (exists) { + deleted = destFile.delete(); + if (!deleted) { + PVPArena.instance.getLogger().severe("could not delete file: " + file); + } + } else { + PVPArena.instance.getLogger().warning("file does not exist: " + file); + } + + return exists && deleted; + } + + @Override + public String getName() { + return this.getClass().getName(); + } + + @Override + public void displayHelp(final CommandSender sender) { + Arena.pmsg(sender, Help.parse(HELP.INSTALL)); + } + + @Override + public List getMain() { + return Collections.singletonList("modules"); + } + + @Override + public List getShort() { + return Collections.singletonList("!m"); + } + + @Override + public CommandTree getSubs(final Arena nothing) { + final CommandTree result = new CommandTree<>(null); + + result.define(new String[]{"download"}); + result.define(new String[]{"list"}); + result.define(new String[]{"update"}); + result.define(new String[]{"upgrade"}); + + getModInFilesFolder().forEach(modName -> result.define(new String[]{"install", modName})); + + PVPArena.instance.getAmm().getAllMods().stream() + .filter(mod -> !mod.isInternal()) + .map(ArenaModule::getName) + .forEach(modName -> result.define(new String[]{"uninstall", modName})); + + return result; + } +} diff --git a/src/net/slipcor/pvparena/commands/PAA_Uninstall.java b/src/net/slipcor/pvparena/commands/PAA_Uninstall.java deleted file mode 100644 index 63389963f..000000000 --- a/src/net/slipcor/pvparena/commands/PAA_Uninstall.java +++ /dev/null @@ -1,138 +0,0 @@ -package net.slipcor.pvparena.commands; - -import net.slipcor.pvparena.PVPArena; -import net.slipcor.pvparena.arena.Arena; -import net.slipcor.pvparena.core.Help; -import net.slipcor.pvparena.core.Help.HELP; -import net.slipcor.pvparena.core.Language; -import net.slipcor.pvparena.core.Language.MSG; -import net.slipcor.pvparena.loadables.ArenaModule; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - *

PVP Arena UNINSTALL Command class
- *

- * A command to uninstall modules - * - * @author slipcor - * @version v0.10.0 - */ - -public class PAA_Uninstall extends AbstractGlobalCommand { - - public PAA_Uninstall() { - super(new String[]{"pvparena.cmds.uninstall"}); - } - - @Override - public void commit(final CommandSender sender, final String[] args) { - if (!hasPerms(sender)) { - return; - } - - if (!argCountValid(sender, args, - new Integer[]{0, 1})) { - return; - } - - // pa install - // pa install ctf - - final YamlConfiguration config = new YamlConfiguration(); - try { - config.load(PVPArena.instance.getDataFolder().getPath() + "/install.yml"); - } catch (final Exception e) { - } - - if (args.length == 0 || config.get(args[0]) != null) { - PAA_Install.listInstalled(sender); - return; - } - - final String name = args[0].toLowerCase(); - final ArenaModule mod = PVPArena.instance.getAmm().getModByName(name); - if (mod != null) { - if (remove("pa_m_" + mod.getName().toLowerCase() + ".jar")) { - PVPArena.instance.getAmm().reload(); - Arena.pmsg(sender, Language.parse(MSG.UNINSTALL_DONE, mod.getName())); - return; - } - Arena.pmsg(sender, Language.parse(MSG.ERROR_UNINSTALL, mod.getName())); - FileConfiguration cfg = PVPArena.instance.getConfig(); - List toDelete = cfg.getStringList("todelete"); - if (toDelete == null){ - toDelete = new ArrayList<>(); - } - toDelete.add("pa_m_" + mod.getName().toLowerCase() + ".jar"); - cfg.set("todelete", toDelete); - PVPArena.instance.saveConfig(); - Arena.pmsg(sender, Language.parse(MSG.ERROR_UNINSTALL2)); - } - } - - @Override - public String getName() { - return getClass().getName(); - } - - public static boolean remove(final String file) { - String folder = null; - if (file.startsWith("pa_g")) { - folder = "/goals/"; - } else if (file.startsWith("pa_m")) { - folder = "/mods/"; - } - if (folder == null) { - PVPArena.instance.getLogger().severe("unable to fetch file: " + file); - return false; - } - final File destination = new File(PVPArena.instance.getDataFolder().getPath() - + folder); - - final File destFile = new File(destination, file); - - boolean exists = destFile.exists(); - boolean deleted = false; - if (exists) { - deleted = destFile.delete(); - if (!deleted) { - PVPArena.instance.getLogger().severe("could not delete file: " + file); - } - } else { - PVPArena.instance.getLogger().warning("file does not exist: " + file); - } - - return exists && deleted; - } - - @Override - public void displayHelp(final CommandSender sender) { - Arena.pmsg(sender, Help.parse(HELP.UNINSTALL)); - } - - @Override - public List getMain() { - return Collections.singletonList("uninstall"); - } - - @Override - public List getShort() { - return Collections.singletonList("!ui"); - } - - @Override - public CommandTree getSubs(final Arena nothing) { - final CommandTree result = new CommandTree<>(null); - for (final ArenaModule mod : PVPArena.instance.getAmm().getAllMods()) { - result.define(new String[]{mod.getName()}); - } - return result; - } -} diff --git a/src/net/slipcor/pvparena/commands/PAA_Update.java b/src/net/slipcor/pvparena/commands/PAA_Update.java deleted file mode 100644 index 690a3ffdc..000000000 --- a/src/net/slipcor/pvparena/commands/PAA_Update.java +++ /dev/null @@ -1,97 +0,0 @@ -package net.slipcor.pvparena.commands; - -import net.slipcor.pvparena.PVPArena; -import net.slipcor.pvparena.arena.Arena; -import net.slipcor.pvparena.core.Help; -import net.slipcor.pvparena.core.Help.HELP; -import net.slipcor.pvparena.loadables.ArenaModule; -import net.slipcor.pvparena.ncloader.NCBLoadable; -import org.bukkit.command.CommandSender; - -import java.io.File; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -/** - *

PVP Arena UPDATE Command class
- *

- * A command to update modules - * - * @author slipcor - * @version v0.10.0 - */ - -public class PAA_Update extends AbstractGlobalCommand { - - public PAA_Update() { - super(new String[]{"pvparena.cmds.update"}); - } - - @Override - public void commit(final CommandSender sender, final String[] args) { - if (!hasPerms(sender)) { - return; - } - - final Set modules = new HashSet(PVPArena.instance.getAmm().getAllMods()); - - if (!modules.isEmpty()) { - for (final NCBLoadable mod : modules) { - if (mod.isInternal()) { - continue; - } - - final File destination = new File(PVPArena.instance.getDataFolder().getPath() - + "/files/"); - final File destFileM = new File(destination, "pa_m_" + mod.getName().toLowerCase() + ".jar"); - - if (!destFileM.exists()) { - continue; - } - - final PAA_Uninstall uninstall = new PAA_Uninstall(); - if (!uninstall.hasPerms(sender)) { - return; - } - uninstall.commit(sender, new String[]{mod.getName()}); - final PAA_Install install = new PAA_Install(); - if (!install.hasPerms(sender)) { - return; - } - install.commit(sender, new String[]{mod.getName()}); - } - } - } - - - @Override - public String getName() { - return getClass().getName(); - } - - @Override - public void displayHelp(final CommandSender sender) { - Arena.pmsg(sender, Help.parse(HELP.UPDATE)); - } - - @Override - public List getMain() { - return Collections.singletonList("update"); - } - - @Override - public List getShort() { - return Collections.singletonList("!u"); - } - - @Override - public CommandTree getSubs(final Arena nothing) { - final CommandTree result = new CommandTree<>(null); - for (final ArenaModule mod : PVPArena.instance.getAmm().getAllMods()) { - result.define(new String[]{mod.getName()}); - } - return result; - } -} diff --git a/src/net/slipcor/pvparena/core/Language.java b/src/net/slipcor/pvparena/core/Language.java index 398c5f6b6..721b575af 100644 --- a/src/net/slipcor/pvparena/core/Language.java +++ b/src/net/slipcor/pvparena/core/Language.java @@ -466,7 +466,10 @@ public enum MSG { UPDATER_PLUGIN("nulang.updater.plugin", "PVP Arena"), UPDATER_MODULES("nulang.updater.modules", "PVP Arena modules pack"), UPDATER_ANNOUNCE("nulang.updater.announce", "%1% %2% is now available ! Your version: %3%"), - UPDATER_SUCCESS("nulang.updater.success", "%1% has been updated to %2%. Restart your server to apply update."), + UPDATER_SUCCESS("nulang.updater.success", "%1% has been updated to %2%."), + UPDATER_RESTART("nulang.updater.restart", "Restart your server to apply update."), + UPDATER_DOWNLOADING("nulang.updater.downloading", "Downloading %1%..."), + UPDATER_DOWNLOAD_ERROR("nulang.updater.downloaderror", "Error while downloading %1%"), WHITELIST_ADDED("nulang.whitelist.added", "Added &a%1%&r to &e%2%&r whitelist!"), WHITELIST_ALLCLEARED("nulang.whitelist.allcleared", "All whitelists cleared!"), diff --git a/src/net/slipcor/pvparena/updater/ModulesUpdater.java b/src/net/slipcor/pvparena/updater/ModulesUpdater.java index 0a036898e..18c61dc84 100644 --- a/src/net/slipcor/pvparena/updater/ModulesUpdater.java +++ b/src/net/slipcor/pvparena/updater/ModulesUpdater.java @@ -2,6 +2,9 @@ import com.google.gson.JsonObject; import net.slipcor.pvparena.PVPArena; +import net.slipcor.pvparena.arena.Arena; +import net.slipcor.pvparena.core.Language; +import org.bukkit.command.CommandSender; import java.io.File; import java.io.FileOutputStream; @@ -54,7 +57,7 @@ protected void runUpdater() throws IOException { String filename = getFilenameFromJson(versionJson); LOG.info("Downloading modules update..."); try { - this.downloadAndUnpackModules(getDownloadUrlFromJson(versionJson), filename); + downloadAndUnpackModules(getDownloadUrlFromJson(versionJson), filename); String updateSuccess = getSuccessMessage(MSG.UPDATER_MODULES.toString(), onlineVersion); LOG.info(updateSuccess); this.updateMsgList.add(updateSuccess); @@ -66,6 +69,26 @@ protected void runUpdater() throws IOException { } } + public static void downloadModulePack(CommandSender sender) { + try { + URL githubApi = new URL(API_URL); + URLConnection connection = githubApi.openConnection(); + JsonObject versionJson = getVersionJson(connection.getInputStream()); + String onlineVersion = getOnlineVersionFromJson(versionJson); + String filename = getFilenameFromJson(versionJson); + + Arena.pmsg(sender, Language.parse(MSG.UPDATER_DOWNLOADING, Language.parse(MSG.UPDATER_MODULES))); + downloadAndUnpackModules(getDownloadUrlFromJson(versionJson), filename); + String updateSuccess = getSuccessMessage(MSG.UPDATER_MODULES.toString(), onlineVersion); + LOG.info(updateSuccess); + } catch (IOException e) { + String errorMsg = Language.parse(MSG.UPDATER_DOWNLOAD_ERROR, Language.parse(MSG.UPDATER_MODULES)); + Arena.pmsg(sender, errorMsg); + LOG.warning(errorMsg); + e.printStackTrace(); + } + } + /** * Get current modules version based on version.lock * @return version string (x.x.x format) @@ -89,7 +112,7 @@ private String getModulesVersion() { * @param filename Packge file name * @throws IOException */ - private void downloadAndUnpackModules(String downloadUrlStr, String filename) throws IOException { + private static void downloadAndUnpackModules(String downloadUrlStr, String filename) throws IOException { URL downloadUrl = new URL(downloadUrlStr); File dataFolder = PVPArena.instance.getDataFolder(); File zipFile = new File(dataFolder, filename); @@ -100,7 +123,7 @@ private void downloadAndUnpackModules(String downloadUrlStr, String filename) th FileOutputStream outputStream = new FileOutputStream(zipFile); outputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE); outputStream.close(); - deleteDirectory(this.getFilesFolder()); + deleteDirectory(getFilesFolder()); ZipUtil.unzip(zipFile, dataFolder); zipFile.delete(); } @@ -109,7 +132,7 @@ private void downloadAndUnpackModules(String downloadUrlStr, String filename) th * Returns PVP Arena "files" folder * @return "files" folder */ - private File getFilesFolder() { + private static File getFilesFolder() { return new File(PVPArena.instance.getDataFolder().getPath() + "/files"); } diff --git a/src/net/slipcor/pvparena/updater/PluginUpdater.java b/src/net/slipcor/pvparena/updater/PluginUpdater.java index d4f250ba0..515998886 100644 --- a/src/net/slipcor/pvparena/updater/PluginUpdater.java +++ b/src/net/slipcor/pvparena/updater/PluginUpdater.java @@ -2,6 +2,7 @@ import com.google.gson.JsonObject; import net.slipcor.pvparena.PVPArena; +import net.slipcor.pvparena.core.Language; import org.bukkit.Bukkit; import java.io.File; @@ -56,7 +57,8 @@ protected void runUpdater() throws IOException { LOG.info("Downloading update..."); try { downloadPlugin(getDownloadUrlFromJson(versionJson), filename); - String updateSuccess = getSuccessMessage(MSG.UPDATER_PLUGIN.toString(), onlineVersion); + String updateSuccess = getSuccessMessage(MSG.UPDATER_PLUGIN.toString(), onlineVersion) + " " + + Language.parse(MSG.UPDATER_RESTART); LOG.info(updateSuccess); this.updateMsgList.add(updateSuccess); this.planPluginRenaming(filename); From 4f6bf89951041f12dfb6bd03177ab0101b2f9750 Mon Sep 17 00:00:00 2001 From: Eredrim Date: Thu, 2 Jul 2020 22:33:54 +0200 Subject: [PATCH 32/43] v1.15 - fix several issues with tab command completion --- lang/lang_en.yml | 4 +- lang/lang_fr.yml | 4 +- src/net/slipcor/pvparena/PVPArena.java | 60 ++---------- .../commands/AbstractGlobalCommand.java | 8 ++ .../pvparena/commands/PAA_ReloadAll.java | 96 +++++++++++++++++++ .../pvparena/commands/PAI_ArenaList.java | 5 + .../pvparena/commands/PAI_GlobalStats.java | 73 ++++++++++++++ src/net/slipcor/pvparena/core/Language.java | 4 +- .../slipcor/pvparena/managers/TabManager.java | 86 ++++++++--------- 9 files changed, 235 insertions(+), 105 deletions(-) create mode 100644 src/net/slipcor/pvparena/commands/PAA_ReloadAll.java create mode 100644 src/net/slipcor/pvparena/commands/PAI_GlobalStats.java diff --git a/lang/lang_en.yml b/lang/lang_en.yml index df896e5df..e65ae4662 100644 --- a/lang/lang_en.yml +++ b/lang/lang_en.yml @@ -210,7 +210,6 @@ nulang: enable: use the enable command gamemode: use the gamemode command goal: use the goal command - install: use the install command playerclass: use the playerclass command playerjoin: use the playerjoin command protection: use the protection command @@ -231,8 +230,7 @@ nulang: teleport: use the teleport command template: use the template command togglemod: use the togglemod command - uninstall: use the uninstall command - update: use the update command + modules: use the modules command whitelist: use the whitelist command arenaclass: use the arenaclass command chat: use the chat command diff --git a/lang/lang_fr.yml b/lang/lang_fr.yml index 6c65dc79f..dbe002ee7 100644 --- a/lang/lang_fr.yml +++ b/lang/lang_fr.yml @@ -222,7 +222,6 @@ nulang: enable: d'utiliser la commande enable gamemode: d'utiliser la commande gamemode goal: d'utiliser la commande goal - install: d'utiliser la commande install playerclass: d'utiliser la commande playerclass playerjoin: d'utiliser la commande playerjoin protection: d'utiliser la commande protection @@ -243,8 +242,7 @@ nulang: teleport: d'utiliser la commande teleport template: d'utiliser la commande template togglemod: d'utiliser la commande togglemod - uninstall: d'utiliser la commande uninstall - update: d'utiliser la commande update + modules: d'utiliser la commande modules whitelist: d'utiliser la commande whitelist arenaclass: d'utiliser la commande arenaclass chat: d'utiliser la commande chat diff --git a/src/net/slipcor/pvparena/PVPArena.java b/src/net/slipcor/pvparena/PVPArena.java index abe7b95da..1ea210cde 100644 --- a/src/net/slipcor/pvparena/PVPArena.java +++ b/src/net/slipcor/pvparena/PVPArena.java @@ -50,7 +50,7 @@ public class PVPArena extends JavaPlugin { public static PVPArena instance; - private static Debug DEBUG; + private static Debug debugger; private ArenaGoalManager agm; private ArenaModuleManager amm; @@ -206,15 +206,18 @@ private void loadArenaCommands() { arenaCommands.add(new PAI_Shutup()); arenaCommands.add(new PAG_Arenaclass()); arenaCommands.add(new PAI_Info()); + arenaCommands.add(new PAI_Stats()); } private void loadGlobalCommands() { globalCommands.add(new PAA_Create()); globalCommands.add(new PAA_Debug()); globalCommands.add(new PAA_Duty()); - globalCommands.add(new PAI_Help()); globalCommands.add(new PAA_Modules()); + globalCommands.add(new PAA_ReloadAll()); globalCommands.add(new PAI_ArenaList()); + globalCommands.add(new PAI_GlobalStats()); + globalCommands.add(new PAI_Help()); globalCommands.add(new PAI_Version()); } @@ -259,59 +262,12 @@ public boolean onCommand(final CommandSender sender, final Command cmd, } } final ArenaPlayer player = ArenaPlayer.parsePlayer(sender.getName()); - if (pacmd != null - && !(player.getArena() != null && pacmd.getName() - .contains("PAI_ArenaList"))) { - DEBUG.i("committing: " + pacmd.getName(), sender); + if (pacmd != null && !(player.getArena() != null && pacmd.hasVersionForArena())) { + debugger.i("committing: " + pacmd.getName(), sender); pacmd.commit(sender, StringParser.shiftArrayBy(args, 1)); return true; } - if ("-s".equalsIgnoreCase(args[0]) || "stats".equalsIgnoreCase(args[0])) { - final PAI_Stats scmd = new PAI_Stats(); - DEBUG.i("committing: " + scmd.getName(), sender); - scmd.commit(null, sender, StringParser.shiftArrayBy(args, 1)); - return true; - } - if (args.length > 1 - && (args[1].equalsIgnoreCase("-s") || args[1] - .equalsIgnoreCase("stats"))) { - final PAI_Stats scmd = new PAI_Stats(); - DEBUG.i("committing: " + scmd.getName(), sender); - scmd.commit(ArenaManager.getIndirectArenaByName(sender, args[0]), sender, - StringParser.shiftArrayBy(args, 2)); - return true; - } - if (args[0].equalsIgnoreCase("!rl") - || args[0].toLowerCase().contains("reload")) { - final PAA_Reload scmd = new PAA_Reload(); - DEBUG.i("committing: " + scmd.getName(), sender); - - this.reloadConfig(); - - Language.init(getConfig().getString("language", "en")); - Help.init(getConfig().getString("language", "en")); - - if (args.length > 1 && args[1].equalsIgnoreCase("ymls")) { - Arena.pmsg(sender, Language.parse(MSG.RELOAD_YMLS_DONE)); - return true; - } - - final String[] emptyArray = new String[0]; - - for (Arena a : ArenaManager.getArenas()) { - scmd.commit(a, sender, emptyArray); - } - - ArenaManager.load_arenas(); - if (getConfig().getBoolean("use_shortcuts") || - getConfig().getBoolean("only_shortcuts")) { - ArenaManager.readShortcuts(getConfig().getConfigurationSection("shortcuts")); - } - - return true; - } - Arena tempArena = "l".equalsIgnoreCase(args[0])?player.getArena():ArenaManager.getIndirectArenaByName(sender, args[0]); final String name = args[0]; @@ -413,7 +369,7 @@ public void onDisable() { public void onEnable() { shuttingDown = false; instance = this; - DEBUG = new Debug(1); + debugger = new Debug(1); //Enable bStats Metrics metrics = new Metrics(this); diff --git a/src/net/slipcor/pvparena/commands/AbstractGlobalCommand.java b/src/net/slipcor/pvparena/commands/AbstractGlobalCommand.java index b3bd5e20b..259359d43 100644 --- a/src/net/slipcor/pvparena/commands/AbstractGlobalCommand.java +++ b/src/net/slipcor/pvparena/commands/AbstractGlobalCommand.java @@ -47,6 +47,14 @@ static boolean argCountValid(final CommandSender sender, final String[] args, public abstract String getName(); + /** + * Check if the global command also exists in arena context + * @return true if there is the same command for arena context + */ + public boolean hasVersionForArena() { + return false; + } + @Override public boolean hasPerms(final CommandSender sender, final Arena arena) { // tabComplete check diff --git a/src/net/slipcor/pvparena/commands/PAA_ReloadAll.java b/src/net/slipcor/pvparena/commands/PAA_ReloadAll.java new file mode 100644 index 000000000..3e751d230 --- /dev/null +++ b/src/net/slipcor/pvparena/commands/PAA_ReloadAll.java @@ -0,0 +1,96 @@ +package net.slipcor.pvparena.commands; + +import net.slipcor.pvparena.PVPArena; +import net.slipcor.pvparena.arena.Arena; +import net.slipcor.pvparena.core.Help; +import net.slipcor.pvparena.core.Help.HELP; +import net.slipcor.pvparena.core.Language; +import net.slipcor.pvparena.managers.ArenaManager; +import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.FileConfiguration; + +import java.util.Collections; +import java.util.List; + +/** + *

PVP Arena DEBUG Command class
+ *

+ * A command to toggle debugging + * + * @author slipcor + * @version v0.10.0 + */ + +public class PAA_ReloadAll extends AbstractGlobalCommand { + + public PAA_ReloadAll() { + super(new String[]{"pvparena.cmds.reload"}); + } + + @Override + public void commit(final CommandSender sender, final String[] args) { + if (!hasPerms(sender)) { + return; + } + + if (!argCountValid(sender, args, new Integer[]{0, 1})) { + return; + } + + final PAA_Reload scmd = new PAA_Reload(); + + PVPArena.instance.reloadConfig(); + + final FileConfiguration config = PVPArena.instance.getConfig(); + Language.init(config.getString("language", "en")); + Help.init(config.getString("language", "en")); + + if (args.length > 1 && args[1].equalsIgnoreCase("ymls")) { + Arena.pmsg(sender, Language.parse(Language.MSG.RELOAD_YMLS_DONE)); + return; + } + + final String[] emptyArray = new String[0]; + + for (Arena a : ArenaManager.getArenas()) { + scmd.commit(a, sender, emptyArray); + } + + ArenaManager.load_arenas(); + if (config.getBoolean("use_shortcuts") || config.getBoolean("only_shortcuts")) { + ArenaManager.readShortcuts(config.getConfigurationSection("shortcuts")); + } + } + + @Override + public boolean hasVersionForArena() { + return true; + } + + @Override + public String getName() { + return getClass().getName(); + } + + @Override + public void displayHelp(final CommandSender sender) { + Arena.pmsg(sender, Help.parse(HELP.DEBUG)); + } + + @Override + public List getMain() { + return Collections.singletonList("reload"); + } + + @Override + public List getShort() { + return Collections.singletonList("!rl"); + } + + @Override + public CommandTree getSubs(final Arena nothing) { + final CommandTree result = new CommandTree<>(null); + result.define(new String[]{"ymls"}); + return result; + } +} diff --git a/src/net/slipcor/pvparena/commands/PAI_ArenaList.java b/src/net/slipcor/pvparena/commands/PAI_ArenaList.java index 2655405ac..fcdd5b628 100644 --- a/src/net/slipcor/pvparena/commands/PAI_ArenaList.java +++ b/src/net/slipcor/pvparena/commands/PAI_ArenaList.java @@ -52,6 +52,11 @@ public void commit(final CommandSender sender, final String[] args) { Arena.pmsg(sender, Language.parse(MSG.ARENA_LIST, StringParser.joinList(names, ", "))); } + @Override + public boolean hasVersionForArena() { + return true; + } + @Override public String getName() { return getClass().getName(); diff --git a/src/net/slipcor/pvparena/commands/PAI_GlobalStats.java b/src/net/slipcor/pvparena/commands/PAI_GlobalStats.java new file mode 100644 index 000000000..f42826180 --- /dev/null +++ b/src/net/slipcor/pvparena/commands/PAI_GlobalStats.java @@ -0,0 +1,73 @@ +package net.slipcor.pvparena.commands; + +import net.slipcor.pvparena.arena.Arena; +import net.slipcor.pvparena.core.Help; +import net.slipcor.pvparena.core.Help.HELP; +import net.slipcor.pvparena.managers.StatisticsManager.Type; +import org.bukkit.command.CommandSender; + +import java.util.Collections; +import java.util.List; + +/** + *

PVP Arena STATS Command class
+ *

+ * A command to display the player statistics + * + * @author slipcor + * @version v0.10.0 + */ + +public class PAI_GlobalStats extends AbstractGlobalCommand { + + public PAI_GlobalStats() { + super(new String[]{"pvparena.user", "pvparena.cmds.stats"}); + } + + @Override + public void commit(final CommandSender sender, final String[] args) { + if (!hasPerms(sender)) { + return; + } + + if (!argCountValid(sender, args, new Integer[]{1})) { + return; + } + + new PAI_Stats().commit(null, sender, args); + } + + @Override + public boolean hasVersionForArena() { + return true; + } + + @Override + public String getName() { + return getClass().getName(); + } + + @Override + public void displayHelp(final CommandSender sender) { + Arena.pmsg(sender, Help.parse(HELP.STATS)); + } + + @Override + public List getMain() { + return Collections.singletonList("stats"); + } + + @Override + public List getShort() { + return Collections.singletonList("-s"); + } + + @Override + public CommandTree getSubs(final Arena arena) { + final CommandTree result = new CommandTree<>(null); + for (final Type val : Type.values()) { + result.define(new String[]{val.name()}); + } + return result; + } +} diff --git a/src/net/slipcor/pvparena/core/Language.java b/src/net/slipcor/pvparena/core/Language.java index 721b575af..09fbccf22 100644 --- a/src/net/slipcor/pvparena/core/Language.java +++ b/src/net/slipcor/pvparena/core/Language.java @@ -184,7 +184,6 @@ public enum MSG { ERROR_NOPERM_C_ENABLE("nulang.nopermto.cmds.enable", "use the enable command"), ERROR_NOPERM_C_GAMEMODE("nulang.nopermto.cmds.gamemode", "use the gamemode command"), ERROR_NOPERM_C_GOAL("nulang.nopermto.cmds.goal", "use the goal command"), - ERROR_NOPERM_C_INSTALL("nulang.nopermto.cmds.install", "use the install command"), ERROR_NOPERM_C_PLAYERCLASS("nulang.nopermto.cmds.playerclass", "use the playerclass command"), ERROR_NOPERM_C_PLAYERJOIN("nulang.nopermto.cmds.playerjoin", "use the playerjoin command"), ERROR_NOPERM_C_PROTECTION("nulang.nopermto.cmds.protection", "use the protection command"), @@ -205,8 +204,7 @@ public enum MSG { ERROR_NOPERM_C_TELEPORT("nulang.nopermto.cmds.teleport", "use the teleport command"), ERROR_NOPERM_C_TEMPLATE("nulang.nopermto.cmds.template", "use the template command"), ERROR_NOPERM_C_TOGGLEMOD("nulang.nopermto.cmds.togglemod", "use the togglemod command"), - ERROR_NOPERM_C_UNINSTALL("nulang.nopermto.cmds.uninstall", "use the uninstall command"), - ERROR_NOPERM_C_UPDATE("nulang.nopermto.cmds.update", "use the update command"), + ERROR_NOPERM_C_MODULES("nulang.nopermto.cmds.uninstall", "use the modules command"), ERROR_NOPERM_C_WHITELIST("nulang.nopermto.cmds.whitelist", "use the whitelist command"), ERROR_NOPERM_C_ARENACLASS("nulang.nopermto.cmds.arenaclass", "use the arenaclass command"), ERROR_NOPERM_C_CHAT("nulang.nopermto.cmds.chat", "use the chat command"), diff --git a/src/net/slipcor/pvparena/managers/TabManager.java b/src/net/slipcor/pvparena/managers/TabManager.java index ae18f7e0b..b2d7dd7be 100644 --- a/src/net/slipcor/pvparena/managers/TabManager.java +++ b/src/net/slipcor/pvparena/managers/TabManager.java @@ -7,7 +7,6 @@ import net.slipcor.pvparena.commands.AbstractArenaCommand; import net.slipcor.pvparena.commands.AbstractGlobalCommand; import net.slipcor.pvparena.commands.CommandTree; -import net.slipcor.pvparena.core.Language; import net.slipcor.pvparena.core.StringParser; import net.slipcor.pvparena.loadables.ArenaRegion; import org.bukkit.Bukkit; @@ -20,6 +19,8 @@ import java.util.*; import java.util.stream.Collectors; +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; import static org.bukkit.util.StringUtil.startsWithIgnoreCase; public final class TabManager { @@ -27,23 +28,20 @@ private TabManager() {} public static List getMatches(final CommandSender sender, final List arenaCommands, final List globalCommands, String[] args) { final Set matches = new LinkedHashSet<>(); + final String firstArg = args[0]; Arena arena = null; if (sender instanceof Player) { arena = ArenaPlayer.parsePlayer(sender.getName()).getArena(); } - if (args.length < 1) { - for (final Arena a : ArenaManager.getArenas()) { - matches.add(a.getName()); - } - return new ArrayList<>(matches); - } - if (arena == null) { - // no proper arena yet - arena = ArenaManager.getArenaByExactName(args[0]); + // player is not inside an arena or in edit mode + + arena = ArenaManager.getArenaByExactName(firstArg); + if (arena == null && ArenaManager.getArenas().size() == 1) { - // still no arena, get the only arena! + // still no arena, get the only arena + arena = ArenaManager.getFirst(); // continue with one arg less args = Arrays.copyOfRange(args, 1, args.length); @@ -51,39 +49,36 @@ public static List getMatches(final CommandSender sender, final List turn to catchall args = new String[]{""}; } + } else if (arena != null) { - // arena has been found + // first argument matches with an arena + if (args.length < 2) { // return the exact arena name - matches.add(arena.getName()); - return new ArrayList<>(matches); + return singletonList(arena.getName()); } else { - // we have more args! + // if more args, we remove the first one (arena name) args = Arrays.copyOfRange(args, 1, args.length); if (args.length < 1) { // empty -> turn to catchall args = new String[]{""}; } } - } else { - // arena has still not been found - if (args.length > 1) { - // the sender has already entered the next thing without a valid arena - sender.sendMessage(Language.parse(Language.MSG.ERROR_ARENA_NOTFOUND, args[0])); - return new ArrayList<>(matches); - } + } else if(args.length == 1) { + // else, if only one arg, suggest arena names and global commands - final String search = args[0]; - return ArenaManager.getArenas().stream() - .filter(a -> startsWithIgnoreCase(a.getName(), search)) + matches.addAll(ArenaManager.getArenas().stream() + .filter(a -> startsWithIgnoreCase(a.getName(), firstArg)) .map(Arena::getName) - .collect(Collectors.toList()); + .collect(Collectors.toList())); + + addCommandsStartingWithPrefix(matches, sender, arena, globalCommands, firstArg); + return new ArrayList<>(matches); } } if (args.length == 1) { addCommandsStartingWithPrefix(matches, sender, arena, arenaCommands, args[0]); - addCommandsStartingWithPrefix(matches, sender, arena, globalCommands, args[0]); if (arena == null) { addCommandsStartingWithPrefix(matches, sender, null, PVPArena.instance.getAgm().getAllGoals(), args[0]); @@ -122,14 +117,17 @@ public static List getMatches(final CommandSender sender, final List matches, final CommandSender sender, final Arena arena, final List list, final String prefix) { for (final IArenaCommandHandler ach : list) { if (ach.hasPerms(sender, arena)) { - for (final String value : ach.getMain()) { - if (startsWithIgnoreCase(value, prefix)) { - matches.add(value); + if(prefix.startsWith("!") || prefix.startsWith("-")) { + for (final String value : ach.getShort()) { + if (startsWithIgnoreCase(value, prefix)) { + matches.add(value); + } } - } - for (final String value : ach.getShort()) { - if (startsWithIgnoreCase(value, prefix)) { - matches.add(value); + } else { + for (final String value : ach.getMain()) { + if (startsWithIgnoreCase(value, prefix)) { + matches.add(value); + } } } } @@ -231,7 +229,7 @@ private static List getKeyMatchesInsideDefinition(final String key, fina if (definition.startsWith("{")) { if ("{Material}".equals(definition)) { final Material[] mats = Material.values(); - addEnumMatchesToList(result, key, Arrays.asList(mats)); + addEnumMatchesToList(result, key, asList(mats)); } else if ("{Player}".equals(definition)) { final Collection players = Bukkit.getOnlinePlayers(); if (key != null && key.isEmpty()) { @@ -247,13 +245,13 @@ private static List getKeyMatchesInsideDefinition(final String key, fina } } else if ("{RegionProtection}".equals(definition)) { final ArenaRegion.RegionProtection[] protections = ArenaRegion.RegionProtection.values(); - addEnumMatchesToList(result, key, Arrays.asList(protections)); + addEnumMatchesToList(result, key, asList(protections)); } else if ("{RegionFlag}".equals(definition)) { final ArenaRegion.RegionFlag[] flags = ArenaRegion.RegionFlag.values(); - addEnumMatchesToList(result, key, Arrays.asList(flags)); + addEnumMatchesToList(result, key, asList(flags)); } else if ("{RegionType}".equals(definition)) { final ArenaRegion.RegionType[] types = ArenaRegion.RegionType.values(); - addEnumMatchesToList(result, key, Arrays.asList(types)); + addEnumMatchesToList(result, key, asList(types)); } else if ("{Boolean}".equals(definition)) { final List values = new ArrayList<>(); values.addAll(StringParser.negative); @@ -282,7 +280,7 @@ private static List getKeyMatchesInsideDefinition(final String key, fina } } else if ("{EntityType}".equals(definition)) { final EntityType[] entityTypes = EntityType.values(); - addEnumMatchesToList(result, key, Arrays.asList(entityTypes)); + addEnumMatchesToList(result, key, asList(entityTypes)); } } return result; @@ -299,7 +297,7 @@ private static String getOverrideFromDefinition(final String key, final String d if (definition.startsWith("{")) { if ("{Material}".equals(definition)) { final Material[] mats = Material.values(); - return getOverrideKey(key, definition, Arrays.asList(mats)); + return getOverrideKey(key, definition, asList(mats)); } else if ("{String}".equals(definition)) { return definition; } else if ("{Player}".equals(definition)) { @@ -312,13 +310,13 @@ private static String getOverrideFromDefinition(final String key, final String d return key; } else if ("{RegionProtection}".equals(definition)) { final ArenaRegion.RegionProtection[] protections = ArenaRegion.RegionProtection.values(); - return getOverrideKey(key, definition, Arrays.asList(protections)); + return getOverrideKey(key, definition, asList(protections)); } else if ("{RegionFlag}".equals(definition)) { final ArenaRegion.RegionFlag[] flags = ArenaRegion.RegionFlag.values(); - return getOverrideKey(key, definition, Arrays.asList(flags)); + return getOverrideKey(key, definition, asList(flags)); } else if ("{RegionType}".equals(definition)) { final ArenaRegion.RegionType[] types = ArenaRegion.RegionType.values(); - return getOverrideKey(key, definition, Arrays.asList(types)); + return getOverrideKey(key, definition, asList(types)); } else if ("{Boolean}".equals(definition)) { final List values = new ArrayList<>(); values.addAll(StringParser.negative); @@ -347,7 +345,7 @@ private static String getOverrideFromDefinition(final String key, final String d return key; } else if ("{EntityType}".equals(definition)) { final EntityType[] entityTypes = EntityType.values(); - return getOverrideKey(key, definition, Arrays.asList(entityTypes)); + return getOverrideKey(key, definition, asList(entityTypes)); } } return key; From 932293e62c01b8b2d03f49f8dc9bf09334b6bb0d Mon Sep 17 00:00:00 2001 From: Eredrim Date: Thu, 9 Jul 2020 22:28:17 +0200 Subject: [PATCH 33/43] v1.15 - kick players if going out of lounge regions - issue #48 --- src/net/slipcor/pvparena/arena/Arena.java | 2 +- .../pvparena/loadables/ArenaRegion.java | 26 +++++++++---------- .../pvparena/runnables/RegionRunnable.java | 9 ++++--- 3 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/net/slipcor/pvparena/arena/Arena.java b/src/net/slipcor/pvparena/arena/Arena.java index fb7b9a24d..b039047a5 100644 --- a/src/net/slipcor/pvparena/arena/Arena.java +++ b/src/net/slipcor/pvparena/arena/Arena.java @@ -225,7 +225,7 @@ public void addRegion(final ArenaRegion region) { if (cfg.getBoolean(CFG.JOIN_FORCE)) { region.initTimer(); } - } else if (region.getType() == RegionType.WATCH) { + } else if (region.getType() == RegionType.WATCH || region.getType() == RegionType.LOUNGE) { region.initTimer(); } } diff --git a/src/net/slipcor/pvparena/loadables/ArenaRegion.java b/src/net/slipcor/pvparena/loadables/ArenaRegion.java index aa62de5aa..8aa4a4812 100644 --- a/src/net/slipcor/pvparena/loadables/ArenaRegion.java +++ b/src/net/slipcor/pvparena/loadables/ArenaRegion.java @@ -29,9 +29,12 @@ import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.EntityDamageEvent.DamageCause; import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.scheduler.BukkitTask; import java.util.*; +import static java.util.Arrays.asList; + public class ArenaRegion { private static final Debug debug = new Debug(34); @@ -39,7 +42,7 @@ public class ArenaRegion { private Arena arena; private String name; private RegionType type; - private int tickID = -1; + private BukkitTask runningTask; private final Set flags = new HashSet<>(); private final Set protections = new HashSet<>(); private final Map playerLocations = new HashMap<>(); @@ -367,19 +370,15 @@ public String getWorldName() { public void initTimer() { - if (tickID != -1) { - if (type == RegionType.JOIN || type == RegionType.WATCH) { - return; + if (this.runningTask != null && !this.runningTask.isCancelled()) { + if (!asList(RegionType.JOIN, RegionType.WATCH, RegionType.LOUNGE).contains(this.type)) { + this.runningTask.cancel(); } - - Bukkit.getScheduler().cancelTask(tickID); } final RegionRunnable regionRunner = new RegionRunnable(this); - tickID = Bukkit.getScheduler().scheduleSyncRepeatingTask( - PVPArena.instance, regionRunner, - (long) arena.getArenaConfig().getInt(CFG.TIME_REGIONTIMER), - (long) arena.getArenaConfig().getInt(CFG.TIME_REGIONTIMER)); + final int timer = this.arena.getArenaConfig().getInt(CFG.TIME_REGIONTIMER); + this.runningTask = regionRunner.runTaskTimer(PVPArena.instance, timer, timer); } public boolean isInNoWoolSet(final Block block) { @@ -446,7 +445,7 @@ public void reset() { } public void removeEntities() { - if (getWorld() == null || getWorld().getEntities() == null) { + if (getWorld() == null || getWorld().getEntities().isEmpty()) { return; } @@ -473,8 +472,9 @@ public void removeEntities() { return; } - Bukkit.getScheduler().cancelTask(tickID); - tickID = -1; + if(this.runningTask != null && !this.runningTask.isCancelled()) { + this.runningTask.cancel(); + } } public void saveToConfig() { diff --git a/src/net/slipcor/pvparena/runnables/RegionRunnable.java b/src/net/slipcor/pvparena/runnables/RegionRunnable.java index 974ab5b87..bfa68603d 100644 --- a/src/net/slipcor/pvparena/runnables/RegionRunnable.java +++ b/src/net/slipcor/pvparena/runnables/RegionRunnable.java @@ -3,6 +3,9 @@ import net.slipcor.pvparena.PVPArena; import net.slipcor.pvparena.loadables.ArenaRegion; import net.slipcor.pvparena.loadables.ArenaRegion.RegionType; +import org.bukkit.scheduler.BukkitRunnable; + +import static java.util.Arrays.asList; /** *

@@ -15,7 +18,7 @@
  * @version v0.9.9
  */
 
-public class RegionRunnable implements Runnable {
+public class RegionRunnable extends BukkitRunnable {
     private final ArenaRegion region;
 //	private final static Debug DEBUG = new Debug(49);
 //	private int iID;
@@ -74,8 +77,8 @@ public void run() {
                 region.getArena().getDebugger().i("tick 2: " + region.getRegionName());
                 region.tick();
             }
-        } else if (region.getType() == RegionType.WATCH) {
-            // always tick for WATCH regions!
+        } else if (asList(RegionType.WATCH, RegionType.LOUNGE).contains(region.getType())) {
+            // always tick for WATCH & LOUNGE regions!
             region.getArena().getDebugger().i("tick 3: " + region.getRegionName());
             region.tick();
         } else if (region.getArena().isFightInProgress()) {

From f06901fca6cce90e546da50df9c680350b82ec22 Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Mon, 20 Jul 2020 21:14:05 +0200
Subject: [PATCH 34/43] v1.15 - fix NPE caused by spectators of infected arenas
 - issue #51

---
 .../slipcor/pvparena/goals/GoalInfect.java    | 300 +++++++++---------
 1 file changed, 145 insertions(+), 155 deletions(-)

diff --git a/src/net/slipcor/pvparena/goals/GoalInfect.java b/src/net/slipcor/pvparena/goals/GoalInfect.java
index 1479994d4..8284f4d8f 100644
--- a/src/net/slipcor/pvparena/goals/GoalInfect.java
+++ b/src/net/slipcor/pvparena/goals/GoalInfect.java
@@ -52,7 +52,7 @@
 public class GoalInfect extends ArenaGoal {
     public GoalInfect() {
         super("Infect");
-        debug = new Debug(108);
+        this.debug = new Debug(108);
     }
 // BREAK, PLACE, TNT, TNTBREAK, DROP, INVENTORY, PICKUP, CRAFT;
     private EndRunnable endRunner;
@@ -70,10 +70,10 @@ public PACheck checkEnd(final PACheck res) {
             return res;
         }
 
-        final int count = getLifeMap().size();
+        final int count = this.getLifeMap().size();
 
         if (count <= 1
-                || anyTeamEmpty()) {
+                || this.anyTeamEmpty()) {
             res.setPriority(this, PRIORITY); // yep. only one player left. go!
         }
         if (count == 0) {
@@ -84,17 +84,18 @@ public PACheck checkEnd(final PACheck res) {
     }
 
     private boolean anyTeamEmpty() {
-        for (final ArenaTeam team : arena.getTeams()) {
+        for (final ArenaTeam team : this.arena.getTeams()) {
             boolean bbreak = false;
             for (final ArenaPlayer player : team.getTeamMembers()) {
                 if (player.getStatus() == Status.FIGHT) {
                     bbreak = true;
+                    break;
                 }
             }
             if (bbreak) {
                 continue;
             }
-            arena.getDebugger().i("team empty: " + team.getName());
+            this.arena.getDebugger().i("team empty: " + team.getName());
             return true;
         }
         return false;
@@ -102,7 +103,7 @@ private boolean anyTeamEmpty() {
 
     @Override
     public String checkForMissingSpawns(final Set list) {
-        if (!arena.isFreeForAll()) {
+        if (!this.arena.isFreeForAll()) {
             return null; // teams are handled somewhere else
         }
 
@@ -139,7 +140,7 @@ public PACheck checkCommand(final PACheck res, final String string) {
     @Override
     public PACheck checkBreak(PACheck result, Arena arena, BlockBreakEvent event) {
         ArenaPlayer ap = ArenaPlayer.parsePlayer(event.getPlayer().getName());
-        if (arena.equals(ap.getArena())) {
+        if (arena.equals(ap.getArena()) && ap.getStatus() == Status.FIGHT) {
             if ("infected".equals(ap.getArenaTeam().getName())) {
                 if (ArenaPlayer.PlayerPrevention.has(
                         arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_PPROTECTS), ArenaPlayer.PlayerPrevention.BREAK
@@ -163,13 +164,13 @@ public PACheck checkBreak(PACheck result, Arena arena, BlockBreakEvent event) {
     @Override
     public PACheck checkCraft(PACheck result, Arena arena, CraftItemEvent event) {
         ArenaPlayer ap = ArenaPlayer.parsePlayer(((Player) event.getInventory().getHolder()).getName());
-        if (arena.equals(ap.getArena())) {
+        if (arena.equals(ap.getArena()) && ap.getStatus() == Status.FIGHT) {
             if ("infected".equals(ap.getArenaTeam().getName())) {
                 if (ArenaPlayer.PlayerPrevention.has(
                         arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_PPROTECTS), ArenaPlayer.PlayerPrevention.CRAFT
                 )) {
                     event.setCancelled(true);
-                    arena.msg((Player) event.getWhoClicked(), Language.parse(arena, MSG.PLAYER_PREVENTED_CRAFT));
+                    arena.msg(event.getWhoClicked(), Language.parse(arena, MSG.PLAYER_PREVENTED_CRAFT));
                     result.setError(this, "CRAFT not allowed");
                 }
             }
@@ -180,7 +181,7 @@ public PACheck checkCraft(PACheck result, Arena arena, CraftItemEvent event) {
     @Override
     public PACheck checkDrop(PACheck result, Arena arena, PlayerDropItemEvent event) {
         ArenaPlayer ap = ArenaPlayer.parsePlayer(event.getPlayer().getName());
-        if (arena.equals(ap.getArena())) {
+        if (arena.equals(ap.getArena()) && ap.getStatus() == Status.FIGHT) {
             if ("infected".equals(ap.getArenaTeam().getName())) {
                 if (ArenaPlayer.PlayerPrevention.has(
                         arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_PPROTECTS), ArenaPlayer.PlayerPrevention.DROP
@@ -196,15 +197,15 @@ public PACheck checkDrop(PACheck result, Arena arena, PlayerDropItemEvent event)
 
     @Override
     public PACheck checkInventory(PACheck result, Arena arena, InventoryClickEvent event) {
-        ArenaPlayer ap = ArenaPlayer.parsePlayer(((Player) event.getWhoClicked()).getName());
-        if (arena.equals(ap.getArena())) {
+        ArenaPlayer ap = ArenaPlayer.parsePlayer(event.getWhoClicked().getName());
+        if (arena.equals(ap.getArena()) && ap.getStatus() == Status.FIGHT) {
             if ("infected".equals(ap.getArenaTeam().getName())) {
                 if (ArenaPlayer.PlayerPrevention.has(
                         arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_PPROTECTS), ArenaPlayer.PlayerPrevention.INVENTORY
                 )) {
                     event.setCancelled(true);
                     event.getWhoClicked().closeInventory();
-                    arena.msg((Player) event.getWhoClicked(), Language.parse(arena, MSG.PLAYER_PREVENTED_INVENTORY));
+                    arena.msg(event.getWhoClicked(), Language.parse(arena, MSG.PLAYER_PREVENTED_INVENTORY));
                     result.setError(this, "INVENTORY not allowed");
                 }
             }
@@ -215,7 +216,7 @@ public PACheck checkInventory(PACheck result, Arena arena, InventoryClickEvent e
     @Override
     public PACheck checkPickup(PACheck result, Arena arena, EntityPickupItemEvent event) {
         ArenaPlayer ap = ArenaPlayer.parsePlayer(event.getEntity().getName());
-        if (arena.equals(ap.getArena())) {
+        if (arena.equals(ap.getArena()) && ap.getStatus() == Status.FIGHT) {
             if ("infected".equals(ap.getArenaTeam().getName())) {
                 if (ArenaPlayer.PlayerPrevention.has(
                         arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_PPROTECTS), ArenaPlayer.PlayerPrevention.PICKUP
@@ -231,7 +232,7 @@ public PACheck checkPickup(PACheck result, Arena arena, EntityPickupItemEvent ev
     @Override
     public PACheck checkPlace(PACheck result, Arena arena, BlockPlaceEvent event) {
         ArenaPlayer ap = ArenaPlayer.parsePlayer(event.getPlayer().getName());
-        if (arena.equals(ap.getArena())) {
+        if (arena.equals(ap.getArena()) && ap.getStatus() == Status.FIGHT) {
             if ("infected".equals(ap.getArenaTeam().getName())) {
                 if (ArenaPlayer.PlayerPrevention.has(
                         arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_PPROTECTS), ArenaPlayer.PlayerPrevention.PLACE
@@ -258,12 +259,12 @@ public PACheck checkJoin(final CommandSender sender, final PACheck res, final St
             return res;
         }
 
-        final int maxPlayers = arena.getArenaConfig().getInt(CFG.READY_MAXPLAYERS);
-        final int maxTeamPlayers = arena.getArenaConfig().getInt(
+        final int maxPlayers = this.arena.getArenaConfig().getInt(CFG.READY_MAXPLAYERS);
+        final int maxTeamPlayers = this.arena.getArenaConfig().getInt(
                 CFG.READY_MAXTEAMPLAYERS);
 
-        if (maxPlayers > 0 && arena.getFighters().size() >= maxPlayers) {
-            res.setError(this, Language.parse(arena, MSG.ERROR_JOIN_ARENA_FULL));
+        if (maxPlayers > 0 && this.arena.getFighters().size() >= maxPlayers) {
+            res.setError(this, Language.parse(this.arena, MSG.ERROR_JOIN_ARENA_FULL));
             return res;
         }
 
@@ -271,12 +272,12 @@ public PACheck checkJoin(final CommandSender sender, final PACheck res, final St
             return res;
         }
 
-        if (!arena.isFreeForAll()) {
-            final ArenaTeam team = arena.getTeam(args[0]);
+        if (!this.arena.isFreeForAll()) {
+            final ArenaTeam team = this.arena.getTeam(args[0]);
 
             if (team != null && maxTeamPlayers > 0
                     && team.getTeamMembers().size() >= maxTeamPlayers) {
-                res.setError(this, Language.parse(arena, MSG.ERROR_JOIN_TEAM_FULL, team.getName()));
+                res.setError(this, Language.parse(this.arena, MSG.ERROR_JOIN_TEAM_FULL, team.getName()));
                 return res;
             }
         }
@@ -290,11 +291,11 @@ public PACheck checkPlayerDeath(final PACheck res, final Player player) {
         if (res.getPriority() <= PRIORITY) {
             res.setPriority(this, PRIORITY);
 
-            if (!getLifeMap().containsKey(player.getName())) {
+            if (!this.getLifeMap().containsKey(player.getName())) {
                 return res;
             }
-            final int iLives = getLifeMap().get(player.getName());
-            arena.getDebugger().i("lives before death: " + iLives, player);
+            final int iLives = this.getLifeMap().get(player.getName());
+            this.arena.getDebugger().i("lives before death: " + iLives, player);
             if (iLives <= 1 && "infected".equals(ArenaPlayer.parsePlayer(player.getName()).getArenaTeam().getName())) {
                 res.setError(this, "0");
             }
@@ -314,7 +315,7 @@ public PACheck checkStart(final PACheck res) {
     @Override
     public void commitCommand(final CommandSender sender, final String[] args) {
 
-        int value = arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_PPROTECTS);
+        int value = this.arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_PPROTECTS);
 
         if ("getprotect".equalsIgnoreCase(args[0])) {
             List values = new ArrayList<>();
@@ -327,14 +328,14 @@ public void commitCommand(final CommandSender sender, final String[] args) {
                 values.add((ArenaPlayer.PlayerPrevention.has(value, pp) ?
                         ChatColor.GREEN.toString() : ChatColor.RED.toString()) + pp.name());
             }
-            arena.msg(sender, Language.parse(arena, MSG.GOAL_INFECTED_IPROTECT, StringParser.joinList(values, (ChatColor.WHITE + ", "))));
+            this.arena.msg(sender, Language.parse(this.arena, MSG.GOAL_INFECTED_IPROTECT, StringParser.joinList(values, (ChatColor.WHITE + ", "))));
 
         } else if ("setprotect".equalsIgnoreCase(args[0])) {
             // setprotect [value] {true|false}
             if (args.length < 2) {
-                arena.msg(
+                this.arena.msg(
                         sender,
-                        Language.parse(arena, MSG.ERROR_INVALID_ARGUMENT_COUNT,
+                        Language.parse(this.arena, MSG.ERROR_INVALID_ARGUMENT_COUNT,
                                 String.valueOf(args.length), "2|3"));
                 return;
             }
@@ -343,9 +344,9 @@ public void commitCommand(final CommandSender sender, final String[] args) {
                 final ArenaPlayer.PlayerPrevention pp = ArenaPlayer.PlayerPrevention.valueOf(args[1].toUpperCase());
                 final boolean has = ArenaPlayer.PlayerPrevention.has(value, pp);
 
-                arena.getDebugger().i("plain value: " + value);
-                arena.getDebugger().i("checked: " + pp.name());
-                arena.getDebugger().i("has: " + String.valueOf(has));
+                this.arena.getDebugger().i("plain value: " + value);
+                this.arena.getDebugger().i("checked: " + pp.name());
+                this.arena.getDebugger().i("has: " + has);
 
                 boolean future = !has;
 
@@ -359,18 +360,18 @@ public void commitCommand(final CommandSender sender, final String[] args) {
 
                 if (future) {
                     value = value | (int) Math.pow(2, pp.ordinal());
-                    arena.msg(
+                    this.arena.msg(
                             sender,
-                            Language.parse(arena, MSG.GOAL_INFECTED_IPROTECT_SET,
+                            Language.parse(this.arena, MSG.GOAL_INFECTED_IPROTECT_SET,
                                     pp.name(), ChatColor.GREEN + "true") + ChatColor.YELLOW);
                 } else {
                     value = value ^ (int) Math.pow(2, pp.ordinal());
-                    arena.msg(
+                    this.arena.msg(
                             sender,
-                            Language.parse(arena, MSG.GOAL_INFECTED_IPROTECT_SET,
+                            Language.parse(this.arena, MSG.GOAL_INFECTED_IPROTECT_SET,
                                     pp.name(), ChatColor.RED + "false") + ChatColor.YELLOW);
                 }
-                arena.getArenaConfig().set(CFG.GOAL_INFECTED_PPROTECTS, value);
+                this.arena.getArenaConfig().set(CFG.GOAL_INFECTED_PPROTECTS, value);
             } catch (final Exception e) {
                 List values = new ArrayList<>();
 
@@ -378,159 +379,157 @@ public void commitCommand(final CommandSender sender, final String[] args) {
                 for (ArenaPlayer.PlayerPrevention pp : ArenaPlayer.PlayerPrevention.values()) {
                     values.add(pp.name());
                 }
-                arena.msg(sender,
-                        Language.parse(arena, MSG.ERROR_ARGUMENT, args[1], StringParser.joinList(values, ", ")));
+                this.arena.msg(sender,
+                        Language.parse(this.arena, MSG.ERROR_ARGUMENT, args[1], StringParser.joinList(values, ", ")));
                 return;
             }
-            arena.getArenaConfig().save();
+            this.arena.getArenaConfig().save();
 
         }
     }
 
     @Override
     public void commitEnd(final boolean force) {
-        if (endRunner != null) {
+        if (this.endRunner != null) {
             return;
         }
-        if (arena.realEndRunner != null) {
-            arena.getDebugger().i("[INFECT] already ending");
+        if (this.arena.realEndRunner != null) {
+            this.arena.getDebugger().i("[INFECT] already ending");
             return;
         }
-        final PAGoalEvent gEvent = new PAGoalEvent(arena, this, "");
+        final PAGoalEvent gEvent = new PAGoalEvent(this.arena, this, "");
         Bukkit.getPluginManager().callEvent(gEvent);
 
-        for (final ArenaTeam team : arena.getTeams()) {
+        for (final ArenaTeam team : this.arena.getTeams()) {
             for (final ArenaPlayer ap : team.getTeamMembers()) {
                 if (ap.getStatus() != Status.FIGHT) {
                     continue;
                 }
                 if ("infected".equals(ap.getArenaTeam().getName())) {
-                    ArenaModuleManager.announce(arena,
-                            Language.parse(arena, MSG.GOAL_INFECTED_WON), "END");
+                    ArenaModuleManager.announce(this.arena,
+                            Language.parse(this.arena, MSG.GOAL_INFECTED_WON), "END");
 
-                    ArenaModuleManager.announce(arena,
-                            Language.parse(arena, MSG.GOAL_INFECTED_WON), "WINNER");
+                    ArenaModuleManager.announce(this.arena,
+                            Language.parse(this.arena, MSG.GOAL_INFECTED_WON), "WINNER");
 
-                    arena.broadcast(Language.parse(arena, MSG.GOAL_INFECTED_WON));
+                    this.arena.broadcast(Language.parse(this.arena, MSG.GOAL_INFECTED_WON));
                     break;
                 } else {
 
-                    ArenaModuleManager.announce(arena,
-                            Language.parse(arena, MSG.GOAL_INFECTED_LOST), "END");
+                    ArenaModuleManager.announce(this.arena,
+                            Language.parse(this.arena, MSG.GOAL_INFECTED_LOST), "END");
                     // String tank = tanks.get(arena);
-                    ArenaModuleManager.announce(arena,
-                            Language.parse(arena, MSG.GOAL_INFECTED_LOST), "LOSER");
+                    ArenaModuleManager.announce(this.arena,
+                            Language.parse(this.arena, MSG.GOAL_INFECTED_LOST), "LOSER");
 
-                    arena.broadcast(Language.parse(arena, MSG.GOAL_INFECTED_LOST));
+                    this.arena.broadcast(Language.parse(this.arena, MSG.GOAL_INFECTED_LOST));
                     break;
                 }
             }
 
-            if (ArenaModuleManager.commitEnd(arena, team)) {
+            if (ArenaModuleManager.commitEnd(this.arena, team)) {
                 return;
             }
         }
 
-        endRunner = new EndRunnable(arena, arena.getArenaConfig().getInt(
+        this.endRunner = new EndRunnable(this.arena, this.arena.getArenaConfig().getInt(
                 CFG.TIME_ENDCOUNTDOWN));
     }
 
     @Override
     public void commitPlayerDeath(final Player player, final boolean doesRespawn,
                                   final String error, final PlayerDeathEvent event) {
-        if (!getLifeMap().containsKey(player.getName())) {
+        if (!this.getLifeMap().containsKey(player.getName())) {
             return;
         }
-        int iLives = getLifeMap().get(player.getName());
-        arena.getDebugger().i("lives before death: " + iLives, player);
-        if (iLives <= 1 || "infected".equals(ArenaPlayer.parsePlayer(player.getName()).getArenaTeam().getName())) {
-            if (iLives <= 1 && "infected".equals(ArenaPlayer.parsePlayer(player.getName()).getArenaTeam().getName())) {
+        int iLives = this.getLifeMap().get(player.getName());
+        this.arena.getDebugger().i("lives before death: " + iLives, player);
+        ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(player.getName());
+        if (iLives <= 1 || "infected".equals(aPlayer.getArenaTeam().getName())) {
+            if (iLives <= 1 && "infected".equals(aPlayer.getArenaTeam().getName())) {
 
-                final PAGoalEvent gEvent = new PAGoalEvent(arena, this, "infected", "playerDeath:" + player.getName());
+                final PAGoalEvent gEvent = new PAGoalEvent(this.arena, this, "infected", "playerDeath:" + player.getName());
                 Bukkit.getPluginManager().callEvent(gEvent);
-                ArenaPlayer.parsePlayer(player.getName()).setStatus(Status.LOST);
+                aPlayer.setStatus(Status.LOST);
                 // kill, remove!
-                getLifeMap().remove(player.getName());
-                if (arena.getArenaConfig().getBoolean(CFG.PLAYER_PREVENTDEATH)) {
-                    arena.getDebugger().i("faking player death", player);
-                    PlayerListener.finallyKillPlayer(arena, player, event);
+                this.getLifeMap().remove(player.getName());
+                if (this.arena.getArenaConfig().getBoolean(CFG.PLAYER_PREVENTDEATH)) {
+                    this.arena.getDebugger().i("faking player death", player);
+                    PlayerListener.finallyKillPlayer(this.arena, player, event);
                 }
                 return;
             }
             if (iLives <= 1) {
-                PAGoalEvent gEvent = new PAGoalEvent(arena, this, "playerDeath:" + player.getName());
+                PAGoalEvent gEvent = new PAGoalEvent(this.arena, this, "playerDeath:" + player.getName());
                 Bukkit.getPluginManager().callEvent(gEvent);
                 // dying player -> infected
-                getLifeMap().put(player.getName(), arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_ILIVES));
-                arena.msg(player, Language.parse(arena, MSG.GOAL_INFECTED_YOU));
-                arena.broadcast(Language.parse(arena, MSG.GOAL_INFECTED_PLAYER, player.getName()));
-
-                ArenaPlayer aPlayer = ArenaPlayer.parsePlayer(player.getName());
+                this.getLifeMap().put(player.getName(), this.arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_ILIVES));
+                this.arena.msg(player, Language.parse(this.arena, MSG.GOAL_INFECTED_YOU));
+                this.arena.broadcast(Language.parse(this.arena, MSG.GOAL_INFECTED_PLAYER, player.getName()));
 
                 final ArenaTeam oldTeam = aPlayer.getArenaTeam();
-                final ArenaTeam respawnTeam = arena.getTeam("infected");
+                final ArenaTeam respawnTeam = this.arena.getTeam("infected");
 
-                PATeamChangeEvent tcEvent = new PATeamChangeEvent(arena, player, oldTeam, respawnTeam);
+                PATeamChangeEvent tcEvent = new PATeamChangeEvent(this.arena, player, oldTeam, respawnTeam);
                 Bukkit.getPluginManager().callEvent(tcEvent);
-                arena.updateScoreboardTeam(player, oldTeam, respawnTeam);
+                this.arena.updateScoreboardTeam(player, oldTeam, respawnTeam);
 
                 oldTeam.remove(aPlayer);
 
                 respawnTeam.add(aPlayer);
 
-                final ArenaClass infectedClass = arena.getClass("%infected%");
+                final ArenaClass infectedClass = this.arena.getClass("%infected%");
                 if (infectedClass != null) {
                     aPlayer.setArenaClass(infectedClass);
                 }
 
-                if (arena.getArenaConfig().getBoolean(CFG.USES_DEATHMESSAGES)) {
-                    arena.broadcast(Language.parse(arena,
+                if (this.arena.getArenaConfig().getBoolean(CFG.USES_DEATHMESSAGES)) {
+                    this.arena.broadcast(Language.parse(this.arena,
                             MSG.FIGHT_KILLED_BY,
                             respawnTeam.colorizePlayer(player) + ChatColor.YELLOW,
-                            arena.parseDeathCause(player, event.getEntity()
+                            this.arena.parseDeathCause(player, event.getEntity()
                                             .getLastDamageCause().getCause(),
                                     player.getKiller()), String.valueOf(iLives)));
                 }
 
                 final List returned;
 
-                if (arena.getArenaConfig().getBoolean(
+                if (this.arena.getArenaConfig().getBoolean(
                         CFG.PLAYER_DROPSINVENTORY)) {
                     returned = InventoryManager.drop(player);
                     event.getDrops().clear();
                 } else {
-                    returned = new ArrayList<>();
-                    returned.addAll(event.getDrops());
+                    returned = new ArrayList<>(event.getDrops());
                 }
 
-                PACheck.handleRespawn(arena,
-                        ArenaPlayer.parsePlayer(player.getName()), returned);
+                PACheck.handleRespawn(this.arena,
+                        aPlayer, returned);
 
-                if (anyTeamEmpty()) {
-                    PACheck.handleEnd(arena, false);
+                if (this.anyTeamEmpty()) {
+                    PACheck.handleEnd(this.arena, false);
                 }
                 return;
             }
             // dying infected player, has lives remaining
-            PAGoalEvent gEvent = new PAGoalEvent(arena, this, "infected", "doesRespawn", "playerDeath:" + player.getName());
+            PAGoalEvent gEvent = new PAGoalEvent(this.arena, this, "infected", "doesRespawn", "playerDeath:" + player.getName());
             Bukkit.getPluginManager().callEvent(gEvent);
             iLives--;
-            getLifeMap().put(player.getName(), iLives);
+            this.getLifeMap().put(player.getName(), iLives);
 
-            final ArenaTeam respawnTeam = ArenaPlayer.parsePlayer(player.getName())
+            final ArenaTeam respawnTeam = aPlayer
                     .getArenaTeam();
-            if (arena.getArenaConfig().getBoolean(CFG.USES_DEATHMESSAGES)) {
-                arena.broadcast(Language.parse(arena,
+            if (this.arena.getArenaConfig().getBoolean(CFG.USES_DEATHMESSAGES)) {
+                this.arena.broadcast(Language.parse(this.arena,
                         MSG.FIGHT_KILLED_BY_REMAINING,
                         respawnTeam.colorizePlayer(player) + ChatColor.YELLOW,
-                        arena.parseDeathCause(player, event.getEntity()
+                        this.arena.parseDeathCause(player, event.getEntity()
                                         .getLastDamageCause().getCause(),
                                 player.getKiller()), String.valueOf(iLives)));
             }
 
             final List returned;
 
-            if (arena.getArenaConfig().getBoolean(
+            if (this.arena.getArenaConfig().getBoolean(
                     CFG.PLAYER_DROPSINVENTORY)) {
                 returned = InventoryManager.drop(player);
                 event.getDrops().clear();
@@ -539,57 +538,56 @@ public void commitPlayerDeath(final Player player, final boolean doesRespawn,
                 returned.addAll(event.getDrops());
             }
 
-            PACheck.handleRespawn(arena,
-                    ArenaPlayer.parsePlayer(player.getName()), returned);
+            PACheck.handleRespawn(this.arena,
+                    aPlayer, returned);
 
 
             // player died => commit death!
-            PACheck.handleEnd(arena, false);
+            PACheck.handleEnd(this.arena, false);
         } else {
             iLives--;
-            getLifeMap().put(player.getName(), iLives);
+            this.getLifeMap().put(player.getName(), iLives);
 
-            final ArenaTeam respawnTeam = ArenaPlayer.parsePlayer(player.getName())
+            final ArenaTeam respawnTeam = aPlayer
                     .getArenaTeam();
-            if (arena.getArenaConfig().getBoolean(CFG.USES_DEATHMESSAGES)) {
-                arena.broadcast(Language.parse(arena,
+            if (this.arena.getArenaConfig().getBoolean(CFG.USES_DEATHMESSAGES)) {
+                this.arena.broadcast(Language.parse(this.arena,
                         MSG.FIGHT_KILLED_BY_REMAINING,
                         respawnTeam.colorizePlayer(player) + ChatColor.YELLOW,
-                        arena.parseDeathCause(player, event.getEntity()
+                        this.arena.parseDeathCause(player, event.getEntity()
                                         .getLastDamageCause().getCause(),
                                 player.getKiller()), String.valueOf(iLives)));
             }
 
             final List returned;
 
-            if (arena.getArenaConfig().getBoolean(
+            if (this.arena.getArenaConfig().getBoolean(
                     CFG.PLAYER_DROPSINVENTORY)) {
                 returned = InventoryManager.drop(player);
                 event.getDrops().clear();
             } else {
-                returned = new ArrayList<>();
-                returned.addAll(event.getDrops());
+                returned = new ArrayList<>(event.getDrops());
             }
 
-            PACheck.handleRespawn(arena,
-                    ArenaPlayer.parsePlayer(player.getName()), returned);
+            PACheck.handleRespawn(this.arena,
+                    aPlayer, returned);
         }
     }
 
     @Override
     public void commitStart() {
-        parseStart(); // hack the team in before spawning, derp!
-        for (final ArenaTeam team : arena.getTeams()) {
-            SpawnManager.distribute(arena, team);
+        this.parseStart(); // hack the team in before spawning, derp!
+        for (final ArenaTeam team : this.arena.getTeams()) {
+            SpawnManager.distribute(this.arena, team);
         }
     }
 
     @Override
     public void displayInfo(final CommandSender sender) {
         sender.sendMessage("normal lives: "
-                + arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_NLIVES) + " || " +
+                + this.arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_NLIVES) + " || " +
                 "infected lives: "
-                + arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_ILIVES));
+                + this.arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_ILIVES));
     }
 
     @Override
@@ -602,7 +600,7 @@ public PACheck getLives(final PACheck res, final ArenaPlayer aPlayer) {
         if (res.getPriority() <= PRIORITY + 1000) {
             res.setError(
                     this,
-                    String.valueOf(getLifeMap().getOrDefault(aPlayer.getName(), 0))
+                    String.valueOf(this.getLifeMap().getOrDefault(aPlayer.getName(), 0))
             );
         }
         return res;
@@ -612,8 +610,8 @@ public PACheck getLives(final PACheck res, final ArenaPlayer aPlayer) {
     public boolean hasSpawn(final String string) {
 
 
-        if (arena.getArenaConfig().getBoolean(CFG.GENERAL_CLASSSPAWN)) {
-            for (final ArenaClass aClass : arena.getClasses()) {
+        if (this.arena.getArenaConfig().getBoolean(CFG.GENERAL_CLASSSPAWN)) {
+            for (final ArenaClass aClass : this.arena.getClasses()) {
                 if (string.toLowerCase().startsWith(
                         aClass.getName().toLowerCase() + "spawn")) {
                     return true;
@@ -621,13 +619,13 @@ public boolean hasSpawn(final String string) {
             }
         }
 
-        return arena.isFreeForAll() && string.toLowerCase()
+        return this.arena.isFreeForAll() && string.toLowerCase()
                 .startsWith("spawn") || string.toLowerCase().startsWith("infected");
     }
 
     @Override
     public void initate(final Player player) {
-        updateLives(player, arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_NLIVES));
+        this.updateLives(player, this.arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_NLIVES));
     }
 
     @Override
@@ -639,63 +637,60 @@ public boolean isInternal() {
     public void parseLeave(final Player player) {
         if (player == null) {
             PVPArena.instance.getLogger().warning(
-                    getName() + ": player NULL");
+                    this.getName() + ": player NULL");
             return;
         }
-        if (getLifeMap().containsKey(player.getName())) {
-            getLifeMap().remove(player.getName());
-        }
+        this.getLifeMap().remove(player.getName());
     }
 
     @Override
     public void parseStart() {
-        if (arena.getTeam("infected") != null) {
+        if (this.arena.getTeam("infected") != null) {
             return;
         }
         ArenaPlayer infected = null;
         final Random random = new Random();
-        for (final ArenaTeam team : arena.getTeams()) {
+        for (final ArenaTeam team : this.arena.getTeams()) {
             int pos = random.nextInt(team.getTeamMembers().size());
-            arena.getDebugger().i("team " + team.getName() + " random " + pos);
+            this.arena.getDebugger().i("team " + team.getName() + " random " + pos);
             for (final ArenaPlayer ap : team.getTeamMembers()) {
-                arena.getDebugger().i("#" + pos + ": " + ap, ap.getName());
-                getLifeMap().put(ap.getName(),
-                        arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_NLIVES));
+                this.arena.getDebugger().i("#" + pos + ": " + ap, ap.getName());
+                this.getLifeMap().put(ap.getName(),
+                        this.arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_NLIVES));
                 if (pos-- == 0) {
                     infected = ap;
-                    getLifeMap().put(ap.getName(),
-                            arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_ILIVES));
+                    this.getLifeMap().put(ap.getName(),
+                            this.arena.getArenaConfig().getInt(CFG.GOAL_INFECTED_ILIVES));
                 }
                 //break;
             }
         }
         final ArenaTeam infectedTeam = new ArenaTeam("infected", "PINK");
-        for (final ArenaTeam team : arena.getTeams()) {
+        for (final ArenaTeam team : this.arena.getTeams()) {
             if (team.getTeamMembers().contains(infected)) {
-                final PATeamChangeEvent tcEvent = new PATeamChangeEvent(arena, infected.get(), team, infectedTeam);
+                final PATeamChangeEvent tcEvent = new PATeamChangeEvent(this.arena, infected.get(), team, infectedTeam);
                 Bukkit.getPluginManager().callEvent(tcEvent);
-                arena.updateScoreboardTeam(infected.get(), team, infectedTeam);
+                this.arena.updateScoreboardTeam(infected.get(), team, infectedTeam);
                 team.remove(infected);
             }
         }
         infectedTeam.add(infected);
 
-        final ArenaClass infectedClass = arena.getClass("%infected%");
+        final ArenaClass infectedClass = this.arena.getClass("%infected%");
         if (infectedClass != null) {
             infected.setArenaClass(infectedClass);
             InventoryManager.clearInventory(infected.get());
             infectedClass.equip(infected.get());
-            for (final ArenaModule mod : arena.getMods()) {
+            for (final ArenaModule mod : this.arena.getMods()) {
                 mod.parseRespawn(infected.get(), infectedTeam, DamageCause.CUSTOM,
                         infected.get());
             }
         }
 
-        arena.msg(infected.get(), Language.parse(arena, MSG.GOAL_INFECTED_YOU, infected.getName()));
-        arena.broadcast(Language.parse(arena, MSG.GOAL_INFECTED_PLAYER, infected.getName()));
+        this.arena.msg(infected.get(), Language.parse(this.arena, MSG.GOAL_INFECTED_YOU, infected.getName()));
+        this.arena.broadcast(Language.parse(this.arena, MSG.GOAL_INFECTED_PLAYER, infected.getName()));
 
-        final Set spawns = new HashSet<>();
-        spawns.addAll(SpawnManager.getPASpawnsStartingWith(arena, "infected"));
+        final Set spawns = new HashSet<>(SpawnManager.getPASpawnsStartingWith(this.arena, "infected"));
 
         int pos = spawns.size();
 
@@ -705,42 +700,37 @@ public void parseStart() {
                 break;
             }
         }
-        arena.getTeams().add(infectedTeam);
+        this.arena.getTeams().add(infectedTeam);
     }
 
     @Override
     public void reset(final boolean force) {
-        endRunner = null;
-        getLifeMap().clear();
-        arena.getTeams().remove(arena.getTeam("infected"));
+        this.endRunner = null;
+        this.getLifeMap().clear();
+        this.arena.getTeams().remove(this.arena.getTeam("infected"));
     }
 
     @Override
     public void setPlayerLives(final int value) {
-        final Set plrs = new HashSet<>();
-
-        for (final String name : getLifeMap().keySet()) {
-            plrs.add(name);
-        }
+        final Set plrs = new HashSet<>(this.getLifeMap().keySet());
 
         for (final String s : plrs) {
-            getLifeMap().put(s, value);
+            this.getLifeMap().put(s, value);
         }
     }
 
     @Override
     public void setPlayerLives(final ArenaPlayer aPlayer, final int value) {
-        getLifeMap().put(aPlayer.getName(), value);
+        this.getLifeMap().put(aPlayer.getName(), value);
     }
 
     @Override
     public Map timedEnd(final Map scores) {
 
-        for (final ArenaPlayer ap : arena.getFighters()) {
-            double score = getLifeMap().containsKey(ap.getName()) ? getLifeMap().get(ap.getName())
-                    : 0;
+        for (final ArenaPlayer ap : this.arena.getFighters()) {
+            double score = this.getLifeMap().getOrDefault(ap.getName(), 0);
             if (ap.getArenaTeam() != null && "infected".equals(ap.getArenaTeam().getName())) {
-                score *= arena.getFighters().size();
+                score *= this.arena.getFighters().size();
             }
             if (scores.containsKey(ap.getName())) {
                 scores.put(ap.getName(), scores.get(ap.getName()) + score);
@@ -754,6 +744,6 @@ public Map timedEnd(final Map scores) {
 
     @Override
     public void unload(final Player player) {
-        getLifeMap().remove(player.getName());
+        this.getLifeMap().remove(player.getName());
     }
 }

From 8178961d6749c6da610d7c27756ab15901128d0e Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Mon, 20 Jul 2020 22:28:03 +0200
Subject: [PATCH 35/43] v1.15 - fix missing scoreboard color for Infected and
 Tank goals - issue #52

---
 src/net/slipcor/pvparena/arena/Arena.java | 39 ++++++++++++++---------
 1 file changed, 24 insertions(+), 15 deletions(-)

diff --git a/src/net/slipcor/pvparena/arena/Arena.java b/src/net/slipcor/pvparena/arena/Arena.java
index b039047a5..53de2f5ed 100644
--- a/src/net/slipcor/pvparena/arena/Arena.java
+++ b/src/net/slipcor/pvparena/arena/Arena.java
@@ -2343,10 +2343,11 @@ public void updateScoreboards() {
                     }
                 } else {
                     for (ArenaTeam team : this.getTeams()) {
-                        ArenaPlayer randomTeamPlayer = team.getTeamMembers().iterator().next();
-                        currentScoreboard.getObjective("lives")
+                        team.getTeamMembers().stream().findFirst().ifPresent(randomTeamPlayer ->
+                            currentScoreboard.getObjective("lives")
                                 .getScore(team.getName())
-                                .setScore(PACheck.handleGetLives(this, randomTeamPlayer));
+                                .setScore(PACheck.handleGetLives(this, randomTeamPlayer))
+                        );
                     }
                     for (ArenaPlayer ap : this.getEveryone()) {
                         Player player = ap.get();
@@ -2382,27 +2383,35 @@ public void updateScoreboardTeam(final Player player, final ArenaTeam oldTeam, f
             Bukkit.getScheduler().runTaskLater(PVPArena.instance, () -> {
                 board.getTeam(oldTeam.getName()).removeEntry(player.getName());
 
-                for (final Team sTeam : board.getTeams()) {
-                    if (sTeam.getName().equals(newTeam.getName())) {
-                        sTeam.addEntry(player.getName());
-                        return;
-                    }
-                }
+                Team sTeam = board.getTeams().stream()
+                        .filter(t -> t.getName().equals(newTeam.getName()))
+                        .findFirst()
+                        .orElseGet(() -> this.addNewTeam(board, newTeam));
+                sTeam.addEntry(player.getName());
+
                 this.updateScoreboard(player);
             }, 1L);
         } else {
             Scoreboard board = this.getStandardScoreboard();
             board.getTeam(oldTeam.getName()).removeEntry(player.getName());
 
-            for (final Team sTeam : board.getTeams()) {
-                if (sTeam.getName().equals(newTeam.getName())) {
-                    sTeam.addEntry(player.getName());
-                    return;
-                }
-            }
+            Team sTeam = board.getTeams().stream()
+                    .filter(t -> t.getName().equals(newTeam.getName()))
+                    .findFirst()
+                    .orElseGet(() -> this.addNewTeam(board, newTeam));
+            sTeam.addEntry(player.getName());
         }
     }
 
+    private Team addNewTeam(Scoreboard board, ArenaTeam newTeam) {
+        final Team sTeam = board.registerNewTeam(newTeam.getName());
+        sTeam.setPrefix(newTeam.getColor().toString());
+        sTeam.setSuffix(ChatColor.RESET.toString());
+        sTeam.setColor(newTeam.getColor());
+        sTeam.setCanSeeFriendlyInvisibles(!this.isFreeForAll());
+        return sTeam;
+    }
+
     public YamlConfiguration getLanguage() {
         return language;
     }

From a733c08fd993d8396e1d7c590196e914b26d44c1 Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Fri, 31 Jul 2020 18:36:18 +0200
Subject: [PATCH 36/43] v1.15 - fix color management and autocompletion for
 teams command

---
 src/net/slipcor/pvparena/commands/PAA_Teams.java | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/net/slipcor/pvparena/commands/PAA_Teams.java b/src/net/slipcor/pvparena/commands/PAA_Teams.java
index fd8ece169..627f1043a 100644
--- a/src/net/slipcor/pvparena/commands/PAA_Teams.java
+++ b/src/net/slipcor/pvparena/commands/PAA_Teams.java
@@ -8,9 +8,9 @@
 import net.slipcor.pvparena.core.Language.MSG;
 import net.slipcor.pvparena.core.StringParser;
 import org.bukkit.ChatColor;
-import org.bukkit.DyeColor;
 import org.bukkit.command.CommandSender;
 
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
@@ -71,10 +71,10 @@ public void commit(final Arena arena, final CommandSender sender, final String[]
         } else if ("add".equals(args[0])) {
             try {
 
-                final DyeColor dColor = DyeColor.valueOf(args[2].toUpperCase());
-                final ArenaTeam newTeam = new ArenaTeam(args[1], dColor.name());
+                final ChatColor color = ChatColor.valueOf(args[2].toUpperCase());
+                final ArenaTeam newTeam = new ArenaTeam(args[1], color.name());
                 arena.getTeams().add(newTeam);
-                arena.getArenaConfig().setManually("teams." + newTeam.getName(), dColor.name());
+                arena.getArenaConfig().setManually("teams." + newTeam.getName(), color.name());
                 arena.getArenaConfig().save();
 
                 arena.msg(sender, Language.parse(arena, MSG.TEAMS_ADD, newTeam.getColoredName()));
@@ -128,7 +128,9 @@ public CommandTree getSubs(final Arena arena) {
         }
         for (final String team : arena.getTeamNames()) {
             result.define(new String[]{"remove", team});
-            result.define(new String[]{"set", team});
+            Arrays.stream(ChatColor.values()).forEach(color ->
+                    result.define(new String[]{"set", team, color.name()})
+            );
         }
         return result;
     }

From 4ada2826654755285d4f163b1c71efb762624445 Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Fri, 7 Aug 2020 18:03:00 +0200
Subject: [PATCH 37/43] v1.15 - fix order of region remove command

---
 src/net/slipcor/pvparena/commands/PAA_Region.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/net/slipcor/pvparena/commands/PAA_Region.java b/src/net/slipcor/pvparena/commands/PAA_Region.java
index 39d2f297a..3903cfc4b 100644
--- a/src/net/slipcor/pvparena/commands/PAA_Region.java
+++ b/src/net/slipcor/pvparena/commands/PAA_Region.java
@@ -89,7 +89,7 @@ public void commit(final Arena arena, final CommandSender sender, final String[]
             region.getShape().showBorder((Player) sender);
             return;
         }
-        if (args.length == 2 && args[0].equalsIgnoreCase("remove")) {
+        if (args.length == 2 && args[1].equalsIgnoreCase("remove")) {
             // usage: /pa {arenaname} region remove [regionname] | remove a region
             final ArenaRegion region = arena.getRegion(args[1]);
 

From 5e9588d95d911dc2e20278b3f629a1852b5690cf Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Mon, 10 Aug 2020 22:16:04 +0200
Subject: [PATCH 38/43] v1.15 - fix PlayerKillRewards graduallyDown option and
 equipping error

---
 .../slipcor/pvparena/arena/ArenaClass.java    |  22 +-
 .../pvparena/goals/GoalPlayerKillReward.java  | 261 +++++++++---------
 2 files changed, 152 insertions(+), 131 deletions(-)

diff --git a/src/net/slipcor/pvparena/arena/ArenaClass.java b/src/net/slipcor/pvparena/arena/ArenaClass.java
index b35cdfcb1..89e6ff9fd 100644
--- a/src/net/slipcor/pvparena/arena/ArenaClass.java
+++ b/src/net/slipcor/pvparena/arena/ArenaClass.java
@@ -6,6 +6,7 @@
 import org.bukkit.Bukkit;
 import org.bukkit.Material;
 import org.bukkit.block.Chest;
+import org.bukkit.configuration.ConfigurationSection;
 import org.bukkit.configuration.file.YamlConfiguration;
 import org.bukkit.entity.EntityType;
 import org.bukkit.entity.Player;
@@ -127,12 +128,10 @@ public static void addGlobalClasses() {
             ItemStack[] armors;
 
             try {
-                items = getItemStacksFromConfig(cfg.getConfigurationSection("classes").getConfigurationSection(className)
-                        .getList("items"));
-                offHand = getItemStacksFromConfig(cfg.getConfigurationSection("classes").getConfigurationSection(className)
-                        .getList("items"))[0];
-                armors = getItemStacksFromConfig(cfg.getConfigurationSection("classes").getConfigurationSection(className)
-                        .getList("items"));
+                ConfigurationSection classesCfg = cfg.getConfigurationSection("classes").getConfigurationSection(className);
+                items = getItemStacksFromConfig(classesCfg.getList("items"));
+                offHand = getItemStacksFromConfig(classesCfg.getList("items"))[0];
+                armors = getItemStacksFromConfig(classesCfg.getList("items"));
             } catch (final Exception e) {
                 Bukkit.getLogger().severe(
                         "[PVP Arena] Error while parsing class, skipping: "
@@ -195,8 +194,15 @@ public void run() {
     }
 
     public static void equip(final Player player, final ItemStack[][] itemArray) {
-        player.getInventory().setItemInOffHand(itemArray[1][0]);
-        player.getInventory().setArmorContents(itemArray[2]);
+        try {
+            player.getInventory().setItemInOffHand(itemArray[1][0]);
+        } catch(ArrayIndexOutOfBoundsException e) {
+            player.getInventory().setItemInOffHand(new ItemStack(Material.AIR));
+        }
+
+        for(ItemStack itemStack : itemArray[2]) {
+            equipArmor(itemStack, player.getInventory());
+        }
 
         for (final ItemStack item : itemArray[0]) {
             if (item.hasItemMeta() && item.getItemMeta().hasDisplayName() && "SPAWN".equals(item.getItemMeta().getDisplayName())) {
diff --git a/src/net/slipcor/pvparena/goals/GoalPlayerKillReward.java b/src/net/slipcor/pvparena/goals/GoalPlayerKillReward.java
index e2dd3a2d8..09d910d05 100644
--- a/src/net/slipcor/pvparena/goals/GoalPlayerKillReward.java
+++ b/src/net/slipcor/pvparena/goals/GoalPlayerKillReward.java
@@ -13,7 +13,6 @@
 import net.slipcor.pvparena.core.Debug;
 import net.slipcor.pvparena.core.Language;
 import net.slipcor.pvparena.core.Language.MSG;
-import net.slipcor.pvparena.core.StringParser;
 import net.slipcor.pvparena.events.PAGoalEvent;
 import net.slipcor.pvparena.loadables.ArenaGoal;
 import net.slipcor.pvparena.loadables.ArenaModuleManager;
@@ -33,6 +32,8 @@
 
 import java.util.*;
 
+import static net.slipcor.pvparena.core.Utils.getSerializableItemStacks;
+
 /**
  * 
  * Arena Goal class "PlayerKillreward"
@@ -48,7 +49,7 @@
 public class GoalPlayerKillReward extends ArenaGoal {
     public GoalPlayerKillReward() {
         super("PlayerKillReward");
-        debug = new Debug(102);
+        this.debug = new Debug(102);
     }
 
     private Map itemMapCubed;
@@ -64,7 +65,7 @@ public String version() {
 
     @Override
     public boolean allowsJoinInBattle() {
-        return arena.getArenaConfig().getBoolean(CFG.PERMS_JOININBATTLE);
+        return this.arena.getArenaConfig().getBoolean(CFG.PERMS_JOININBATTLE);
     }
 
     @Override
@@ -100,8 +101,8 @@ public PACheck checkEnd(final PACheck res) {
             return res;
         }
 
-        if (!arena.isFreeForAll()) {
-            final int count = TeamManager.countActiveTeams(arena);
+        if (!this.arena.isFreeForAll()) {
+            final int count = TeamManager.countActiveTeams(this.arena);
 
             if (count <= 1) {
                 res.setPriority(this, PRIORITY); // yep. only one team left. go!
@@ -109,7 +110,7 @@ public PACheck checkEnd(final PACheck res) {
             return res;
         }
 
-        final int count = getLifeMap().size();
+        final int count = this.getLifeMap().size();
 
         if (count <= 1) {
             res.setPriority(this, PRIORITY); // yep. only one player left. go!
@@ -123,11 +124,11 @@ public PACheck checkEnd(final PACheck res) {
 
     @Override
     public String checkForMissingSpawns(final Set list) {
-        if (!arena.isFreeForAll()) {
-            return checkForMissingTeamSpawn(list);
+        if (!this.arena.isFreeForAll()) {
+            return this.checkForMissingTeamSpawn(list);
         }
 
-        return checkForMissingSpawn(list);
+        return this.checkForMissingSpawn(list);
     }
 
     @Override
@@ -136,12 +137,12 @@ public PACheck checkJoin(final CommandSender sender, final PACheck res, final St
             return res;
         }
 
-        final int maxPlayers = arena.getArenaConfig().getInt(CFG.READY_MAXPLAYERS);
-        final int maxTeamPlayers = arena.getArenaConfig().getInt(
+        final int maxPlayers = this.arena.getArenaConfig().getInt(CFG.READY_MAXPLAYERS);
+        final int maxTeamPlayers = this.arena.getArenaConfig().getInt(
                 CFG.READY_MAXTEAMPLAYERS);
 
-        if (maxPlayers > 0 && arena.getFighters().size() >= maxPlayers) {
-            res.setError(this, Language.parse(arena, MSG.ERROR_JOIN_ARENA_FULL));
+        if (maxPlayers > 0 && this.arena.getFighters().size() >= maxPlayers) {
+            res.setError(this, Language.parse(this.arena, MSG.ERROR_JOIN_ARENA_FULL));
             return res;
         }
 
@@ -149,12 +150,12 @@ public PACheck checkJoin(final CommandSender sender, final PACheck res, final St
             return res;
         }
 
-        if (!arena.isFreeForAll()) {
-            final ArenaTeam team = arena.getTeam(args[0]);
+        if (!this.arena.isFreeForAll()) {
+            final ArenaTeam team = this.arena.getTeam(args[0]);
 
             if (team != null && maxTeamPlayers > 0
                     && team.getTeamMembers().size() >= maxTeamPlayers) {
-                res.setError(this, Language.parse(arena, MSG.ERROR_JOIN_TEAM_FULL, team.getName()));
+                res.setError(this, Language.parse(this.arena, MSG.ERROR_JOIN_TEAM_FULL, team.getName()));
                 return res;
             }
         }
@@ -165,7 +166,7 @@ public PACheck checkJoin(final CommandSender sender, final PACheck res, final St
 
     @Override
     public void commitCommand(final CommandSender sender, final String[] args) {
-        if (!AbstractArenaCommand.argCountValid(sender, arena, args, new Integer[]{2,
+        if (!AbstractArenaCommand.argCountValid(sender, this.arena, args, new Integer[]{2,
                 3})) {
             return;
         }
@@ -177,16 +178,16 @@ public void commitCommand(final CommandSender sender, final String[] args) {
         try {
             value = Integer.parseInt(args[1]);
         } catch (final Exception e) {
-            arena.msg(sender, Language.parse(arena, MSG.ERROR_NOT_NUMERIC, args[1]));
+            this.arena.msg(sender, Language.parse(this.arena, MSG.ERROR_NOT_NUMERIC, args[1]));
             return;
         }
         if (args.length > 2) {
-            getItemMap().remove(value);
-            arena.msg(sender,
-                    Language.parse(arena, MSG.GOAL_KILLREWARD_REMOVED, args[1]));
+            this.getItemMap().remove(value);
+            this.arena.msg(sender,
+                    Language.parse(this.arena, MSG.GOAL_KILLREWARD_REMOVED, args[1]));
         } else {
             if (!(sender instanceof Player)) {
-                Arena.pmsg(sender, Language.parse(arena, MSG.ERROR_ONLY_PLAYERS));
+                Arena.pmsg(sender, Language.parse(this.arena, MSG.ERROR_ONLY_PLAYERS));
                 return;
             }
             final Player player = (Player) sender;
@@ -197,80 +198,76 @@ public void commitCommand(final CommandSender sender, final String[] args) {
                     player.getInventory().getArmorContents()
             };
 
-            getItemMap().put(value, content);
-            arena.msg(sender, Language.parse(arena, MSG.GOAL_KILLREWARD_ADDED,
+            this.getItemMap().put(value, content);
+            this.arena.msg(sender, Language.parse(this.arena, MSG.GOAL_KILLREWARD_ADDED,
                     args[1]));
 
         }
 
-        saveItems();
+        this.saveItems();
     }
 
     @Override
     public void commitEnd(final boolean force) {
-        if (endRunner != null) {
+        if (this.endRunner != null) {
             return;
         }
-        if (arena.realEndRunner != null) {
-            arena.getDebugger().i("[PKW] already ending");
+        if (this.arena.realEndRunner != null) {
+            this.arena.getDebugger().i("[PKW] already ending");
             return;
         }
-        final PAGoalEvent gEvent = new PAGoalEvent(arena, this, "");
+        final PAGoalEvent gEvent = new PAGoalEvent(this.arena, this, "");
         Bukkit.getPluginManager().callEvent(gEvent);
 
-        for (final ArenaTeam team : arena.getTeams()) {
+        for (final ArenaTeam team : this.arena.getTeams()) {
             for (final ArenaPlayer ap : team.getTeamMembers()) {
                 if (ap.getStatus() != Status.FIGHT) {
                     continue;
                 }
 
-                if (arena.isFreeForAll()) {
-                    ArenaModuleManager.announce(arena,
-                            Language.parse(arena, MSG.PLAYER_HAS_WON, ap.getName()),
+                if (this.arena.isFreeForAll()) {
+                    ArenaModuleManager.announce(this.arena,
+                            Language.parse(this.arena, MSG.PLAYER_HAS_WON, ap.getName()),
                             "END");
 
-                    ArenaModuleManager.announce(arena,
-                            Language.parse(arena, MSG.PLAYER_HAS_WON, ap.getName()),
+                    ArenaModuleManager.announce(this.arena,
+                            Language.parse(this.arena, MSG.PLAYER_HAS_WON, ap.getName()),
                             "WINNER");
 
-                    arena.broadcast(Language.parse(arena, MSG.PLAYER_HAS_WON,
+                    this.arena.broadcast(Language.parse(this.arena, MSG.PLAYER_HAS_WON,
                             ap.getName()));
                 } else {
                     ArenaModuleManager.announce(
-                            arena,
-                            Language.parse(arena, MSG.TEAM_HAS_WON,
+                            this.arena,
+                            Language.parse(this.arena, MSG.TEAM_HAS_WON,
                                     team.getColoredName()), "END");
 
                     ArenaModuleManager.announce(
-                            arena,
-                            Language.parse(arena, MSG.TEAM_HAS_WON,
+                            this.arena,
+                            Language.parse(this.arena, MSG.TEAM_HAS_WON,
                                     team.getColoredName()), "WINNER");
 
-                    arena.broadcast(Language.parse(arena, MSG.TEAM_HAS_WON,
+                    this.arena.broadcast(Language.parse(this.arena, MSG.TEAM_HAS_WON,
                             team.getColoredName()));
                     break;
                 }
             }
 
-            if (ArenaModuleManager.commitEnd(arena, team)) {
+            if (ArenaModuleManager.commitEnd(this.arena, team)) {
                 return;
             }
         }
-        endRunner = new EndRunnable(arena, arena.getArenaConfig().getInt(
+        this.endRunner = new EndRunnable(this.arena, this.arena.getArenaConfig().getInt(
                 CFG.TIME_ENDCOUNTDOWN));
     }
 
     @Override
     public void parsePlayerDeath(final Player player, final EntityDamageEvent event) {
-        if (!getLifeMap().containsKey(player.getName())) {
+        if (!this.getLifeMap().containsKey(player.getName())) {
             return;
         }
-        if (arena.getArenaConfig().getBoolean(CFG.GOAL_PLAYERKILLREWARD_GRADUALLYDOWN)) {
-            int lives = getLifeMap().get(player.getName());
-            lives++;
-            getLifeMap().put(player.getName(), lives);
-        } else {
-            getLifeMap().put(player.getName(), getMaxInt());
+        if (!this.arena.getArenaConfig().getBoolean(CFG.GOAL_PLAYERKILLREWARD_GRADUALLYDOWN)) {
+            this.getLifeMap().put(player.getName(), this.getDefaultRemainingKills());
         }
 
 
@@ -279,7 +276,7 @@ class ResetRunnable implements Runnable {
 
             @Override
             public void run() {
-                reset(player);
+                this.reset(this.player);
             }
 
             ResetRunnable(final Player player) {
@@ -287,19 +284,19 @@ public void run() {
             }
 
             private void reset(final Player player) {
-                if (!getLifeMap().containsKey(player.getName())) {
+                if (!GoalPlayerKillReward.this.getLifeMap().containsKey(player.getName())) {
                     return;
                 }
 
-                final int iLives = getLifeMap().get(player.getName());
+                final int iLives = GoalPlayerKillReward.this.getLifeMap().get(player.getName());
                 if (ArenaPlayer.parsePlayer(player.getName()).getStatus() != Status.FIGHT) {
                     return;
                 }
-                if (!arena.getArenaConfig().getBoolean(CFG.GOAL_PLAYERKILLREWARD_ONLYGIVE)) {
+                if (!GoalPlayerKillReward.this.arena.getArenaConfig().getBoolean(CFG.GOAL_PLAYERKILLREWARD_ONLYGIVE)) {
                     InventoryManager.clearInventory(player);
                 }
-                if (getItemMap().containsKey(iLives)) {
-                    ArenaClass.equip(player, getItemMap().get(iLives));
+                if (GoalPlayerKillReward.this.getItemMap().containsKey(iLives)) {
+                    ArenaClass.equip(player, GoalPlayerKillReward.this.getItemMap().get(iLives));
                 } else {
                     ArenaPlayer.parsePlayer(player.getName()).getArenaClass()
                             .equip(player);
@@ -315,21 +312,21 @@ private void reset(final Player player) {
             return;
         }
 
-        int iLives = getLifeMap().get(killer.getName());
-        arena.getDebugger().i("kills to go for " + killer.getName() + ": " + iLives, killer);
+        int iLives = this.getLifeMap().get(killer.getName());
+        this.arena.getDebugger().i("kills to go for " + killer.getName() + ": " + iLives, killer);
         if (iLives <= 1) {
             // player has won!
-            final PAGoalEvent gEvent = new PAGoalEvent(arena, this, "trigger:" + killer.getName(), "playerKill:" + killer.getName() + ':' + player.getName(), "playerDeath:" + player.getName());
+            final PAGoalEvent gEvent = new PAGoalEvent(this.arena, this, "trigger:" + killer.getName(), "playerKill:" + killer.getName() + ':' + player.getName(), "playerDeath:" + player.getName());
             Bukkit.getPluginManager().callEvent(gEvent);
             final Set plrs = new HashSet<>();
-            for (final ArenaPlayer ap : arena.getFighters()) {
+            for (final ArenaPlayer ap : this.arena.getFighters()) {
                 if (ap.getName().equals(killer.getName())) {
                     continue;
                 }
                 plrs.add(ap);
             }
             for (final ArenaPlayer ap : plrs) {
-                getLifeMap().remove(ap.getName());
+                this.getLifeMap().remove(ap.getName());
 				/*
 				arena.getDebugger().i("faking player death", ap.get());
 				arena.removePlayer(ap.get(), CFG.TP_LOSE.toString(), true,
@@ -341,33 +338,33 @@ private void reset(final Player player) {
                 //PlayerState.fullReset(arena, ap.get());
             }
 
-            if (ArenaManager.checkAndCommit(arena, false)) {
+            if (ArenaManager.checkAndCommit(this.arena, false)) {
                 return;
             }
-            PACheck.handleEnd(arena, false);
+            PACheck.handleEnd(this.arena, false);
         } else {
-            final PAGoalEvent gEvent = new PAGoalEvent(arena, this, "playerKill:" + killer.getName() + ':' + player.getName(), "playerDeath:" + player.getName());
+            final PAGoalEvent gEvent = new PAGoalEvent(this.arena, this, "playerKill:" + killer.getName() + ':' + player.getName(), "playerDeath:" + player.getName());
             Bukkit.getPluginManager().callEvent(gEvent);
             iLives--;
-            getLifeMap().put(killer.getName(), iLives);
+            this.getLifeMap().put(killer.getName(), iLives);
             Bukkit.getScheduler().runTaskLater(PVPArena.instance,
                     new ResetRunnable(killer), 4L);
         }
     }
 
     private Map getItemMap() {
-        if (itemMapCubed == null) {
-            itemMapCubed = new HashMap<>();
+        if (this.itemMapCubed == null) {
+            this.itemMapCubed = new HashMap<>();
         }
-        return itemMapCubed;
+        return this.itemMapCubed;
     }
 
     @Override
     public boolean hasSpawn(final String string) {
-        if (arena.isFreeForAll()) {
+        if (this.arena.isFreeForAll()) {
 
-            if (arena.getArenaConfig().getBoolean(CFG.GENERAL_CLASSSPAWN)) {
-                for (final ArenaClass aClass : arena.getClasses()) {
+            if (this.arena.getArenaConfig().getBoolean(CFG.GENERAL_CLASSSPAWN)) {
+                for (final ArenaClass aClass : this.arena.getClasses()) {
                     if (string.toLowerCase().startsWith(
                             aClass.getName().toLowerCase() + "spawn")) {
                         return true;
@@ -376,14 +373,14 @@ public boolean hasSpawn(final String string) {
             }
             return string.toLowerCase().startsWith("spawn");
         }
-        for (final String teamName : arena.getTeamNames()) {
+        for (final String teamName : this.arena.getTeamNames()) {
             if (string.toLowerCase().startsWith(
                     teamName.toLowerCase() + "spawn")) {
                 return true;
             }
 
-            if (arena.getArenaConfig().getBoolean(CFG.GENERAL_CLASSSPAWN)) {
-                for (final ArenaClass aClass : arena.getClasses()) {
+            if (this.arena.getArenaConfig().getBoolean(CFG.GENERAL_CLASSSPAWN)) {
+                for (final ArenaClass aClass : this.arena.getClasses()) {
                     if (string.toLowerCase().startsWith(teamName.toLowerCase() +
                             aClass.getName().toLowerCase() + "spawn")) {
                         return true;
@@ -396,12 +393,12 @@ public boolean hasSpawn(final String string) {
 
     @Override
     public void initate(final Player player) {
-        getLifeMap().put(player.getName(), getMaxInt());
+        this.getLifeMap().put(player.getName(), this.getDefaultRemainingKills());
     }
 
-    private int getMaxInt() {
+    private int getDefaultRemainingKills() {
         int max = 0;
-        for (final int i : getItemMap().keySet()) {
+        for (final int i : this.getItemMap().keySet()) {
             max = Math.max(max, i);
         }
         return max + 1;
@@ -416,43 +413,41 @@ public boolean isInternal() {
     public void parseLeave(final Player player) {
         if (player == null) {
             PVPArena.instance.getLogger().warning(
-                    getName() + ": player NULL");
+                    this.getName() + ": player NULL");
             return;
         }
-        if (getLifeMap().containsKey(player.getName())) {
-            getLifeMap().remove(player.getName());
-        }
+        this.getLifeMap().remove(player.getName());
     }
 
     @Override
     public void parseStart() {
-        for (final ArenaTeam team : arena.getTeams()) {
+        for (final ArenaTeam team : this.arena.getTeams()) {
             for (final ArenaPlayer ap : team.getTeamMembers()) {
-                getLifeMap().put(ap.getName(), getMaxInt());
+                this.getLifeMap().put(ap.getName(), this.getDefaultRemainingKills());
             }
         }
     }
 
     @Override
     public void reset(final boolean force) {
-        endRunner = null;
-        getLifeMap().clear();
+        this.endRunner = null;
+        this.getLifeMap().clear();
     }
 
     @Override
     public void setDefaults(final YamlConfiguration config) {
-        if (!arena.isFreeForAll()) {
+        if (!this.arena.isFreeForAll()) {
             if (config.get("teams.free") != null) {
                 config.set("teams", null);
             }
             if (config.get("teams") == null) {
-                arena.getDebugger().i("no teams defined, adding custom red and blue!");
+                this.arena.getDebugger().i("no teams defined, adding custom red and blue!");
                 config.addDefault("teams.red", ChatColor.RED.name());
                 config.addDefault("teams.blue", ChatColor.BLUE.name());
             }
-            if (arena.getArenaConfig().getBoolean(CFG.GOAL_FLAGS_WOOLFLAGHEAD)
+            if (this.arena.getArenaConfig().getBoolean(CFG.GOAL_FLAGS_WOOLFLAGHEAD)
                     && config.get("flagColors") == null) {
-                arena.getDebugger().i("no flagheads defined, adding white and black!");
+                this.arena.getDebugger().i("no flagheads defined, adding white and black!");
                 config.addDefault("flagColors.red", "WHITE");
                 config.addDefault("flagColors.blue", "BLACK");
             }
@@ -465,98 +460,91 @@ public void setDefaults(final YamlConfiguration config) {
         if (cs != null) {
             for (final String line : cs.getKeys(false)) {
                 try {
-                    getItemMap().put(Integer.parseInt(line.substring(2)),
+                    this.getItemMap().put(Integer.parseInt(line.substring(2)),
                         new ItemStack[][] {
                             cs.getList(line + ".items").toArray(new ItemStack[0]),
                             cs.getList(line + ".offhand").toArray(new ItemStack[]{new ItemStack(Material.AIR, 1)}),
                             cs.getList(line + ".armor").toArray(new ItemStack[0])
                         });
-                } catch (final Exception e) {
+                } catch (final Exception ignored) {
                 }
             }
         }
 
-        if (getItemMap().size() < 1) {
+        if (this.getItemMap().size() < 1) {
 
-            getItemMap().put(5, new ItemStack[][]{
-                        new ItemStack[]{},
-                        new ItemStack[]{},
+            this.getItemMap().put(5, new ItemStack[][]{
+                        new ItemStack[]{new ItemStack(Material.WOODEN_SWORD, 1)},
+                        new ItemStack[]{new ItemStack(Material.AIR, 1)},
                         new ItemStack[]{
                                 new ItemStack(Material.LEATHER_HELMET, 1),
                                 new ItemStack(Material.LEATHER_CHESTPLATE, 1),
                                 new ItemStack(Material.LEATHER_LEGGINGS, 1),
                                 new ItemStack(Material.LEATHER_BOOTS, 1),
-                                new ItemStack(Material.WOODEN_SWORD, 1)
                         },
                     });
-            getItemMap().put(4, new ItemStack[][]{
-                    new ItemStack[]{},
+            this.getItemMap().put(4, new ItemStack[][]{
+                    new ItemStack[]{new ItemStack(Material.STONE_SWORD, 1)},
                     new ItemStack[]{new ItemStack(Material.AIR, 1)},
                     new ItemStack[]{
                             new ItemStack(Material.CHAINMAIL_HELMET, 1),
                             new ItemStack(Material.CHAINMAIL_CHESTPLATE, 1),
                             new ItemStack(Material.CHAINMAIL_LEGGINGS, 1),
                             new ItemStack(Material.CHAINMAIL_BOOTS, 1),
-                            new ItemStack(Material.STONE_SWORD, 1)
                     },
             });
-            getItemMap().put(3, new ItemStack[][]{
-                    new ItemStack[]{},
+            this.getItemMap().put(3, new ItemStack[][]{
+                    new ItemStack[]{new ItemStack(Material.IRON_SWORD, 1)},
                     new ItemStack[]{new ItemStack(Material.AIR, 1)},
                     new ItemStack[]{
                             new ItemStack(Material.GOLDEN_HELMET, 1),
                             new ItemStack(Material.GOLDEN_CHESTPLATE, 1),
                             new ItemStack(Material.GOLDEN_LEGGINGS, 1),
                             new ItemStack(Material.GOLDEN_BOOTS, 1),
-                            new ItemStack(Material.IRON_SWORD, 1)
                     },
             });
-            getItemMap().put(2, new ItemStack[][]{
-                    new ItemStack[]{},
+            this.getItemMap().put(2, new ItemStack[][]{
+                    new ItemStack[]{new ItemStack(Material.DIAMOND_SWORD, 1)},
                     new ItemStack[]{new ItemStack(Material.AIR, 1)},
                     new ItemStack[]{
                             new ItemStack(Material.IRON_HELMET, 1),
                             new ItemStack(Material.IRON_CHESTPLATE, 1),
                             new ItemStack(Material.IRON_LEGGINGS, 1),
                             new ItemStack(Material.IRON_BOOTS, 1),
-                            new ItemStack(Material.DIAMOND_SWORD, 1)
                     },
             });
-            getItemMap().put(1, new ItemStack[][]{
-                    new ItemStack[]{},
+            this.getItemMap().put(1, new ItemStack[][]{
+                    new ItemStack[]{new ItemStack(Material.DIAMOND_SWORD, 1)},
                     new ItemStack[]{new ItemStack(Material.AIR, 1)},
                     new ItemStack[]{
                             new ItemStack(Material.DIAMOND_HELMET, 1),
                             new ItemStack(Material.DIAMOND_CHESTPLATE, 1),
                             new ItemStack(Material.DIAMOND_LEGGINGS, 1),
                             new ItemStack(Material.DIAMOND_BOOTS, 1),
-                            new ItemStack(Material.DIAMOND_SWORD, 1)
                     },
             });
 
-            saveItems();
+            this.saveItems();
         }
     }
 
     private void saveItems() {
-        for (final int i : getItemMap().keySet()) {
-            arena.getArenaConfig().setManually("goal.playerkillrewards.kr" + i+".items",
-                    getItemMap().get(i)[0]);
-            arena.getArenaConfig().setManually("goal.playerkillrewards.kr" + i+".offhand",
-                    getItemMap().get(i)[1]);
-            arena.getArenaConfig().setManually("goal.playerkillrewards.kr" + i+".armor",
-                    getItemMap().get(i)[2]);
-        }
-        arena.getArenaConfig().save();
+        for (final int i : this.getItemMap().keySet()) {
+            this.arena.getArenaConfig().setManually("goal.playerkillrewards.kr" + i+".items",
+                    getSerializableItemStacks(this.getItemMap().get(i)[0]));
+            this.arena.getArenaConfig().setManually("goal.playerkillrewards.kr" + i+".offhand",
+                    getSerializableItemStacks(this.getItemMap().get(i)[1]));
+            this.arena.getArenaConfig().setManually("goal.playerkillrewards.kr" + i+".armor",
+                    getSerializableItemStacks(this.getItemMap().get(i)[2]));
+        }
+        this.arena.getArenaConfig().save();
     }
 
     @Override
     public Map timedEnd(final Map scores) {
 
-        for (final ArenaPlayer ap : arena.getFighters()) {
-            double score = getMaxInt()
-                    - (getLifeMap().containsKey(ap.getName()) ? getLifeMap()
-                    .get(ap.getName()) : 0);
+        for (final ArenaPlayer ap : this.arena.getFighters()) {
+            double score = this.getDefaultRemainingKills() - (this.getLifeMap().getOrDefault(ap.getName(), 0));
             if (scores.containsKey(ap.getName())) {
                 scores.put(ap.getName(), scores.get(ap.getName()) + score);
             } else {
@@ -567,8 +555,35 @@ public Map timedEnd(final Map scores) {
         return scores;
     }
 
+    @Override
+    public PACheck getLives(PACheck res, ArenaPlayer player) {
+        if (res.getPriority() <= PRIORITY + 1000) {
+            if (this.arena.isFreeForAll()) {
+                res.setError(
+                        this, String.valueOf(this.getLifeMap().getOrDefault(player.getName(), 0))
+                );
+            } else {
+                if (this.getLifeMap().containsKey(player.getArenaTeam().getName())) {
+                    res.setError(this, String.valueOf(this.getLifeMap().get(player.getName())));
+                } else {
+
+                    int sum = 0;
+
+                    for (final ArenaPlayer ap : player.getArenaTeam().getTeamMembers()) {
+                        if (this.getLifeMap().containsKey(ap.getName())) {
+                            sum += this.getLifeMap().get(ap.getName());
+                        }
+                    }
+
+                    res.setError(this, String.valueOf(sum));
+                }
+            }
+        }
+        return res;
+    }
+
     @Override
     public void unload(final Player player) {
-        getLifeMap().remove(player.getName());
+        this.getLifeMap().remove(player.getName());
     }
 }

From 788f8fe618ef966e0bb704dc8e8fe9737f3b1062 Mon Sep 17 00:00:00 2001
From: Eredrim 
Date: Thu, 25 Jun 2020 18:35:08 +0200
Subject: [PATCH 39/43] creating getting started documentation

---
 doc/commands/gamemode.md |   8 +--
 doc/creation.md          |  61 --------------------
 doc/getting-started.md   | 120 +++++++++++++++++++++++++++++++++++++++
 doc/goals.md             |  26 +++++++++
 doc/modules.md           |  69 ++++++++++++++++++++++
 doc/update-version.md    |  46 +++++++++++++++
 readme.md                | 118 ++++++++++++++------------------------
 7 files changed, 305 insertions(+), 143 deletions(-)
 delete mode 100644 doc/creation.md
 create mode 100644 doc/getting-started.md
 create mode 100644 doc/goals.md
 create mode 100644 doc/modules.md

diff --git a/doc/commands/gamemode.md b/doc/commands/gamemode.md
index 7bc7e9bac..8462fd2fb 100644
--- a/doc/commands/gamemode.md
+++ b/doc/commands/gamemode.md
@@ -7,12 +7,8 @@ The gamemode defines the general play mode. Free For All or Team Play ?
 ## Usage Examples
 Command |  Definition
 ------------- | -------------
-/pa ctf gamemode ctf | set the gamemode of arena "ctf" to "team"
-/pa free !gm free    | set the gamemode of arena "free" to "free"
-
-## Hazards
-
-Messing up here results in strange game logic interpretations, because several things are based on the decision if we have teams or not.
+/pa ctf gamemode team | set the gamemode of arena "ctf" to "team"
+/pa ffa !gm free    | set the gamemode of arena "ffa" to "free"
 
 ## Details
 
diff --git a/doc/creation.md b/doc/creation.md
deleted file mode 100644
index 8f502fb2e..000000000
--- a/doc/creation.md
+++ /dev/null
@@ -1,61 +0,0 @@
-
-## Basic creation
-
-_\[Required] (Optional) Arena name is optional if you are inside an arena or in edit mode, but if you have more than one arena it is required._
-
-### 1. Create the arena.
-
-`/pa create [Arena Name] (Legacy Type)`
-
-Valid types are: 
-- team 
-- teamdm 
-- dm 
-- free 
-- ctf 
-- ctp 
-- spleef 
-- tank
-- sabotage
-
-### 2. Set spawns for the arena.
-
-/pa (Arena Name) spawn [spawntype]
-Types are: [team]spawn / [team]lounge / spectator / spawn[x] (ffa only)
-
-By default you need: 2 spawns (red & blue) / 2 lounges (red & blue) / spectator zone.
-
-### 3. Create the battle region.
-
-`/pa (Arena Name) region`
-
-The default region setting tool is a stick. Set your region with left and right click. 
-
-Then:
-
-`/pa (Arena Name) region [Region Name] (Region Shape)`
-
-Valid shape types: 
-
-- cuboid 
-- spheric 
-- cylindric
-
-### 4. Place required items in the lounge
-
-Simply place the signs and on the first line put the class names.
-
-Default classes are: Swordsman / Tank / Pyro / Ranger
-
-Add more classes with the [class command](commands/class.md)
-
-Place the signs in each lobby, and an iron block (configurable). The iron block is the default ready block, and you push it when your ready to start the match.
-
-:triangular_flag_on_post: Tip : You can set a default class using the config parameter `autoClass`.
-
-### 5. Join the arena!
-
-`/pa [Arena Name] (join) (teamname)`
-
-
-See the [video tutorial](https://www.youtube.com/watch?v=yyPJ6vlv09s)
\ No newline at end of file
diff --git a/doc/getting-started.md b/doc/getting-started.md
new file mode 100644
index 000000000..629dd43ac
--- /dev/null
+++ b/doc/getting-started.md
@@ -0,0 +1,120 @@
+
+## Getting Started
+
+
+ +> **🚩 Syntax tip:** +> [required] indicates a required parameter +> (optional) indicates an optional parameter +> + + +### Foreword: what's an arena? + +Before creating your first arena, you have to understand what's. +Arena is immaterial, it's a game configuration you create with goals, teams, classes, etc. It references your arena +config file created at `/plugins/pvparena/yourArenaName/config.yml`. So your arena defines how your game takes place. + +In this arena, only two things are bind to locations: spawn point and regions. So if you need to move your arena in +another place, don't destroy it, just redefine your spawn points and your regions. + +
+ +### 1. Create the arena + +Just type this command to create your arena: + +`/pa create [newArenaName] (free)` + +By default your arena will work with a team system. If you add the `free` option, your arena will work on a *Free for +all* (FFA) game mode. + +> **🚩 Tip:** This parameter can be changed using [/pa gamemode](commands/gamemode.md) command or in your config file by +> setting `general.type` parameter to `free` or `none`. + +
+ +### 2. Set goals for the arena + +By default, your arena will use [TeamLives](goals/teamlives.md) goal if your arena is in team mode and +[PlayerLives](goals/playerlives.md) goal otherwise. If you're ok with this, go to the next point, otherwise please +continue reading. + +You can choose a custom goal [in the list](goals.md) and set it for your arena with the command: +`/pa [arenaName] goal [goalName]` + +You will find more information about this command [on this link](commands/goal.md). + +
+ +### 3. Set spawn points + +Now you have to create game spawn points by using this command: +`/pa [arenaName] spawn [spawnType]` + +##### Team arenas +For team arenas, spawn types are: `[team]spawn`, `[team]lounge`, `spectator`, `exit`. +So by default you need: 2 spawns (red & blue) / 2 lounges (red & blue) / 1 spectator zone / 1 exit. + +##### Free arenas +For **free** (FFA) arenas, spawn types are: `spawn[x]`, `lounge`, `spectator`, `exit`. +By default you need: 4 spawns (spawn1, spawn2, spawn3, spawn4) / 1 lounge / 1 spectator zone / 1 exit. + +
+ +> **🚩 Tips:** +>- In free arenas, you can create as many spawn points as you want. +>- You can use `/pa spawn` command again to move a spawn point + +
+ +### 4. Create the battle region + +> *This step is optional but really useful in mostly configurations* + +Now create the battle region with this command: + +`/pa [arenaName] region` + +It enables selection mode. Equip your hand with a **stick** and set your region with left and right click. + +Then type : + +`/pa [arenaName] region [yourNewRegionName]` + +Finally, specify your region type : + +`/pa [arenaName] regionType [regionName] BATTLE` + +> **🚩 Tips:** +> - By default your region is protected from block destruction and placing +> - Get a look to [the region documentation page](regions.md) to improve your arena regions + +
+ +### 5. Place required items in the lounge + +By default, four classes already exist : Swordsman, Tank, Pyro and Ranger. +You can chose to keep these classes or create new ones with the the [class command](commands/class.md). + +Then simply place signs near your **lounge** spawn point(s) and write the class names on the first line. + +Place the signs in each lobby, and an iron block (configurable). +The iron block is the default ready block that players can click on when they are ready. The match begins +when all players +are ready. + +> **🚩 Tips:** +> - Players can can choose their class with `/pa arenaclass [className]` command +> - You can set a default class using the config parameter `autoClass` +> - Players can also be ready typing `/pa ready`, that's why ready block is not mandatory + +
+ +### 6. Join the arena! + +Your first arena was created! Join the game with: + +`/pa [arenaName] (join) (teamName)` + +> **🚩 Tip:** If you just type `/pa [arenaName]` your team will be randomly selected. \ No newline at end of file diff --git a/doc/goals.md b/doc/goals.md new file mode 100644 index 000000000..6a1667489 --- /dev/null +++ b/doc/goals.md @@ -0,0 +1,26 @@ +## PVP Arena Goals + +Create ways to win the game or lose the game! + +Goal | Description +------------- | ------------- +[Beacons](goals/beacons.md) | Stand near beacons and claim them to win! +[BlockDestroy](goals/blockdestroy.md) | Destroy blocks (pre-installed) +[CheckPoints](goals/checkpoints.md) | Reach checkpoints in order to win (pre-installed) +[Domination](goals/domination.md) | Dominate flag positions (pre-installed) +[Flags](goals/flags.md) | Capture flags and bring 'em home (pre-installed) +[Food](goals/food.md) | Cook food and bring it home (pre-installed) +[Infect](goals/infect.md) | Infect people to win / kill infected players (pre-installed) +[Liberation](goals/liberation.md) | Jail dead players, possibility to unjail! (pre-installed) +[PhysicalFlags](goals/physicalflags.md) | Capture flags physically and bring 'em home (pre-installed) +[Pillars](goals/pillars.md) | Capture pillars by clicking/destroying! +[PlayerDeathMatch](goals/playerdeathmatch.md) | Player kills win (pre-installed) +[PlayerKillReward](goals/playerkillreward.md) | Player get better gears when killing (pre-installed) +[Rescue](goals/rescue.md) | Rescue a trapped Entity +[PlayerLives](goals/playerlives.md) | Player deaths lose (pre-installed) +[Sabotage](goals/sabotage.md) | Ignite TNT (pre-installed) +[Tank](goals/tank.md) | all vs one (pre-installed) +[TeamDeathConfirm](goals/teamdeathconfirm.md) | Confirmed Team kills win (pre-installed) +[TeamDeathMatch](goals/teamdeathmatch.md) | Team kills win (pre-installed) +[TeamLives](goals/teamlives.md) | Team deaths lose (pre-installed) +[Time](goals/time.md) | Time ends the arena (pre-installed) \ No newline at end of file diff --git a/doc/modules.md b/doc/modules.md new file mode 100644 index 000000000..d1dbb4a7b --- /dev/null +++ b/doc/modules.md @@ -0,0 +1,69 @@ +## PVP Arena Modules + +### Installation + +Unzip the module files (files tab, "PA Files v\*.\*.\*") into the /pvparena/files folder and install them via +`/pa install [modname]`, **activate per arena via** +`/pa [arenaname] !tm [modname]` + + +### PVP Arena Mods + +Hook into many different aspects of the game! + +Mod | Description | Status +------------- | ------------- | ------------- +[AfterMatch](mods/aftermatch.md) | could also be called "Sudden Death" | ⚠ +[Announcements](mods/announcements.md) | announce events happening | ⚠ +[ArenaBoards](mods/arenaboards.md) | stats display | ⚠ +[ArenaMaps](mods/arenamaps.md) | never lose yourself ever again! | ⚠ +[AutoSneak](mods/autosneak.md) | automatically hide player nametags by forcing sneak mode | ⚠ +[AutoVote](mods/autovote.md) | automatism | ⚠ +[BanKick](mods/bankick.md) | secure your arenas! | ⚠ +[BattlefieldGuard](mods/battlefieldguard.md) | secure your battlefield | ✔ +[BattlefieldManager](mods/battlefieldmanager.md) | manage your battlefield | ⚠ +[BetterClasses](mods/betterclasses.md) | add potion effects and more to specific classes | ✔ +[BetterGears](mods/bettergears.md) | give team colored leather | ✔ +[BetterFight](mods/betterfight.md) | kill streaks and one-hit-kill items! | ⚠ +[BetterKillstreaks](mods/betterkillstreaks.md) | even more detailed kill streaks! | ⚠ +[BlockDissolve](mods/blockdissolve.md) | dissolve blocks under fighting players | ✔ +[BlockRestore](mods/blockrestore.md) | restore the battlefield | ✔ +[ChestFiller](mods/chestfiller.md) | fill battlefield chests with customizable content! | ✔ +[Duel](mods/duel.md) | duel someone! | ⚠ +[EventActions](mods/eventactions.md) | do stuff when stuff happens | ⚠ +[Factions](mods/factions.md) | fix pvp not working | ⚠ +[FixInventoryLoss](mods/fixinventoryloss.md) | prevent loss by gamemode / inventory check | ⚠ +[FlySpectate](mods/flyspectate.md) | have players spectating a fight in fly mode | ✔ +[Items](mods/items.md) | spawn (random) items | ⚠ +[LateLounge](mods/latelounge.md) | keep playing until enough ppl are joining | ✔ +[MatchResultStats](mods/matchresultstats.md) | keep stats of player games, who won, who lost? | ⚠ +[PlayerFinder](mods/playerfinder.md) | allow players to find others with a compass | ✔ +[Points](mods/points.md) | allow to restrict certain classes to require players to fight for better classes | ⚠ +[PowerUps](mods/powerups.md) | spawn items giving special powers | ✔ +[RealSpectate](mods/realspectate.md) | spectate the game, CounterStrike style! | ✔ +[RedstoneTriggers](mods/redstonetriggers.md) | add win/lose triggered by redstone | ⚠ +[RespawnRelay](mods/respawnrelay.md) | add a relay for respawning players | ⚠ +[SinglePlayerSupport](mods/singleplayersupport.md) | Allow players to use an arena on their own! | ⚠ +[Skins](mods/skins.md) | add custom skins to teams/classes | ❌ +[SpecialJoin](mods/specialjoin.md) | join via buttons, levers, etc | ⚠ +[Spectate](mods/spectate.md) | use the new 1.8 SPECTATOR mode to allow flying and POV spectating | ⚠ +[Squads](mods/squads.md) | add squads to the game, basically only showing players belonging together apart from teams and classes. | ✔ +[StartFreeze](mods/startfreeze.md) | freeze players at start | ⚠ +[TeamSizeRestrict](mods/teamsizerestrict.md) | a small mod to restrict the size of specific teams | ⚠ +[Titles](mods/titles.md) | send messages to players as the "title" command would do | ✔ +[TempPerms](mods/tempperms.md) | add temporary perms | ⚠ +[Turrets](mods/turrets.md) | add turrets where players fire projectiles | ⚠ +[Vault](mods/vault.md) | add economy | ✔ +[Walls](mods/walls.md) | define wall regions to simulate "The Walls" | ⚠ +[WorldEdit](mods/worldedit.md) | backup/restore regions | ✔ +[WorldGuard](mods/worldguard.md) | import region definitions from WorldGuard | ⚠ + +**Key :** ✔ Recently tested and full-functional | ⚠ Legacy modules, not tested for a while | ❌ Temporarily unavailable + +### Why are there different statuses? + +PVP Arena exists since 2011 and Minecraft servers evolution make modules follow-up complicated. The objective of next +updates will be to make a great check-up of all of them and fix all eventual issues. + +Anyway, don't hesitate to test legacy modules by yourself, a big part of them work normally or have trivial issues. Obviously +if you encounter one, you can report it 😉 \ No newline at end of file diff --git a/doc/update-version.md b/doc/update-version.md index d9385b332..5d7f59117 100644 --- a/doc/update-version.md +++ b/doc/update-version.md @@ -59,4 +59,50 @@ spawns: checkpoint4: world,297,64,1285,14.695302963256836,50.40021514892578 checkpoint5: world,298,64,1289,53.69533920288086,54.75028610229492 checkpoint6: world,295,64,1292,1.795335054397583,46.80023193359375 +``` + +## PowerUps Module + +In powerups mod, items and effects configuration was previously in a dedicated `powerups` bloc at root of your arena +config files. Just move this block content into a the following path `modules.powerups.items` + +Example : + +*Replace this* +```yaml +powerups: + Heal: + item: BREAD + health: + diff: 3 + Repair: + item: WORKBENCH + repair: + items: helmet,chestplate,leggins,boots + factor: 0.2 +# Lines below have no importance +teams: + red: RED + blue: BLUE +``` +*with this* +```yaml +modules: + powerups: + dropspawn: true + usage: death:1 + items: + Heal: + item: BREAD + health: + diff: 3 + Repair: + item: WORKBENCH + repair: + items: helmet,chestplate,leggins,boots + factor: 0.2 +# Lines below have no importance +teams: + red: RED + blue: BLUE ``` \ No newline at end of file diff --git a/readme.md b/readme.md index f0a3e22df..37c5363a8 100644 --- a/readme.md +++ b/readme.md @@ -1,117 +1,83 @@ -![PVP-Arena](/doc/images/logo.png) - -*** -**IF YOU'RE UPGRADING FROM 1.14.x VERSION OR BELOW, PLEASE READ [UPGRADE DOCUMENTATION](doc/update-version.md)** -*** - -**Enhance your server by adding a new dimension of PVP battles!** - -Create fully customizable, moddable, flexible arenas, develop your own arena goal or mod that totally changes the game as you wish. -This flexibility is achieved on the one hand by a module loader created by NodinChan which loads arena goals (/pvparena/goals) and arena mods (/pvparena/mods) which enhance the gameplay just limited by your imagination, on the other hand it features an API, which still is a WIP due to lack of requests. I will enhance it as feature/hook requests arise. +![PVP-Arena](doc/images/logo.png) +

+ + IF YOU'RE UPGRADING FROM 1.14.x VERSION OR BELOW, PLEASE READ + UPGRADE DOCUMENTATION + +

*** +[What is PVP Arena?](#What-is-PVP-Arena?) | [Dependencies](#Dependencies) | [Downloads](#Downloads) | +[Installation](#Installation) | [Documentation](#Documentation) | [Update Checker](#Update-Checker) | +[Telemetry](#Telemetry) | [Credits](#Credits) +*** +
+## What is PVP Arena? -## Features +PVP Arena is a plugin for Spigot based servers which enables creation of customizable fight and mini-games arenas. +Define your own teams, classes, lobbies, spawn points, messages, gear colors, rewards and even game modes! +Theses game modes (included in the plugin) can combined with tens of modules to enhance your gameplay! +In addition, all arenas can be protected with an embedded protection system based on regions. +Anyway, here's a quick (non exhaustive) list of plugin features: - Multiple arenas -- Battlefield regions -- Customizable classes +- Arena regions and protections - Player-state saving -- Arena regions -- In-game configuration access -- Arena disable -- Leader boards +- Customizable classes +- Customizable spawn points, lobbies and spectator zones +- In-game configuration access and simple config files +- Arena disabling +- Scoreboards - Spawn protection - Flag coloring - Inventory drops - Announcements -- Arena end timer +- Time limited match +- Battlefield regeneration +So take time to read the docs, it's full of useful information 😉 *** ## Dependencies - Spigot 1.13+ +- Java 8+ *** ## Downloads -- [spigotmc.org](https://www.spigotmc.org/resources/pvp-arena.16584/) -- [Dev builds on Jenkins](https://ci.craftyn.com/view/Spigot%20PVP%20Arena/) +PVP Arena release version can be downloaded on following pages: +- [PVP Arena - SpigotMC](https://www.spigotmc.org/resources/pvp-arena.16584/) +- [Github releases page](https://github.com/Eredrim/pvparena/releases) + +Development builds (experimental) can be downloaded on Jenkins: +- [Jenkins dev builds](https://ci.craftyn.com/view/Spigot%20PVP%20Arena/) *** -## How to install +## Installation -- Stop your server -- Place jar in plugins folder -- Run a first time to create config folder -- Configure if you wish to -- Done ! +Place PVP Arena `.jar` file in the plugin repository of your server and restart. *** ## Documentation -- [Creation](doc/creation.md) +- [Getting started](doc/getting-started.md) - [Commands](doc/commands.md) -- [Enhancements](doc/enhancements.md) -- [Items](doc/items.md) -- [Languages](doc/languages.md) - [Permissions](doc/permissions.md) - [Regions](doc/regions.md) +- [Goals](doc/goals.md) +- [Modules](doc/modules.md) +- [Items](doc/items.md) +- [Languages](doc/languages.md) - [Configuration](doc/configuration.md) *** -## Video Tutorials - -- Basic Setup (v1.3): - - [Team Arena](https://www.youtube.com/watch?v=PT0piAyVMIw) - - [Free For All Arena](https://www.youtube.com/watch?v=bYNtxGxVGfE) - - [Region Tutorial (Shapes)](https://www.youtube.com/watch?v=jWdWbwRg9zY) - - [Region Tutorial (Protections)](https://youtu.be/WFIZ7ZskPVc) -- Localized Setup (v1.3): - - [Team Arena (German)](https://www.youtube.com/watch?v=2KSAk-PvwRM) -- Goal Tutorials (v1.3): - - [BlockDestroy](https://www.youtube.com/watch?v=i7Fpuh_O5O8) - - [CheckPoints](https://www.youtube.com/watch?v=anO_tYwcKsg) - - [Domination](https://www.youtube.com/watch?v=_Ngq5xBlLsk) -- [CTF (v1.0)](http://www.youtube.com/watch?v=SuL78bce-f0) -- [DeathMatch (v1.0)](http://www.youtube.com/watch?v=KqBueDNbpD8) -- [Food Block Destroy (v1.0)](http://www.youtube.com/watch?v=ntloY1BTKHQ) -- [FreeForAll (v1.0)](http://www.youtube.com/watch?v=xBIxHoKMu98) -- [Spleef (v1.0)](http://www.youtube.com/watch?v=DRmLNXEAs_4) -- [Pillar Domination (v1.0)](http://www.youtube.com/watch?v=Xi7yNURxAjw) -- [TeamDeathMatch (v1.0)](http://www.youtube.com/watch?v=rQ1ljlc6SJM) - -Users tutorials : - -- [TeamDeathMatch (v1.0)](http://www.youtube.com/watch?v=Jw6E8s2kiKw) - -*** - -## Changelog - -- v1.13.5 - address #355 - set some more scoreboard settings to hopefully get colors going -- [read more](doc/changelog.md) - -*** - -## Todo - -- plugin - - [ ] calculate a winner based on ROUND results -- modules -- goals - - [ ] tournament arenas ; rounds switch through arenas - - [ ] siege -> bring PACKET from A to B || prevent - -*** - ## Update Checker If you wan't you can be informed of plugin or modules updates. Each release version was pushed on github since 1.14.0. The update checker will call the github APIs and announce an update to OPs on login. You can configure it to @@ -132,7 +98,7 @@ automatically download updates. ## Telemetry PVPArena uses bStats to get statistics about basic information like plugin version, java version, -kind of used Minecraft server, etc. You can disable it in the dedicated config file `plugins/bStats/config.yml` +kind of used Minecraft server, etc. You can disable it in the dedicated config file `/plugins/bStats/config.yml` *** From 8371f13d3c831feb603a8dd06f98e57d8f586cef Mon Sep 17 00:00:00 2001 From: Eredrim Date: Thu, 16 Jul 2020 21:40:33 +0200 Subject: [PATCH 40/43] v1.15 - update all docs --- doc/changelog.md | 9 -- doc/commands.md | 87 ++++++----- doc/commands/arenaclass.md | 22 +++ doc/commands/blacklist.md | 20 +-- doc/commands/check.md | 5 +- doc/commands/class.md | 13 +- doc/commands/classchest.md | 18 +-- doc/commands/create.md | 18 +-- doc/commands/debug.md | 7 +- doc/commands/disable.md | 7 +- doc/commands/edit.md | 14 ++ doc/commands/enable.md | 7 +- doc/commands/forcewin.md | 7 +- doc/commands/gamemode.md | 7 +- doc/commands/goal.md | 12 +- doc/commands/install.md | 20 --- doc/commands/join.md | 14 ++ doc/commands/modules.md | 32 ++++ doc/commands/playerjoin.md | 9 +- doc/commands/protection.md | 17 +- doc/commands/ready.md | 12 ++ doc/commands/region.md | 30 ++-- doc/commands/regionclear.md | 18 ++- doc/commands/regionflags.md | 13 +- doc/commands/regions.md | 10 +- doc/commands/regiontype.md | 51 ++---- doc/commands/reload.md | 6 +- doc/commands/remove.md | 13 +- doc/commands/round.md | 19 ++- doc/commands/set.md | 45 +++--- doc/commands/setowner.md | 9 +- doc/commands/spawn.md | 30 +++- doc/commands/start.md | 10 +- doc/commands/stats.md | 13 +- doc/commands/stop.md | 9 +- doc/commands/teams.md | 46 +++--- doc/commands/teleport.md | 14 +- doc/commands/togglemod.md | 14 +- doc/commands/uninstall.md | 17 -- doc/commands/update.md | 20 --- doc/commands/whitelist.md | 20 +-- doc/configuration.md | 14 +- doc/enhancements.md | 99 ------------ doc/faq.md | 49 ++++++ doc/getting-started.md | 28 ++-- doc/goals.md | 45 +++--- doc/goals/beacons.md | 2 +- doc/goals/blockdestroy.md | 29 ++-- doc/goals/checkpoints.md | 28 ++-- doc/goals/domination.md | 18 +-- doc/goals/flags.md | 29 ++-- doc/goals/food.md | 45 +++--- doc/goals/infect.md | 25 ++- doc/goals/liberation.md | 22 +-- doc/goals/physicalflags.md | 25 +-- doc/goals/pillars.md | 108 ++++++------- doc/goals/playerdeathmatch.md | 36 ++--- doc/goals/playerkillreward.md | 55 +++---- doc/goals/playerlives.md | 40 +++-- doc/goals/rescue.md | 45 +++--- doc/goals/sabotage.md | 34 ++-- doc/goals/tank.md | 39 +++-- doc/goals/teamdeathconfirm.md | 20 +-- doc/goals/teamdeathmatch.md | 37 ++--- doc/goals/teamlives.md | 31 ++-- doc/goals/time.md | 41 +++-- doc/history/0.1.md | 16 -- doc/history/0.10.md | 97 ------------ doc/history/0.2.md | 4 - doc/history/0.3.md | 17 -- doc/history/0.4.md | 7 - doc/history/0.5.md | 13 -- doc/history/0.6.md | 83 ---------- doc/history/0.7.md | 90 ----------- doc/history/0.8.md | 92 ----------- doc/history/0.9.md | 203 ------------------------ doc/history/1.0.md | 284 ---------------------------------- doc/history/1.1.md | 131 ---------------- doc/history/1.2.md | 78 ---------- doc/history/1.3.0.md | 66 -------- doc/history/1.3.1.md | 47 ------ doc/history/1.3.2.md | 79 ---------- doc/history/1.3.3.md | 112 -------------- doc/history/1.3.4.md | 52 ------- doc/items.md | 10 +- doc/languages.md | 20 ++- doc/mods/powerups.md | 2 +- doc/modules.md | 17 +- doc/permissions.md | 13 +- doc/regions.md | 49 ++++-- doc/update-checker.md | 15 ++ readme.md | 27 ++-- 92 files changed, 958 insertions(+), 2374 deletions(-) delete mode 100644 doc/changelog.md create mode 100644 doc/commands/arenaclass.md create mode 100644 doc/commands/edit.md delete mode 100644 doc/commands/install.md create mode 100644 doc/commands/join.md create mode 100644 doc/commands/modules.md create mode 100644 doc/commands/ready.md delete mode 100644 doc/commands/uninstall.md delete mode 100644 doc/commands/update.md delete mode 100644 doc/enhancements.md create mode 100644 doc/faq.md delete mode 100644 doc/history/0.1.md delete mode 100644 doc/history/0.10.md delete mode 100644 doc/history/0.2.md delete mode 100644 doc/history/0.3.md delete mode 100644 doc/history/0.4.md delete mode 100644 doc/history/0.5.md delete mode 100644 doc/history/0.6.md delete mode 100644 doc/history/0.7.md delete mode 100644 doc/history/0.8.md delete mode 100644 doc/history/0.9.md delete mode 100644 doc/history/1.0.md delete mode 100644 doc/history/1.1.md delete mode 100644 doc/history/1.2.md delete mode 100644 doc/history/1.3.0.md delete mode 100644 doc/history/1.3.1.md delete mode 100644 doc/history/1.3.2.md delete mode 100644 doc/history/1.3.3.md delete mode 100644 doc/history/1.3.4.md create mode 100644 doc/update-checker.md diff --git a/doc/changelog.md b/doc/changelog.md deleted file mode 100644 index c7b7f70c2..000000000 --- a/doc/changelog.md +++ /dev/null @@ -1,9 +0,0 @@ -== PVP-Arena v1.13 Changelog - -- v1.13.5 - address #355 - set some more scoreboard settings to hopefully get colors going -- v1.13.4 - various exceptions caught, addressing issues #351 and #352 -- v1.13.3 - [WIP] the core game should be operational, region setup tested, blockrestore fixed -- v1.13.2 - plugin.yml api update -- v1.13.1 - rework many things that now work differently - among those all things involving items, especially class definitions -- v1.13.0 - slowly work our way to Spigot 1.13 - diff --git a/doc/commands.md b/doc/commands.md index c365da051..a904352e8 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -1,71 +1,78 @@ -*Note that `/pvparena` and `/pa` are the same. Furthermore, those commands only work as-is if you have only one arena, OR entered edit mode with an arena if you have more than one arena: -`/pa [arenaname] edit`* +# Command list -## Command list +Click on a command to get its syntax, usage examples and more information about its working. Commands `/pvparena` and + `/pa` are the same. -Click on a command to view more information about it. +> 🚩 **Note:** +> You always have to precise your arena name in commands (like `/pa myArena enable`) except for these cases: +> - For global admin commands +> - After you joined an arena +> - When you're editing an arena (see [`/pa edit`](commands/edit.md) command) +> - When you have only one arena -### Global Admin Commands -_(Permission: pvparena.admin)_ +
+ +## Global Admin Commands + +> ℹ Permission: pvparena.admin Command | Shorthand | Definition ------------- | ------------- | ------------- -[/pa debug](commands/debug.md) | /pa !d | Debugs nodes +[/pa debug](commands/debug.md) | /pa !d | Debug nodes +[/pa modules](commands/modules.md) | /pa !mi | Manage modules [/pa reload](commands/reload.md) | /pa !r | Reload arena configs -[/pa install](commands/install.md) | /pa !i | Installs a module -[/pa uninstall](commands/uninstall.md) | /pa !ui | Uninstalls a module -[/pa update](commands/update.md) | /pa !u | Updates a module -### Arena Administration Commands +## Arena Administration Commands -_(Permission: pvparena.admin OR ownership AND pvparena.create)_ +> ℹ Permission: pvparena.admin OR both ownership and pvparena.create Command | Shorthand | Definition ------------- | ------------- | ------------- -[/pa blacklist \(or whitelist\)](commands/blacklist.md) | /pa !bl (!wl) | Manage arena blacklists or whitelists -[/pa check](commands/check.md) | /pa !ch | Checks an arena configuration +[/pa blacklist](commands/blacklist.md) | /pa !bl | Manage arena blacklists +[/pa check](commands/check.md) | /pa !ch | Check an arena configuration [/pa class](commands/class.md) | /pa !cl | Manage arena classes [/pa classchest](commands/classchest.md) | /pa !cc | Manage arena class chests -[/pa create](commands/create.md) | /pa !c | Creates an arena -[/pa disable](commands/disable.md) | /pa !dis | Disables an arena. -/pa edit | /pa !e | Toggles editing of an arena -[/pa enable](commands/enable.md) | /pa !en | Enables an arena. -[/pa forcewin](commands/forcewin.md) | /pa !fw | Forces a player/team to win. +[/pa create](commands/create.md) | /pa !c | Create an arena +[/pa disable](commands/disable.md) | /pa !dis | Disable an arena. +[/pa edit](commands/edit.md) | /pa !e | Toggle editing of an arena +[/pa enable](commands/enable.md) | /pa !en | Enable an arena. +[/pa forcewin](commands/forcewin.md) | /pa !fw | Force a player/team to win. [/pa gamemode](commands/gamemode.md) | /pa !gm | Change the general gamemode of an arena [/pa goal](commands/goal.md) | /pa !g | Manage arena goals [/pa playerjoin](commands/playerjoin.md) | /pa !pj | Make a player join -[/pa protection](commands/protection.md) | /pa !p | Manages arena protections -[/pa region](commands/region.md) | /pa !rg | Manages arena regions -[/pa regionclear](commands/regionclear.md) | /pa !rc | Manages arena region clearing exceptions -[/pa regionflags](commands/regionflags.md) | /pa !rf | Manages arena flags -[/pa regiontype](commands/regiontype.md) | /pa !rt | Changes a region type -[/pa regions](commands/regions.md) | /pa !rs | Debugs regions | ^ +[/pa protection](commands/protection.md) | /pa !p | Manage arena protections +[/pa region](commands/region.md) | /pa !rg | Manage arena regions +[/pa regionclear](commands/regionclear.md) | /pa !rc | Manage arena region clearing exceptions +[/pa regionflags](commands/regionflags.md) | /pa !rf | Manage arena flags +[/pa regiontype](commands/regiontype.md) | /pa !rt | Change a region type +[/pa regions](commands/regions.md) | /pa !rs | Debug regions [/pa reload](commands/reload.md) | /pa !rl | Reload arena configs -[/pa remove](commands/remove.md) | /pa !rm | Removes an arena. -[/pa round](commands/round.md) | /pa !rd | Manages arena rounds +[/pa remove](commands/remove.md) | /pa !rm | Remove an arena. +[/pa round](commands/round.md) | /pa !rd | Manage arena rounds [/pa set](commands/set.md) | /pa !s | Set an arena config setting [/pa setowner](commands/setowner.md) | /pa !so | Sets the owner of an arena [/pa spawn](commands/spawn.md) | /pa !sp | Manage arena spawns [/pa start](commands/start.md) | /pa !go | Force starts an arena. [/pa stop](commands/stop.md) | /pa !st | Force stops an arena. -[/pa teams](commands/teams.md) | /pa !ts | Manages arena teams -[/pa teleport](commands/teleport.md) | /pa !tp | Teleports you to an arena spawnpoint -[/pa togglemod \[module\]](commands/togglemod.md) | /pa !tm | Activates/Deactivates module +[/pa teams](commands/teams.md) | /pa !ts | Manage arena teams +[/pa teleport](commands/teleport.md) | /pa !tp | Teleport you to an arena spawnpoint +[/pa togglemod](commands/togglemod.md) | /pa !tm | Enable or disable a module for an arena +[/pa whitelist](commands/whitelist.md) | /pa !wl | Manage arena whitelists -### Arena Standard Commands +## Arena Standard Commands -_(Permission: pvparena.user (defaults to true))_ +> ℹ Permission: pvparena.user (defaults to true) Command | Shorthand | Definition ------------- | ------------- | ------------- -/pa arenaclass | /pa -ac | Changes your class, if allowed (/pa -ac [classname]) -/pa list | none | List available arenas (red: disabled, yellow: edit, green: running) -/pa chat | /pa -c | Sets arena chat mode -/pa info | /pa -i | Displays the active modules of an arena and its settings -/pa join {team} | /pa -j | Joins an arena +[/pa arenaclass](commands/arenaclass.md) | /pa -ac | Change your class, if allowed +/pa chat | /pa -c | Set arena chat mode +/pa info | /pa -i | Display the active modules of an arena and its settings /pa help | /pa -h | Basic help. Splits into subsections. +[/pa join](commands/join.md) | /pa -j | Join an arena (specifying a team or not) /pa leave | /pa -l | Leave an arena -/pa ready | /pa -r | Readys you up or lists who is ready +/pa list | none | List available arenas (red: disabled, yellow: edit, green: running) +[/pa ready](commands/ready.md) | /pa -r | Ready you up or list who is ready /pa spectate | /pa -s | Spectate an arena -[/pa stats](commands/stats.md) | /pa -s | Shows [arena/global] statistics -/pa version | /pa -v | Shows detailed version information \ No newline at end of file +[/pa stats](commands/stats.md) | /pa -s | Show [arena/global] statistics +/pa version | /pa -v | Show detailed version information \ No newline at end of file diff --git a/doc/commands/arenaclass.md b/doc/commands/arenaclass.md new file mode 100644 index 000000000..0aa812c7b --- /dev/null +++ b/doc/commands/arenaclass.md @@ -0,0 +1,22 @@ +# Arenaclass command + +## Description + +This command allow players to change their class if it's allowed. It must be typed inside an arena. + +## Usage Examples + +Command | Definition +------------- | ------------- +/pa arenaclass [className] | switch you current arena class + +Example: `/pa -ac assassin` - get the assassin class + +## Details + +You can change you class in two cases : +- Before a match, when you're waiting in lounge +- During a match if `ingameClassSwitch` arena setting is enabled + +> 🚩**Tip:** +> With `classSwitchAfterRespawn` you can delay ingame class switching on next respawn \ No newline at end of file diff --git a/doc/commands/blacklist.md b/doc/commands/blacklist.md index c84697487..eac587772 100644 --- a/doc/commands/blacklist.md +++ b/doc/commands/blacklist.md @@ -2,18 +2,20 @@ ## Description -This command manages the block place / break blacklist for an arena. +This command manages the block place / break blacklist for an arena. With this, you are able to forbid +some actions to arena players. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa ctf blacklist clear | clear the general blacklist -/pa ctf blacklist break clear | clear the BREAK blacklist -/pa ctf blacklist break add SNOW | add SNOW to the BREAK blacklist -/pa ctf blacklist place show | show the PLACE blacklist -/pa ctf blacklist break remove SNOW | remove SNOW from the BREAK blacklist +/pa [arena] blacklist clear | clear the general blacklist +/pa [arena] blacklist [break/place] clear | clear the BREAK or the PLACE blacklist +/pa [arena] blacklist [break/place] show | show a blacklist content +/pa [arena] blacklist [break/place] add [block] | add a block to a blacklist +/pa [arena] blacklist [break/place] remove [block] | remove a block from a blacklist -## Details +Example: `/pa ctf blacklist break add SNOW` - add SNOW block to the BREAK blacklist -Both ENUMs and ITEM IDs work, you can even add DATA values, e.g. WOOL:13 \ No newline at end of file +> **🚩 Tip:** +> [`/pa whitelist`](whitelist.md) command works exactly in the same way \ No newline at end of file diff --git a/doc/commands/check.md b/doc/commands/check.md index 5d8374202..e11db105f 100644 --- a/doc/commands/check.md +++ b/doc/commands/check.md @@ -8,8 +8,9 @@ The check command basically tries to parse an arena config, in case you are unsu Command | Definition ------------- | ------------- -/pa check myArena | debug the arena "myArena" -/pa check Teams | debug the arena "Teams" +/pa check [arena] | check the config of an arena + +Example: `/pa check myArena` - debug the arena "myArena" ## Hazards diff --git a/doc/commands/class.md b/doc/commands/class.md index 198300246..ed8fee47a 100644 --- a/doc/commands/class.md +++ b/doc/commands/class.md @@ -4,13 +4,18 @@ This command manages the arena classes. You can use it to show, edit and remove arena classes. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa test class load Tank | Give you the class items of the Class "Tank" of the arena "test" -/pa temp class save Test | Save your inventory to the class items of the Class "Test" of the arena "temp" -/pa team class remove Blue | Remove the class "Blue" from the arena "team" +/pa [arena] class load [class] | Preview the class items of the class directly in your inventory +/pa [arena] class save [class] | Save your inventory to the class items of a class +/pa [arena] class remove [class] | Remove a class from an arena + +Example: use `/pa temp class save Test` to save your inventory to the class "Test" of the arena "temp" + +> **🚩 Tip:** +> Type `/pa leave` to leave class preview ## Hazards diff --git a/doc/commands/classchest.md b/doc/commands/classchest.md index 1548d2f55..c16a1e556 100644 --- a/doc/commands/classchest.md +++ b/doc/commands/classchest.md @@ -2,22 +2,12 @@ ## Description -This command manages the arena class chests. You use it to define a class item chest. +If you want, you can save class inventories inside chests instead of using [/pa class](class.md) command. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa test classchest Ranger | Define the chest containing the items of the class "Ranger" from the arena "test" +/pa [arena] classchest [class] | Use a chest to store items of a class. You have to look at the chest. -## Hazards - -- - -## Details - -Look at a chest you want to set - -## ToDo - -- \ No newline at end of file +Example: `/pa test classchest Ranger` - Define the chest containing the items of the class "Ranger" from the arena "test". \ No newline at end of file diff --git a/doc/commands/create.md b/doc/commands/create.md index d7bff3c89..d0b2ceb89 100644 --- a/doc/commands/create.md +++ b/doc/commands/create.md @@ -4,22 +4,10 @@ The create command basically creates a standard, boring, arena. Given legacy types enhance this, but still you will probably want to customize your arena and definately continue setting it up by setting spawn points. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa create teamArena | create a standard Teams Arena -/pa create capture ctf | create a Capture The Flag Arena called "capture" +/pa create [arenaName] (free) | Create an arena. Arena uses team gamemode by default, add `free` parameter to use FFA gamemode instead. -## Details - -In order to have a quicker start when setting up an arena, you can use the oldschool legacy types, which will be supported until v2.0 I guess. Those types add pre-definitions to define how the arena works in general. You can still go ahead and adjust the goal setup to your needs! - -Valid legacy types include: - -- ctf -- free -- ctp -- sabotage -- tank -- spleef \ No newline at end of file +Example: `/pa create ffa free` - create a free for all arena named "ffa" \ No newline at end of file diff --git a/doc/commands/debug.md b/doc/commands/debug.md index b0b3458c4..cd0106de4 100644 --- a/doc/commands/debug.md +++ b/doc/commands/debug.md @@ -4,15 +4,16 @@ The debug command is used to spam the log file with a hell lot more of information, based on your current issue, or just in general when unsure where the issue comes from. -## Usage Examples +## Usage Command | Definition ------------- | ------------- /pa debug all | debug ALL classes -/pa debug 4 | debug class number 4 -/pa debug 4,7 | debug class 4 and 7 +/pa debug [value] | debug class or arena where name equals to `value` /pa debug none | disable debugging +Example: `/pa debug 4,7` - debug class 4 and 7 + ## Hazards The way PVP Arena debugs is known to **spam** a LOT. This rises exponentially the more people you have on. So if you want to debug and are unsure if you're debugging the right thing, diff --git a/doc/commands/disable.md b/doc/commands/disable.md index 8074a9853..e38a046b2 100644 --- a/doc/commands/disable.md +++ b/doc/commands/disable.md @@ -4,12 +4,13 @@ This command disables arenas, force stopping them in the first place. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa test disable | disable the "test" arena -/pa temp disable | disable the "temp" arena +/pa [arena] disable | disable an arena + +Example: `/pa test disable` - disable the "test" arena ## Details diff --git a/doc/commands/edit.md b/doc/commands/edit.md new file mode 100644 index 000000000..cf656932e --- /dev/null +++ b/doc/commands/edit.md @@ -0,0 +1,14 @@ +# Edit command + +## Description + +The edit command switch your arena in edit mode. That temporarily closes your arena and allows you to type +any arena command without precising arena name. + +## Usage Examples + +Command | Definition +------------- | ------------- +/pa [arena] edit | toggle the edit mode of an arena + +Example: `/pa ctf edit` - enable or disable edit mode for "ctf" arena \ No newline at end of file diff --git a/doc/commands/enable.md b/doc/commands/enable.md index bcd700477..59b2ed1bd 100644 --- a/doc/commands/enable.md +++ b/doc/commands/enable.md @@ -4,10 +4,11 @@ This command re-enables an arena after disabling it. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa test enable | enable the **"test"** arena -/pa temp enable | enable the **"temp"** arena +/pa [arena] enable | disable an arena + +Example: `/pa test enable` - enable the "test" arena diff --git a/doc/commands/forcewin.md b/doc/commands/forcewin.md index 9d92de2eb..ab0e57bee 100644 --- a/doc/commands/forcewin.md +++ b/doc/commands/forcewin.md @@ -4,10 +4,11 @@ This command forces a player/team to win. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa test !fw slipcor | Make **slipcor** the winner in the **"test"** arena -/pa temp forcewin red | Make team **red** the winner in the **"temp"** arena +/pa [arena] forcewin [player/team] | Force a player or a team to win + +Example: `/pa temp forcewin red` - Make team **red** the winner in the **"temp"** arena diff --git a/doc/commands/gamemode.md b/doc/commands/gamemode.md index 8462fd2fb..9602b6b1a 100644 --- a/doc/commands/gamemode.md +++ b/doc/commands/gamemode.md @@ -4,11 +4,12 @@ The gamemode defines the general play mode. Free For All or Team Play ? -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa ctf gamemode team | set the gamemode of arena "ctf" to "team" -/pa ffa !gm free | set the gamemode of arena "ffa" to "free" +/pa [arena] gamemode [team/free] | Change gamemode of an arena + +Example: `/pa ffa gamemode free` - set the gamemode of arena "ffa" to "free" ## Details diff --git a/doc/commands/goal.md b/doc/commands/goal.md index 919428e27..1721c9cdc 100644 --- a/doc/commands/goal.md +++ b/doc/commands/goal.md @@ -4,16 +4,20 @@ The goal command is used to activate certain goals, to enhance your arena or disable goals to narrow down the goals. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa free goal Time | Enable the goal "Time" for the arena "free" -/pa ctf !g Time off | Disable the goal "Time" for the arena "ctf" +/pa [arena] goal [goal] (true/false) | Toggle a goal for an arena + +Example: `/pa free goal Time` - Enable the goal "Time" for the arena "free" ## Details You will receive a list of valid (installed) arena goals when trying to activate an unknown goal, so e.g. /pa [arenaname] !g list will show you possible goals. Giving no second argument will just toggle the goal status and show you the result, valid arguments to activate/deactivate include: -on | 1 | true || off | 0 | false \ No newline at end of file +on | 1 | true || off | 0 | false + +> 🚩 **Tip:** +> You can see active goals of your arena with command `/pa [arena] info` \ No newline at end of file diff --git a/doc/commands/install.md b/doc/commands/install.md deleted file mode 100644 index 86090bb44..000000000 --- a/doc/commands/install.md +++ /dev/null @@ -1,20 +0,0 @@ -# Install command - -## Description - -This command manages installation of modules. You can list available modules, see your current state, and install new modules. - -## Usage Examples - -Command | Definition -------------- | ------------- -/pa install | list all available modules -/pa install worldedit | install the worldedit module - -## Hazards - -Know your versions. If unsure, download the latest zip file from the files section, replace the files inside /files and then you can be sure you're up to date. Outdated modules lead to errors. - -## Details - -The list contains all available modules, with their respective version. Yellow names mark installed plugins, green version numbers mark as up to date, red version numbers show that you need to update the files. \ No newline at end of file diff --git a/doc/commands/join.md b/doc/commands/join.md new file mode 100644 index 000000000..74988e862 --- /dev/null +++ b/doc/commands/join.md @@ -0,0 +1,14 @@ +# Join command + +## Description + +Use this command to join an arena. You can specify a team. + + +## Usage Examples + +Command | Definition +------------- | ------------- +/pa [arena] join (team) | join a arena + +Example: `/pa ctf join blue` - join the blue team of "ctf" arena \ No newline at end of file diff --git a/doc/commands/modules.md b/doc/commands/modules.md new file mode 100644 index 000000000..b7cde8e37 --- /dev/null +++ b/doc/commands/modules.md @@ -0,0 +1,32 @@ +# Install command + +## Description + +This command manages modules. You can list installed modules, download latest version, install, uninstall, update and +upgrade your modules. + +## Usage + +Command | Definition +------------- | ------------- +/pa modules (list) | list all available modules (installed modules are highlighted) +/pa modules install [moduleName] | install a module (from the `files` folder) +/pa modules uninstall [moduleName] | uninstall a module (removing from `mods` folder) +/pa modules update | update all modules in `mods` folder with versions which are in `files` folder +/pa modules download | download latest release of modules pack and place it in `files` folder +/pa modules upgrade | upgrade all your modules (perform a download and an update) + + +## Directory management + +In order to increase performances, PVP Arena has two directories for mods: +- `/mods` contains only mods used in arenas and installed by admins +- `/files` contains all downloaded mods + +When you install a mod, the plugin copies it from `/files` to `/mods`. + + +## Details + +The result of list command contains all available modules, with their respective version. Yellow names mark installed +plugins, green version numbers mark as up to date, red version numbers show that you need to update the files. \ No newline at end of file diff --git a/doc/commands/playerjoin.md b/doc/commands/playerjoin.md index 544a05b5e..9fcd467ff 100644 --- a/doc/commands/playerjoin.md +++ b/doc/commands/playerjoin.md @@ -2,12 +2,13 @@ ## Description -This command force joins an online player into an arena. You can specify an arena team, or not. Just as the player would join the game. In fact it "makes the player call the join command" ;) +This command forces an online player to join an arena. You can specify an arena team, or not. Just as the player would join the game. In fact it "makes the player call the join command" ;) -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa ctf playerjoin slipcor | make slipcor join the CTF arena, random team -/pa ctf !pj valera blue | make valera join the CTF arena, team blue +/pa [arena] playerjoin [player] (team) | force a player to join an arena + +Example: `/pa ctf !pj valera blue` - make valera join the CTF arena, team blue diff --git a/doc/commands/protection.md b/doc/commands/protection.md index 28f2c6391..64b8e406d 100644 --- a/doc/commands/protection.md +++ b/doc/commands/protection.md @@ -2,18 +2,20 @@ ## Description -Manage protections of a certain arena region +Manage protections of a certain [arena region](../regions.md). **When a protection is enabled, player actions +are prevented.** -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa main protection battlefield DROP | toggle the DROP protection of the arena "main"s region called "battlefield" -/pa hunger !p battlefield INVENTORY true | enable the INVENTORY protection of the arena "hunger"s region called "battlefield" +/pa [arena] protection [region] [protection] (true/false) | toggle a protection of an arena region + +Example: `/pa main protection battlefield DROP` - toggle the DROP protection of the arena "main"s region called "battlefield" ## Details -Erroneous protection flag usage will show you the supported flags, they include: (definition: when active) +Here is a quick list supported flags, they include: - BREAK - prevent player block breaking - FIRE - prevent fire spreading/burning @@ -29,4 +31,7 @@ Erroneous protection flag usage will show you the supported flags, they include: - PICKUP - prevent player item pickup - TELEPORT - prevent player teleportation -Always verify your protections with `/pa [arenaname] !rs [regionname]` \ No newline at end of file +
+ +> **🚩 Tip:** +> Check your protections with [`/pa [arenaname] !rs [regionname]`](regions.md) diff --git a/doc/commands/ready.md b/doc/commands/ready.md new file mode 100644 index 000000000..fe989dd00 --- /dev/null +++ b/doc/commands/ready.md @@ -0,0 +1,12 @@ +# Ready Command + +## Description + +This command passes players to "ready" state or lists ready players. It must be typed inside an arena. + +## Usage + +Command | Definition +------------- | ------------- +/pa ready | pass a player in "ready" state +/pa ready list | list ready players in current arena \ No newline at end of file diff --git a/doc/commands/region.md b/doc/commands/region.md index 2dfe4f8e5..17fab65be 100644 --- a/doc/commands/region.md +++ b/doc/commands/region.md @@ -2,26 +2,30 @@ ## Description -Set up regions for an arena. Oh, and show their borders. ... and set some WIP values +Manage regions for an arena. More information is available [on dedicated page](../regions.md). -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa free region | start setting up a region for the arena "free" -/pa free !r ball | save the cuboid region "ball" to the arena "free" -/pa ctf !r X spher | save the spheric region "X" to the arena "ctf" -/pa ctf !r remove X | remove the region "X" from the arena "ctf" -/pa free !r ball border | shows the border around the region "ball" of the arena "free" - +/pa [arena] region | start setting up a region for an arena (type again to leave region editor) +/pa [arena] region [regionName] (shape) | save a region for the arena. Cuboid is the default shape +/pa [arena] region [regionName] remove | remove an arena region +/pa [arena] region [regionName] border | show limits of a region + +Example: +- `/pa free !r ball` - save the cuboid region "ball" to the arena "free" +- `/pa ctf !r X remove` - remove the region "X" from the arena "ctf" ## Details +If we have to sum up, setting up an arena needs 3 things: + +- `/pa [arenaname] region` +- select two points that define the region +- `/pa [arenaname] region [regionshape]` -For a better display of HOW to setup regions, you might want to check out our tutorial section. -Setting up an arena needs 3 things: +Check out [our tutorial section](../regions.md) for more information. -`/pa [arenaname] region` -select two points that define the region -`/pa [arenaname] region [regionshape]` +
Valid regionshapes include: diff --git a/doc/commands/regionclear.md b/doc/commands/regionclear.md index b003f99ab..d1afde40b 100644 --- a/doc/commands/regionclear.md +++ b/doc/commands/regionclear.md @@ -2,20 +2,24 @@ ## Description -This command manages the regions' clearing behaviour by adding/removing exceptions. +By default, at the end of a match, all entities are removed from [arena regions](../regions.md). If you want to keep some kind of entities +(like armor stands for instance), you can manage an exception list with this command. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa ctf regionclear VILLAGER | toggle the VILLAGER clearing of the arena "ctf" -/pa ctf !rc TNT true | enable the TNT clearing exception of the arena "ctf" (ALLOW TNT to stay after clearing!) +/pa [arena] regionclear [entity] (true/false) | toggle entity clearing of an arena -## Details -Valid entitytypes will be told when you mistype, or you can find them here: +Example: +- `/pa ctf regionclear VILLAGER` - toggle the VILLAGER clearing of the arena "ctf" +- `/pa ctf !rc TNT true` - add a clearing exception for TNT in the arena "ctf" (ALLOW TNT to stay after clearing!) + +## Details -https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/EntityType.html +Valid entitytypes will be told when you mistype, or you can find them +[on this page](https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/EntityType.html). Giving no second argument will just toggle exception status and show you the result, valid arguments to activate/deactivate include: diff --git a/doc/commands/regionflags.md b/doc/commands/regionflags.md index 53020dcd0..0cebace49 100644 --- a/doc/commands/regionflags.md +++ b/doc/commands/regionflags.md @@ -2,14 +2,15 @@ ## Description -This command manages the regions' behaviour by enabling/disabling flags. +This command manages the [regions](../regions.md) behaviour by enabling/disabling flags. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa ctf regionflag death1 DEATH | toggle the DEATH regionflag for the region "death1" of the arena "ctf" -/pa ctf !rf win2 WIN true | enable the WIN regionflag for the region "win2" of the arena "ctf" +/pa [arena] regionflag [region] [flag] (true/false) | toggle regionflag for an arena region + +Example: `/pa ctf !rf win2 WIN true` - enable the WIN regionflag for the region "win2" of the arena "ctf" ## Details @@ -17,8 +18,8 @@ There are several region flags that can be set: - NOCAMP - move in here, or get punished ! - DEATH - come in, die ! -- WIN - come in, WIN ! -- LOSE - come in, LOSE ! +- WIN - come in, win ! +- LOSE - come in, lose ! - NODAMAGE - players are invincible ! Giving no second argument will just toggle the flag status and show you the result, valid arguments to activate/deactivate include: diff --git a/doc/commands/regions.md b/doc/commands/regions.md index 150a8ae05..0f103173a 100644 --- a/doc/commands/regions.md +++ b/doc/commands/regions.md @@ -2,14 +2,16 @@ ## Description -This command displays a list of arena regions / their properties. +This command displays a list of arena [regions](../regions.md) / their properties. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa free regions | list all arena regions of "free", and their shape and type -/pa free !rs ball | debug print properties of the region "ball" of the arena "free" +/pa [arena] regions | list all regions of an arena +/pa [arena] regions [region] | display properties of a given arena region + +Example: `/pa free !rs ball` - print properties of the region "ball" of the arena "free" ## Details diff --git a/doc/commands/regiontype.md b/doc/commands/regiontype.md index ca630b3ee..c87d812f0 100644 --- a/doc/commands/regiontype.md +++ b/doc/commands/regiontype.md @@ -2,47 +2,28 @@ ## Description -This command sets the region type which is essential for its functionality. +This command sets the [region](../regions.md) type which is essential for its functionality. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa ctf regiontype exit EXIT | set the "ctf" region "exit" type to EXIT -/pa ctf !rt battlefield BATTLE | set the "ctf" region "battlefield" to BATTLE +/pa [arena] regiontype [region] [type] | change the type of an arena regions + +Example: `/pa ctf !rt battlefield BATTLE` - set the "ctf" region "battlefield" to BATTLE ## Details The region types include: -- CUSTOM => a default / module added region -- WATCH => the spectator region -- LOUNGE => the ready lounge region -- BATTLE => the battlefield region -- EXIT => the exit region -- JOIN => the join region -- SPAWN => the spawn region -- BL_INV => blacklist inventory access -- WL_INV => whitelist inventory access - -### BL_INV - -This region type blocks chest access for every team whichs name is in the region name, same for classes - -example names: - -`xxbluexx` => disallows the blue team -`RedSwordsman` => disallows the red team and any Swordsman - -### WL_INV - -This region type restricts chest access to teams / classes which names are part of the region name - -example names: - -`RedBlueRanger` => allows Red and Blue and Rangers to access chests -`%infected%` => allows the infected (class) to access chests - -## Todo - -add functionality like protection to the other region types +- CUSTOM +- WATCH +- LOUNGE +- BATTLE +- EXIT +- JOIN +- SPAWN +- BL_INV +- WL_INV + +Usage of each region type is detailed on [region documentation page](../regions.md#region-types). diff --git a/doc/commands/reload.md b/doc/commands/reload.md index bb926f514..702e4599a 100644 --- a/doc/commands/reload.md +++ b/doc/commands/reload.md @@ -5,13 +5,15 @@ The reload command does what you might think it does. It reloads the arena by force stopping it, removing it from the arena list, and loading it from the config definition. If you don't specify an arena and are not part of an arena, this command reloads all arenas. -## Usage Examples +## Usage Command | Definition ------------- | ------------- /pa reload | reload everything or the arena you're part of /pa reload ymls | reload main config, language and help ymls -/pa reload CTF | reload the arena called CTF +/pa [arena] reload | reload a specific arena + +Example: `/pa ctf reload` - reload the arena called CTF ## Details diff --git a/doc/commands/remove.md b/doc/commands/remove.md index 959e2cfac..7f087d7a4 100644 --- a/doc/commands/remove.md +++ b/doc/commands/remove.md @@ -4,17 +4,16 @@ This command does only one thing: Remove the arena. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa test remove | remove the "test" arena -/pa temp remove | remove the "temp" arena +/pa [arena] remove | remove an arena -## Hazards -Well, once you did that, the file is gone. So when unsure, either make backups or use disable instead of remove. +Example: `/pa test remove` - remove the "test" arena -## Todo +## Hazards -Maybe some day I'll add a confirmation that tells you about the fact that the arena will be gone "for a long time" ;) +Well, once you did that, the associated file is deleted. So when unsure, either make backups or use +[disable](disable.md) command instead of remove. \ No newline at end of file diff --git a/doc/commands/round.md b/doc/commands/round.md index 3fddb978b..1a2e8bf89 100644 --- a/doc/commands/round.md +++ b/doc/commands/round.md @@ -1,20 +1,23 @@ # Round Command +> ⚠ This command has NOT been tested at ALL! Use at your own risks. + ## Description This command is a WIP to manage "round behaviour" in arenas. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa free round | list rounds of arena "free" -/pa free round 1 | list goals of round 1 of arena "free" -/pa free round 1 Tank | Toggle the Tank goal for the first round of the arena "free" - -## Hazards - -This command has NOT been tested at ALL! This should be warning enough oO +/pa [arena] round | list rounds of an arena +/pa [arena] round [roundNumber] | list goals of an arena round +/pa [arena] round [roundNumber] [goal] | toggle a specific goal for a round of an arena + +Example: +- `/pa free round` - list rounds of arena "free" +- `/pa free round 1 ` - list goals of round 1 of arena "free" +- `/pa free round 1 Tank` - toggle the Tank goal for the first round of the arena "free" ## Details diff --git a/doc/commands/set.md b/doc/commands/set.md index 671795645..0da503543 100644 --- a/doc/commands/set.md +++ b/doc/commands/set.md @@ -2,30 +2,37 @@ ## Description -Sets a specific config node, or lists possible nodes. +Sets a specific config node of an arena configuration, or lists possible nodes. +It's an alternative to manually edit your config files. -## Usage Examples +> ⚠ If you mess up you might change the wrong node, erase parts of the config and render your config useless. +So only use this if you know what you're doing. + +## Usage Command | Definition ------------- | ------------- -/pa test set 0 | get the first page of the arena "test" -/pa test set minPlayers 5 | requires the "test" arena to have 5 players before starting - -## Hazards +/pa [arena] set [pageNumber] | show a list of editable config nodes of your arena +/pa [arena] set [configNode] [value] | edit the value of an arena config node -If you mess up you might change the wrong node, erase parts of the config and render your config useless. So only use this if you know what you're doing. +Examples : +- `/pa test set 0` - get the first page of editable nodes of the arena "test" configuration +- `/pa test set minPlayers 5` - require the "test" arena to have 5 players before starting ## Details -A number as only argument lists that page, a node and value tries to set the config node to the given value. - -You know know what the node types on the pages mean, but here they are: - -- boolean - true or false -- string - a word -- int - a whole number -- double - a decimal (e.g. 0.5) -- tp - a spawn point (exit, old, spectator) -- item - a bukkit ENUM or ID of a material -- items - e.g. class items, see the corresponding page about item definitions - +The value of a configuration node depends on its type. These types are show when you use `/pa [arena] set [pageNumber]`. +However, it's quite simple to guess a node type. +There are severals categories of types and here is how to set them : +- **boolean:** Quite simple, just type `true` or `false` +- **numbers:** They can be integer or floating-point numbers. Just type them after the name of your config node +- **string:** The easiest, just type the word you want. +- **material:** The name of a bukkit material. You can directly type material names picked from +[this list](https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html) or type `hand` to get items you're +holding in your hand. +- **items:** A list of items is expected (for instance to give rewards). Type `inventory` to convert all your current +inventory to a list of items (metadata will be saved) or use `hand` get only get the item you're holding. + +> 🚩 **NB:** +> If you want to define items or material nodes directly in your config file, please check +>[this documentation](../items.md). \ No newline at end of file diff --git a/doc/commands/setowner.md b/doc/commands/setowner.md index 7f01ac749..117c1eaf2 100644 --- a/doc/commands/setowner.md +++ b/doc/commands/setowner.md @@ -2,12 +2,15 @@ ##Description -This command hands over ownership. This has to be either "%server%" or a player name. Note that the player name is NOT checked, but you can verify it with `/pa info` +This command hands over ownership. This has to be either "%server%" or a player name. Note that the player name is +NOT checked, but you can verify it with [`/pa info`](../commands.md#arena-standard-commands) ##Usage Examples Command | Definition ------------- | ------------- -/pa slip setowner slipcor | give slipcor ownership of the arena "slip" -/pa global setowner %server% | remove player ownership from the arena "global", set the server as owner +/pa [arena] setowner [player] | give player ownership of an arena + + +Example: `/pa global setowner %server%` - set the server as owner of the "global" arena diff --git a/doc/commands/spawn.md b/doc/commands/spawn.md index 9c9262d7b..1766a775d 100644 --- a/doc/commands/spawn.md +++ b/doc/commands/spawn.md @@ -4,22 +4,36 @@ Set an arena spawn to your current position, including orientation ! -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa ctf spawn redspawn | sets the red team's spawn of the arena "ctf" -/pa free spawn spawnEAST | sets "spawnEAST" of the arena "free" +/pa [arena] spawn [spawnName] | Define a spawn for an arena + + +Example: +- `/pa ctf spawn redspawn` - sets the red team's spawn of the arena "ctf" +- `/pa free spawn spawnEAST` - sets "spawnEAST" of the arena "free" ## Details -If you get a message "spawn unknown", this is probably because you did not install / activate a goal / module ; be sure that you install and activate stuff you want to add, -e.g. the "Flags" goal, or the "StandardSpectate" module... +There are two syntax according to the [gamemode](gamemode.md) of your arena : +- If you're using a "free" arena, you can define unlimited spawns using syntax `/pa myArena spawn spawnX` where X should + be anything (word, digit, letter, etc). +- If your arena works with teams, you have to use `/pa myArena spawn teamspawn` where "team" is the name of one of your +team. + + +If you get a message "spawn unknown", this is probably because you did not install/activate a [goal](../goals.md) or +a [module](../modules.md). +Be sure you have installed and activated stuff you want to add, for instance the "Flags" goal, or the "StandardSpectate" +module... ## Spawn Offset -Since v1.3.1.31 you can define unique offsets for each spawn name, in order to not be placed on the block center but rather one edge: +You can define unique offsets for each spawn name, in order to not be placed on the block center but rather one edge: -- /pa {arenaname} spawn [spawnname] offset X Y Z +- `/pa [arena] spawn [spawnname] offset X Y Z` -For example 0.5 0 0.5 as X Y Z would work setting you on an edge. You might want to keep F3 at hand to see if you actually have to add or subtract to get to the right edge. \ No newline at end of file +For example 0.5 0 0.5 as X Y Z would work setting you on an edge. +You might want to keep F3 at hand to see if you actually have to add or subtract to get to the right edge. \ No newline at end of file diff --git a/doc/commands/start.md b/doc/commands/start.md index 323f5cbca..f471aa23e 100644 --- a/doc/commands/start.md +++ b/doc/commands/start.md @@ -4,13 +4,17 @@ This command force starts an arena for testing purposes or when players don't manage to get ready on their own. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa test start | force start the arena called "test" +/pa [arena] start | force start an arena + +Example: +- `/pa test start` - force start the arena called "test" ## Hazards -If you start a game with only one player, the results may vary depending on the goals and the environment. You should know what you're doing ;) \ No newline at end of file +If you start a game with only one player, the results may vary depending on the goals and the environment. +You should know what you're doing ;) \ No newline at end of file diff --git a/doc/commands/stats.md b/doc/commands/stats.md index c6dd93c06..094669396 100644 --- a/doc/commands/stats.md +++ b/doc/commands/stats.md @@ -4,14 +4,19 @@ This command displays the top X players in a specific statistics type. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa stats LOSSES | shows the top 10 losers -/pa stats WINS 5 | shops the top 5 winners +/pa stats [statistic] (number) | show top 10 of a statistic for all the server. Change results size with "number" parameter. +/pa [arena] stats [statistic] (number) | show top 10 of a statistic for current arena game -Valid values are : +Examples: +- `/pa ctf stats DAMAGE` - shows the top 10 player damaged for the current CTF game +- `/pa stats WINS 5` - shops the top 5 winners for all the server + +## Details +Valid statistic values are : - WINS - LOSSES diff --git a/doc/commands/stop.md b/doc/commands/stop.md index 20886f829..81d4a1204 100644 --- a/doc/commands/stop.md +++ b/doc/commands/stop.md @@ -4,13 +4,12 @@ This command force stops an arena in case players are stuck / the game freezes and so on. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa test stop | force stop the arena called "test" +/pa [arena] stop | force stop an arena -## Hazards - -Should be clear, but... players will lose eventual game status that goals might offer. The arena game will start from scratch ;) \ No newline at end of file +Example: +- `/pa test stop` - force stop the arena called "test" \ No newline at end of file diff --git a/doc/commands/teams.md b/doc/commands/teams.md index 2df025e95..cc07e96fa 100644 --- a/doc/commands/teams.md +++ b/doc/commands/teams.md @@ -4,32 +4,38 @@ The teams command adds team management. Add, set and remove teams! -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa *(arena)* teams set blue GREEN | Set the blue team's color to green -/pa *(arena)* teams add yellow YELLOW | Add a yellow team -/pa *(arena)* teams remove blue | Remove the blue team -/pa *(arena)* teams | list all teams +/pa [arena] teams add [team] [color] | Add a new team to an arena +/pa [arena] teams set [team] [color] | Set color to existing team +/pa [arena] teams remove [team] | Remove a team +/pa [arena] teams | list all teams + +Examples: +- `/pa test teams set blue GREEN` - Set the blue team's color to green in the arena "test" +- `/pa ctf teams add yellow YELLOW` - Add a yellow team to the "ctf" arena ## Details You will need a proper color as a value. The possible colors are as follows: -- WHITE -- ORANGE -- MAGENTA -- LIGHT_BLUE -- YELLOW -- LIME -- PINK -- GRAY -- SILVER -- CYAN -- PURPLE -- BLUE -- GREEN -- RED -- BLACK +- AQUA +- BLACK +- BLUE +- DARK_AQUA +- DARK_BLUE +- DARK_GRAY +- DARK_GREEN +- DARK_PURPLE +- DARK_RED +- GOLD +- GRAY +- GREEN +- LIGHT_PURPLE +- RED +- WHITE +- YELLOW + diff --git a/doc/commands/teleport.md b/doc/commands/teleport.md index 5e0f024de..baf8f3f2e 100644 --- a/doc/commands/teleport.md +++ b/doc/commands/teleport.md @@ -2,19 +2,19 @@ ## Description -Teleports you to a specific spawn point of an arena. +Teleports you to a specific spawn point of an arena. This command should be for administration purpose and +not during game. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa free teleport spawn2 | teleport to the spawn "spawn2" of arena "free" -/pa free teleport spawn | teleport to a random spawn of arena "free" -/pa ctf !tp bluespawn | teleport to the blue spawn of arena "ctf" +/pa [arena] teleport [spawnPoint] | teleport to a spawn point of an arena -## Hazards +Examples: +- `/pa free teleport spawn` - teleport to a random spawn of arena "free" +- `/pa ctf !tp bluelounge` - teleport to the blue lounge of arena "ctf" -You might not want to do that ingame unless you're godded ;) ## Details diff --git a/doc/commands/togglemod.md b/doc/commands/togglemod.md index a078af80b..006979744 100644 --- a/doc/commands/togglemod.md +++ b/doc/commands/togglemod.md @@ -4,18 +4,16 @@ Toggles a module on or off. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa free togglemod BattleGears | Toggles mod "BattleGears" in arena "free" -/pa ctf togglemod StandardSpectate | Toggles mod "Standard Spectate" in arena "ctf" -/pa ctf !tm WorldEdit | Toggles mod "WorldEdit" in arena "ctf" +/pa [arena] togglemod [module] | Toggles a mod for an arena -## Hazards - -You may need to restart your server for some mods to hook or take effect. +Example: +- `/pa ctf !tm WorldEdit` - Toggles mod "WorldEdit" in "ctf" arena ## Details -Toggling a mod allows you to simply change if a module is active or not. You can do further setting tweaks using the module-specific command or `/pa set` \ No newline at end of file +Toggling a mod allows you to simply change if a module is active or not. +You can do further setting tweaks using the module-specific command or [`/pa set`](set.md). \ No newline at end of file diff --git a/doc/commands/uninstall.md b/doc/commands/uninstall.md deleted file mode 100644 index 10c062734..000000000 --- a/doc/commands/uninstall.md +++ /dev/null @@ -1,17 +0,0 @@ -# Uninstall command - -## Description - -This command manages removal of modules. You can list available modules, see your current state, and remove installed modules. - -## Usage Examples - -Command | Definition -------------- | ------------- -/pa uninstall | list all available modules -/pa uninstall worldedit | uninstall the worldedit module - -## Details - -The list contains all available modules, with their respective version. Yellow names mark installed plugins, green version numbers mark as up to date, -red version numbers show that you need to update the files. \ No newline at end of file diff --git a/doc/commands/update.md b/doc/commands/update.md deleted file mode 100644 index 4b8758513..000000000 --- a/doc/commands/update.md +++ /dev/null @@ -1,20 +0,0 @@ -# Update command - -## Description - -This command manages updating of modules. You can list available modules, see your current state, and update modules. - -## Usage Examples - -Command | Definition -------------- | ------------- -/pa update | list all available modules -/pa update worldedit | update the worldedit module - -## Hazards - -Know your versions. If unsure, download the latest zip file from the files section, replace the files inside /files and then you can be sure you're up to date. Outdated modules lead to errors. - -## Details - -The list contains all available modules, with their respective version. Yellow names mark installed plugins, green version numbers mark as up to date, red version numbers show that you need to update the files. \ No newline at end of file diff --git a/doc/commands/whitelist.md b/doc/commands/whitelist.md index 695f54edf..4114f6a34 100644 --- a/doc/commands/whitelist.md +++ b/doc/commands/whitelist.md @@ -2,18 +2,20 @@ ## Description -This command manages the block place / break whitelist for an arena. +This command manages the block place / break whitelist for an arena. With this, you're able to restrict actions +in your arena. -## Usage Examples +## Usage Command | Definition ------------- | ------------- -/pa ctf whitelist clear | clear the general whitelist -/pa ctf whitelist break clear | clear the BREAK whitelist -/pa ctf whitelist break add SNOW | add SNOW to the BREAK whitelist -/pa ctf whitelist PLACE show | show the PLACE whitelist -/pa ctf whitelist break remove SNOW | remove SNOW from the BREAK whitelist +/pa [arena] whitelist clear | clear the general whitelist +/pa [arena] whitelist [break/place] clear | clear the BREAK or the PLACE whitelist +/pa [arena] whitelist [break/place] show | show a whitelist content +/pa [arena] whitelist [break/place] add [block] | add a block to a whitelist +/pa [arena] whitelist [break/place] remove [block] | remove a block from a whitelist -## Details +Example: `/pa ctf whitelist break add SNOW` - add SNOW block to the BREAK whitelist -Both ENUMs and ITEM IDs work, you can even add DATA values, e.g. WOOL:13 \ No newline at end of file +> **🚩 Tip:** +> [`/pa blacklist`](blacklist.md) command works exactly in the same way \ No newline at end of file diff --git a/doc/configuration.md b/doc/configuration.md index 66193d3b0..924ff6a3d 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -1,6 +1,10 @@ -# Configuration File +# Configuration file + +This page explains what are each parameter of arena config file. +All those parameters can be changed via in-game command ([/pa set](commands/set.md)). + +> ℹ This is a default configuration file. -This is a default configuration file. All parameters can be changed via in-game commands ([/pa set](commands/set.md)). ```yaml configversion: 1.3.3.217 chat: @@ -8,7 +12,7 @@ chat: defaultTeam: false #Limit chat to team only enabled: true #Allows chat usage onlyPrivate: false #Limit chat to the arena - toGlobal: none #Begin word to talk to all the arena of onlyPrivate is active. Eg: @all + toGlobal: none #Begin word to talk to all the arena of onlyPrivate is active. E.g. @all cmds: defaultjoin: true #Join the arena if just typing /pa #List of allowed commands in the arena @@ -22,9 +26,9 @@ damage: spawncamp: 1 #If nocamp region flag is enabled, damage set to player weapons: true #Allow weapon damage - false = unbreakable general: - classspawn: false #Create specific class spawns. Eg: blueTankSpawn + classspawn: false #Create specific class spawns. E.g. blueTankSpawn classSwitchAfterRespawn: false #If IngameClassSwitch is enabled, switch class only on next respawn - customReturnsGear: false #If player has custom inventory, reload it on respawn + customReturnsGear: false #If player has custom inventory, reload it after the match enabled: true #Make arena accessible or not gm: 0 #Arena game mode leavedeath: false #Kill the player on battleground leaving diff --git a/doc/enhancements.md b/doc/enhancements.md deleted file mode 100644 index e9cd1092b..000000000 --- a/doc/enhancements.md +++ /dev/null @@ -1,99 +0,0 @@ -There are currently four ways of adding to the game: -# PVP Arena API - -The API features basic access to several things, based on very few requests. If you need something, give me a shout! -## PVP Arena Modules - -### Installation - -Unzip the module files (files tab, "PA Files v\*.\*.\*") into the /pvparena/files folder and install them via -`/pa install [modname]`, **activate per arena via** -`/pa [arenaname] !tm [modname]` - -### PVP Arena Goals - -Create ways to win the game or lose the game! - -Goal | Description -------------- | ------------- -[Beacons](goals/beacons.md) | Stand near beacons and claim them to win! -[BlockDestroy](goals/blockdestroy.md) | Destroy blocks (pre-installed) -[CheckPoints](goals/checkpoints.md) | Reach checkpoints in order to win (pre-installed) -[Domination](goals/domination.md) | Dominate flag positions (pre-installed) -[Flags](goals/flags.md) | Capture flags and bring 'em home (pre-installed) -[Food](goals/food.md) | Cook food and bring it home (pre-installed) -[Infect](goals/infect.md) | Infect people to win / kill infected players (pre-installed) -[Liberation](goals/liberation.md) | Jail dead players, possibility to unjail! (pre-installed) -[PhysicalFlags](goals/physicalflags.md) | Capture flags physically and bring 'em home (pre-installed) -[Pillars](goals/pillars.md) | Capture pillars by clicking/destroying! -[PlayerDeathMatch](goals/playerdeathmatch.md) | Player kills win (pre-installed) -[PlayerKillReward](goals/playerkillreward.md) | Player get better gears when killing (pre-installed) -[Rescue](goals/rescue.md) | Rescue a trapped Entity -[PlayerLives](goals/playerlives.md) | Player deaths lose (pre-installed) -[Sabotage](goals/sabotage.md) | Ignite TNT (pre-installed) -[Tank](goals/tank.md) | all vs one (pre-installed) -[TeamDeathConfirm](goals/teamdeathconfirm.md) | Confirmed Team kills win (pre-installed) -[TeamDeathMatch](goals/teamdeathmatch.md) | Team kills win (pre-installed) -[TeamLives](goals/teamlives.md) | Team deaths lose (pre-installed) -[Time](goals/time.md) | Time ends the arena (pre-installed) - -### PVP Arena Mods - -Hook into many different aspects of the game! - -Mod | Description -------------- | ------------- -[AfterMatch](mods/aftermatch.md) | could also be called "Sudden Death" -[Announcements](mods/announcements.md) | announce events happening -[ArenaBoards](mods/arenaboards.md) | stats display -[ArenaMaps](mods/arenamaps.md) | never lose yourself ever again! -[AutoSneak](mods/autosneak.md) | automatically hide player nametags by forcing sneak mode -[AutoVote](mods/autovote.md) | automatism -[BanKick](mods/bankick.md) | secure your arenas! -[BattlefieldGuard](mods/battlefieldguard.md) | secure your battlefield -[BattlefieldManager](mods/battlefieldmanager.md) | manage your battlefield -[BetterClasses](mods/betterclasses.md) | add potion effects and more to specific classes -[BetterGears](mods/bettergears.md) | give team colored leather -[BetterFight](mods/betterfight.md) | kill streaks and one-hit-kill items! -[BetterKillstreaks](mods/betterkillstreaks.md) | even more detailed kill streaks! -[BlockDissolve](mods/blockdissolve.md) | dissolve blocks under fighting players -[BlockRestore](mods/blockrestore.md) | restore the battlefield -[ChestFiller](mods/chestfiller.md) | fill battlefield chests with customizable content! -[Duel](mods/duel.md) | duel someone! -[EventActions](mods/eventactions.md) | do stuff when stuff happens -[Factions](mods/factions.md) | fix pvp not working -[FixInventoryLoss](mods/fixinventoryloss.md) | prevent loss by gamemode / inventory check -[FlySpectate](mods/flyspectate.md) | have players spectating a fight in fly mode -[Items](mods/items.md) | spawn (random) items -[LateLounge](mods/latelounge.md) | keep playing until enough ppl are joining -[MatchResultStats](mods/matchresultstats.md) | keep stats of player games, who won, who lost? -[PlayerFinder](mods/playerfinder.md) | allow players to find others with a compass -[Points](mods/points.md) | allow to restrict certain classes to require players to fight for better classes -[PowerUps](mods/powerups.md) | exactly that -[RealSpectate](mods/realspectate.md) | spectate the game, CounterStrike style! -[RedstoneTriggers](mods/redstonetriggers.md) | add win/lose triggered by redstone -[RespawnRelay](mods/respawnrelay.md) | add a relay for respawning players -[SinglePlayerSupport](mods/singleplayersupport.md) | Allow players to use an arena on their own! -[Skins](mods/skins.md) | add custom skins to teams/classes -[SpecialJoin](mods/specialjoin.md) | join via buttons, levers, etc -[Spectate](mods/spectate.md) | use the new 1.8 SPECTATOR mode to allow flying and POV spectating -[Squads](mods/squads.md) | add squads to the game, basically only showing players belonging together apart from teams and classes. -[StartFreeze](mods/startfreeze.md) | freeze players at start -[TeamSizeRestrict](mods/teamsizerestrict.md) | a small mod to restrict the size of specific teams -[Titles](mods/titles.md) | send messages to players as the "title" command would do -[TempPerms](mods/tempperms.md) | add temporary perms -[Turrets](mods/turrets.md) | add turrets where players fire projectiles -[Vault](mods/vault.md) | add economy -[Walls](mods/walls.md) | define wall regions to simulate "The Walls" -[WorldEdit](mods/worldedit.md) | backup/restore regions -[WorldGuard](mods/worldguard.md) | import region definitions from WorldGuard - -### PVP Arena Region Shapes - -Create region shapes to customize your arena! Default: COBOID! - -Shape| Description -------------- | ------------- -[CUBOID](shapes/cuboid.md) | a standard region that all should know -[CYLINDRIC](shapes/cylindric.md) | a standing can/barrel region -[SPHERIC](shapes/spheric.md) | a sphere/ball \ No newline at end of file diff --git a/doc/faq.md b/doc/faq.md new file mode 100644 index 000000000..903143c1b --- /dev/null +++ b/doc/faq.md @@ -0,0 +1,49 @@ +# Frequently Asked Questions + +## How I can create a spleef arena? + +When you create a minigame with PVPArena, you have to ask yourself "How will work score calculation?". In spleef case, +when a player dies, he looses the match. + +So you should use the [playerLives](goals/playerlives.md) goal (enabled by default). Build you arena and configure it +following [this guide](getting-started.md). + +You can restore you battlefield (snow ground) using [BlockRestore](mods/blockrestore.md) or +[Worldedit](mods/worldedit.md) module. Please check [modules documentation](modules.md) to learn more. + +
+ +## Can my players use their own inventories? + +Yes it is possible, just pass `playerclasses` parameter to `true`. You can do this directly by editing your config file +or use the [`/pa [arena] set`](commands/set.md) command. + +Then you can propose player inventories as a class: corresponding class name is `custom`. If you want this class by +default, just set `autoclass` parameter to `custom`. + +Finally, if you want to return player inventory as it was before the beginning of the match, pass `customReturnsGear` to +true. + +
+ +## How can I use arena commands from a command block? + +Maybe you will wish to use buttons, pressure plates and command blocks to allowing players to choose their class, get +ready or leave the arena. + +Most of PvPArena commands must be types by players (in order to keep context). So if you want to use plugins commands in +a command block, you will have to use a **sudo** plugin. Utility plugins like +[EssentialsX](https://www.spigotmc.org/resources/essentialsx.9089/) already include this. + +"Sudo" make possible to type a command as if player typed it. For instance, if you a to create a command block to leave +an arena, use the command `sudo @p pa leave`. + +> ⚙ **Technical precision:** +> Since Minecraft 1.13, spigot based servers does no longer support command selectors (like `@p`). If you want to use it +> you will have to use a plugin like [CommandHook](https://www.spigotmc.org/resources/commandhook.61415/). + +
+ +## Still have questions? + +Don't hesitate to [get in touch](../readme.md#support) with us 😉 \ No newline at end of file diff --git a/doc/getting-started.md b/doc/getting-started.md index 629dd43ac..49c314fe3 100644 --- a/doc/getting-started.md +++ b/doc/getting-started.md @@ -1,5 +1,4 @@ - -## Getting Started +# Getting Started
@@ -9,7 +8,7 @@ > -### Foreword: what's an arena? +## Foreword: what's an arena? Before creating your first arena, you have to understand what's. Arena is immaterial, it's a game configuration you create with goals, teams, classes, etc. It references your arena @@ -20,7 +19,7 @@ another place, don't destroy it, just redefine your spawn points and your region
-### 1. Create the arena +## 1. Create the arena Just type this command to create your arena: @@ -29,12 +28,13 @@ Just type this command to create your arena: By default your arena will work with a team system. If you add the `free` option, your arena will work on a *Free for all* (FFA) game mode. -> **🚩 Tip:** This parameter can be changed using [/pa gamemode](commands/gamemode.md) command or in your config file by +> **🚩 Tip:** +> This parameter can be changed using [/pa gamemode](commands/gamemode.md) command or in your config file by > setting `general.type` parameter to `free` or `none`.
-### 2. Set goals for the arena +## 2. Set goals for the arena By default, your arena will use [TeamLives](goals/teamlives.md) goal if your arena is in team mode and [PlayerLives](goals/playerlives.md) goal otherwise. If you're ok with this, go to the next point, otherwise please @@ -43,11 +43,16 @@ continue reading. You can choose a custom goal [in the list](goals.md) and set it for your arena with the command: `/pa [arenaName] goal [goalName]` +Each goal has its own setup, so take the time to read [documentation](goals.md) of the goal you want to use. + You will find more information about this command [on this link](commands/goal.md). +> **Reminder:** +> Don't forget to remove _TeamLives_ goal if you don't use it 😉 +
-### 3. Set spawn points +## 3. Set spawn points Now you have to create game spawn points by using this command: `/pa [arenaName] spawn [spawnType]` @@ -68,7 +73,7 @@ By default you need: 4 spawns (spawn1, spawn2, spawn3, spawn4) / 1 lounge / 1 sp
-### 4. Create the battle region +## 4. Create the battle region > *This step is optional but really useful in mostly configurations* @@ -92,7 +97,7 @@ Finally, specify your region type :
-### 5. Place required items in the lounge +## 5. Place required items in the lounge By default, four classes already exist : Swordsman, Tank, Pyro and Ranger. You can chose to keep these classes or create new ones with the the [class command](commands/class.md). @@ -111,10 +116,11 @@ are ready.
-### 6. Join the arena! +## 6. Join the arena! Your first arena was created! Join the game with: `/pa [arenaName] (join) (teamName)` -> **🚩 Tip:** If you just type `/pa [arenaName]` your team will be randomly selected. \ No newline at end of file +> **🚩 Tip:** +> If you just type `/pa [arenaName]` your team will be randomly selected. \ No newline at end of file diff --git a/doc/goals.md b/doc/goals.md index 6a1667489..568aff2fd 100644 --- a/doc/goals.md +++ b/doc/goals.md @@ -1,26 +1,25 @@ ## PVP Arena Goals -Create ways to win the game or lose the game! +Goals are ways to win the game or lose the game! You can see active goals of your arena with `/pa [arena] info`. -Goal | Description -------------- | ------------- -[Beacons](goals/beacons.md) | Stand near beacons and claim them to win! -[BlockDestroy](goals/blockdestroy.md) | Destroy blocks (pre-installed) -[CheckPoints](goals/checkpoints.md) | Reach checkpoints in order to win (pre-installed) -[Domination](goals/domination.md) | Dominate flag positions (pre-installed) -[Flags](goals/flags.md) | Capture flags and bring 'em home (pre-installed) -[Food](goals/food.md) | Cook food and bring it home (pre-installed) -[Infect](goals/infect.md) | Infect people to win / kill infected players (pre-installed) -[Liberation](goals/liberation.md) | Jail dead players, possibility to unjail! (pre-installed) -[PhysicalFlags](goals/physicalflags.md) | Capture flags physically and bring 'em home (pre-installed) -[Pillars](goals/pillars.md) | Capture pillars by clicking/destroying! -[PlayerDeathMatch](goals/playerdeathmatch.md) | Player kills win (pre-installed) -[PlayerKillReward](goals/playerkillreward.md) | Player get better gears when killing (pre-installed) -[Rescue](goals/rescue.md) | Rescue a trapped Entity -[PlayerLives](goals/playerlives.md) | Player deaths lose (pre-installed) -[Sabotage](goals/sabotage.md) | Ignite TNT (pre-installed) -[Tank](goals/tank.md) | all vs one (pre-installed) -[TeamDeathConfirm](goals/teamdeathconfirm.md) | Confirmed Team kills win (pre-installed) -[TeamDeathMatch](goals/teamdeathmatch.md) | Team kills win (pre-installed) -[TeamLives](goals/teamlives.md) | Team deaths lose (pre-installed) -[Time](goals/time.md) | Time ends the arena (pre-installed) \ No newline at end of file +To manage arena goals, use the [`/pa [arena] goal`](commands/goal.md) command. + +Goal | Description | Supported gamemodes +------------- | ------------- | ----------- +[BlockDestroy](goals/blockdestroy.md) | Destroy block of the other team | team +[CheckPoints](goals/checkpoints.md) | Reach checkpoints in order to win | free +[Domination](goals/domination.md) | Dominate flag/beacon positions | team +[Flags](goals/flags.md) | Capture flags and bring them at home | team +[Food](goals/food.md) | Cook food and bring it home | team +[Infect](goals/infect.md) | Infect people to win or kill infected players | free +[Liberation](goals/liberation.md) | Jail your enemies, free your allies! | team +[PhysicalFlags](goals/physicalflags.md) | Destroy enemy flag and place it at yours | team +[PlayerDeathMatch](goals/playerdeathmatch.md) | Score points by killing players | free & team +[PlayerKillReward](goals/playerkillreward.md) | Player get better gears when killing | free & team +[PlayerLives](goals/playerlives.md) | Last alive players win | free & team +[Sabotage](goals/sabotage.md) | Ignite TNT of the opposing team | team +[Tank](goals/tank.md) | all vs one | free +[TeamDeathConfirm](goals/teamdeathconfirm.md) | Confirmed Team kills win | team +[TeamDeathMatch](goals/teamdeathmatch.md) | Team kills win | team +[TeamLives](goals/teamlives.md) | Last alive team wins | team +[Time](goals/time.md) | Time ends the arena | free & team \ No newline at end of file diff --git a/doc/goals/beacons.md b/doc/goals/beacons.md index 459a3a941..b28a27637 100644 --- a/doc/goals/beacons.md +++ b/doc/goals/beacons.md @@ -15,7 +15,7 @@ A claimed beacon gives points every few seconds (tickinterval) that add up to a The GLASS blocks have to be added. In order to do that, use `/pa [arenaname] beacon`. This toggles edit mode. Don't forget to exit it again after setting the beacons. Set them by clicking the GLASS blocks which will color according to claim status. -## Config Settings +## Config settings - spamoffset => after how many updates should the arena announce? (default: 3) - claimrange => how near need players to be? (default: 3) diff --git a/doc/goals/blockdestroy.md b/doc/goals/blockdestroy.md index 730039194..41b9b61c4 100644 --- a/doc/goals/blockdestroy.md +++ b/doc/goals/blockdestroy.md @@ -1,22 +1,27 @@ # BlockDestroy - ## Description -This activates Blocks (to set), per team. Simply break the block of another team to remove a team life! +> ℹ This goal is designed for **team** gamemode -## Setup +## Description + +Each team have to destroy the block of opponent team(s). Blocks have lives, therefore when a block a no longer life, +its team is eliminated. -Blocks have to be added. In order to do that, use `/pa [arenaname] [teamname]block`. This enables setting. -Do this by clicking the block type (IRON_BLOCK by default) +## Setup -## Config Settings +Firstly, make sure the `blockType` parameter is set as you want. -- blockType \- the material checked for blocks (default: IRON_BLOCK) -- bdlives \- the maximum count of blocks/block destructions a team needs to win +If so, you can register destroyable blocks in your arena config. +In order to do that, use `/pa [arenaname] [teamname]block`. This will enable the selection mode. +Then left-click of the chosen block (that has to be of the defined block type). -## Supported Game Modes +## Config settings -Only supports team game mode! +- `blockType` - the material checked for blocks (default: IRON_BLOCK) +- `bdlives` - the maximum count of blocks/block destructions a team needs to win (default: 1) -## YouTube video +
-[click me](http://www.youtube.com/watch?v=ntloY1BTKHQ) +> 🚩 **Tip:** +> If you choose a colorable block (like RED_WOOL or WHITE_CONCRETE) all its variants will be supported. So you will be +> able, for instance, to set a red block for one team and a blue block for the other one. diff --git a/doc/goals/checkpoints.md b/doc/goals/checkpoints.md index 49cffcaf3..4609b8b3f 100644 --- a/doc/goals/checkpoints.md +++ b/doc/goals/checkpoints.md @@ -1,28 +1,28 @@ # CheckPoints +> ℹ This goal is designed for **free** gamemode + ## Description -CheckPoints is designed for free for all game mode! +Players have to take a path composed by checkpoints. The first one every checkpoint up to the last (in order) wins! -It requires you to set spawns that players have to reach, and in case they get lost, they can get back to the latest checkpoint with /pa checkpoint. -First player to reach every checkpoint up to the last (in order) wins! +> 🚩 **One more thing:** +> Players can get back to the latest checkpoint with /pa checkpoint ## Setup Spawns have to be added. In order to do that, use `/pa [arenaname] checkpoint [number]`. This sets checkpoint number [number]. -Make sure you start with 1 and don't forget to add every single number, or else it will not be possible to win :P - -## Config Settings - -- cpclaimrange => how near need players to be? (default: 5) -- cplives => number of checkpoints to reach -- cptickinterval => the amount of ticks to wait before checking for position (default: 20 = 1 second) +Make sure you start with 1 and don't forget to add every single number, or else it will not be possible to win 😋 -## Warnings +## Config settings -This game mode has to check for player's position. Based on the player and checkpoint count this can lag your server. But, how else should I determine a claimed checkpoint? :p +- `cpclaimrange` - how near need players to be? (default: 5) +- `cplives` - number of checkpoints to reach (default: 10) +- `cptickinterval` - the amount of ticks to wait before checking for position (default: 20 = 1 second) -## Supported Game Modes +
-Free for all +> ⚙ **Technical precision:** +> This goal has to check for player's position. Based on the player and checkpoint count this can lag your server. +> Unfortunately, there is no other way to determine a claimed checkpoint. diff --git a/doc/goals/domination.md b/doc/goals/domination.md index 1d334c517..5271554cb 100644 --- a/doc/goals/domination.md +++ b/doc/goals/domination.md @@ -1,8 +1,8 @@ # Domination -## Description +> ℹ This goal is designed for **team** gamemode -Domination is designed to use teams. As always, it defaults to red and blue. +## Description The game is simple : @@ -36,10 +36,10 @@ Given that flag must be able to change color, you can use the following blocks a * WHITE_TERRACOTTA * WHITE_WALL_BANNER -It suggest you to try glass block with a beacon bottom the flag. When flag will be claimed, glass blocks will change its +I suggest you to try glass block with a beacon bottom the flag. When flag will be claimed, glass blocks will change its color, altering beacon light ray in the same time :wink: -## Config Settings +## Config settings - spamoffset => after how many updates should the arena announce? (default: 3) - claimrange => how near need players to be? (default: 3) @@ -49,11 +49,9 @@ color, altering beacon light ray in the same time :wink: - tickinterval => the amount of ticks to wait before doing an update. (default: 60 = 3 seconds) - tickreward => the amount of points to give for each score. (default: 1) -## Warnings - -This game mode has to check for player's position. Based on the player count this can lag your server. -But, how else should I determine a claimed flag? :p +
-## YouTube video (legacy) +> ⚙ **Technical precision:** +> This goal has to check for player's position. Based on the player and checkpoint count this can lag your server. +> Unfortunately, there is no other way to determine a claimed checkpoint. -[click me](http://www.youtube.com/watch?v=Xi7yNURxAjw) diff --git a/doc/goals/flags.md b/doc/goals/flags.md index 260c46ef8..2b2b0cb7d 100644 --- a/doc/goals/flags.md +++ b/doc/goals/flags.md @@ -1,8 +1,10 @@ # Flags +> ℹ This goal is designed for **team** gamemode + ## Description -This activates Flags (to set), per team. Team A captures the flag of team B and brings it home. +There is a flag per team. Team A captures the flag of team B and brings it home. To do this, simply hit/click on flags. ## Setup @@ -23,27 +25,26 @@ of the following material (color prefix doesn't matter): * WHITE_TERRACOTTA * WHITE_WALL_BANNER -  +
Flags have to be added afterwards. In order to do that, use `/pa [arenaname] [teamname]flag` \- this enables setting. Just left click on your flag block. Clicked block must have same type as defined in your config. However nothing will happen. +> 🚩 **One more thing:** You can activate a special "touchdown" way of playing. Set a flag called "touchdown", it will be BLACK ingame. Players claim this flag and bring it home. Only one team can bring this flag home, obviously :) -## Config Settings +
+ +## Config settings -- flives \- the count of flags being brought home that lead to winning -- flagType \- the material checked for flags (default: WHITE_WOOL). Plugin handle automatically flag colors if flagType +- `flives` \- the count of flags being brought home that lead to winning +- `flagType` \- the material checked for flags (default: WHITE_WOOL). Plugin handle automatically flag colors if flagType is a colorable item. -- mustBeSafe \- do claimed flags prevent bringing home other flags? \- (default: true) -- woolFlagHead \- should PVP Arena enforce putting a wool head on flag carriers? - (default: true) -- effect \- the potion effect a player should get when carrying the flag (default: none; possible value: SLOWx2 - -slowness, level 2) ; see bukkit docs -- alterOnCatch \- change flag aspect when a player catch it. If flag is colorable (list below), color is passed to white +- `mustBeSafe` \- do claimed flags prevent bringing home other flags? \- (default: true) +- `woolFlagHead` \- should PVP Arena enforce putting a wool head on flag carriers? - (default: true) +- `effect` \- the potion effect a player should get when carrying the flag (default: none; possible value: SLOWx2 - +slowness, level 2) ; [see bukkit docs](https://hub.spigotmc.org/javadocs/spigot/org/bukkit/potion/PotionEffectType.html) +- `alterOnCatch` \- change flag aspect when a player catch it. If flag is colorable (list below), color is passed to white otherwise block is replaced by bedrock. (default: true) - -## YouTube video (legacy) - -[click me](http://www.youtube.com/watch?v=SuL78bce-f0) diff --git a/doc/goals/food.md b/doc/goals/food.md index a937bde90..844b49127 100644 --- a/doc/goals/food.md +++ b/doc/goals/food.md @@ -1,18 +1,22 @@ # Food +> ℹ This goal is designed for **team** gamemode + ## Description -Your players are hungry! The first team gathering enough cooked food items (of their type) wins the game. +Players are hungry! The first team gathering enough **cooked** food items (of their type) wins the game. The following food types exist: +- Beef +- Chicken +- Cod +- Mutton +- Porkchop +- Potato +- Salmon -- RAW_BEEF => COOKED_BEEF -- RAW_CHICKEN => COOKED_CHICKEN -- RAW_FISH => COOKED_FISH -- POTATO_ITEM => BAKED_POTATO -- PORK => GRILLED_PORK - -Note: the module does NOT include coal or furnaces, you have to manage that on your own :) +> 🚩 **Note:** +> The module does NOT include coal or furnaces, you have to manage that on your own ## Setup @@ -20,22 +24,17 @@ You have to prepare chests. To define those, use `/pa [arenaname] [teamname]food Finish the setting by clicking the chest that should be the team's chest. -This chest will be checked for incoming and outgoing food items (of the team type) You can optionally prepare furnaces so that a team can ONLY use this furnace. - -Set this by `/pa [arenaname] [teamname]foodfurnace` and hit the furnace. Teams not having a corresponding furnace will be able to access all of them. Note that one furnace can be set multiple times ! - -So red/blue can share a furnace and green/yellow :) Just set the same spot for multiple teams. - -## Config Settings - -- fmaxitems \- the item count that triggers win (default: 50) -- fplayeritems \- the item count players receive on start and respawn \- (default: 50) -- fteamitems \- the item count the team receives on start, divided by team members \- (default: 100) +This chest will be checked for incoming and outgoing food items (of the team type). You can optionally prepare furnaces so that a team can ONLY use this furnace. -## Supported Game Modes +Set this by `/pa [arenaname] [teamname]foodfurnace` and hit the furnace. -Only supports team game mode! +> 🚩 **Notes:** +> - Teams not having a corresponding furnace will be able to access all of them. +> - One furnace can be set multiple times! Just set the same spot for multiple teams. For example, +> red and blue teams can share the same furnace. -## YouTube video +## Config settings -[click me](http://www.youtube.com/watch?v=ntloY1BTKHQ) +- `fmaxitems` \- the item count that triggers win (default: 50) +- `fplayeritems` \- the item count players receive on start and respawn \- (default: 50) +- `fteamitems` \- the item count the team receives on start, divided by team members \- (default: 100) diff --git a/doc/goals/infect.md b/doc/goals/infect.md index 634c0514a..9f9faab2c 100644 --- a/doc/goals/infect.md +++ b/doc/goals/infect.md @@ -1,28 +1,23 @@ # Infect +> ℹ This goal is designed for **free** gamemode + ## Description -Quite simple. A random player is infected, he can have special gear and it's everyone against that player. +A random player is infected, he can have special gear and everyone is against that player. Killing an infected player kicks him out of the game, killing a non infected player infects him. Either the infected win by killing everyone else, or the other way round. ## Setup -At least one special "infected" spawn has to be set. You know how to do that, right? `/pa [arena] spawn infected*` - -The other spawns are set like the standard free for all goals, with spawns named like spawn1 through spawn10 or alike. - -You can set a class called "%infected%" in order to give infected players special gear - -## Config Settings - -- iilives \- infected player's lives (1) -- inlives \- normal player's lives (1) +At least one special "infected" spawn has to be set. Type the following command: +[`/pa [arena] spawn infected*`](../commands/spawn.md) -## Warnings +The other spawns are set like the standard free for all goals, with spawns named like _spawn1_ through _spawn10_ or alike. -\- +You can set a class called `%infected%` in order to give infected players special gear. -## Supported Game Modes +## Config settings -Only supports free game mode! +- `iilives` \- infected player's lives (default: 1) +- `inlives` \- normal player's lives (default: 1) diff --git a/doc/goals/liberation.md b/doc/goals/liberation.md index 81235331b..3d0f34668 100644 --- a/doc/goals/liberation.md +++ b/doc/goals/liberation.md @@ -1,22 +1,22 @@ # Liberation +> ℹ This goal is designed for **team** gamemode + ## Description A medium complex game mode. Dead players are teleported to the killer team's jail. -They can be unjailed, liberated, get one life back, so to speak :) +Other team member of jailed players can liberate them by clicking on a button, giving them one life back. ## Setup -You have to add spawns for the jails, set them like every other spawn (bluejail, redjail) and on top of that, -you have to set a button that will trigger the liberation of jailed players. - -It needs to be a stone block, and you set it with `/pa [arenaname] [teamname]button` \- Set it by clicking the button. - -## Config Settings - -- llives \- the lives players have before being put to prison +You have to add spawns for the jails, set them with command [`/pa [arena] spawn [team]jail`](../commands/spawn.md). +Then you have to set a button, at the outside of the jail, that will trigger the liberation of jailed players. To do +that: +- place a **stone button** where you want +- type `/pa [arenaname] [teamname]button` (to open selection mode) +- do a left-click on your button -## Supported Game Modes +## Config settings -Only supports team game mode! +- `llives` \- the lives players have before being put to prison (default: 3) diff --git a/doc/goals/physicalflags.md b/doc/goals/physicalflags.md index 2d4df4731..962fb3657 100644 --- a/doc/goals/physicalflags.md +++ b/doc/goals/physicalflags.md @@ -1,9 +1,11 @@ # PhysicalFlags +> ℹ This goal is designed for **team** gamemode + ## Description -This activates Flags (to set), per team. Team A have to break team B flag and brings it at home. -Point is score when team A place team B flag on its own flag. +There is a flag per team. Team A have to **break** team B flag and brings it at home. +Point is scored when team A place team B flag on its own flag. ## Setup @@ -23,22 +25,25 @@ of the following material (color prefix doesn't matter): * WHITE_TERRACOTTA * WHITE_WALL_BANNER -  +
Flags have to be added afterwards. In order to do that, use `/pa [arenaname] [teamname]flag` \- this enables setting. Just left click on your flag block. Clicked block must have same type as defined in your config. However nothing will happen. +> 🚩 **One more thing:** You can activate a special "touchdown" way of playing. Set a flag called "touchdown", it will be BLACK ingame. Players claim this flag and bring it home. Only one team can bring this flag home, obviously :) -## Config Settings +
+ +## Config settings -- flives \- the count of flags being brought home that lead to winning -- flagType \- the material checked for flags (default: WHITE_WOOL). Plugin handle automatically flag colors if flagType +- `flives` \- the count of flags being brought home that lead to winning +- `flagType` \- the material checked for flags (default: WHITE_WOOL). Plugin handle automatically flag colors if flagType is a colorable item. -- mustBeSafe \- do claimed flags prevent bringing home other flags? \- (default: true) -- woolFlagHead \- should PVP Arena enforce putting a wool head on flag carriers? - (default: true) -- effect \- the potion effect a player should get when carrying the flag (default: none; possible value: SLOWx2 - -slowness, level 2) ; see bukkit docs +- `mustBeSafe` \- do claimed flags prevent bringing home other flags? \- (default: true) +- `woolFlagHead` \- should PVP Arena enforce putting a wool head on flag carriers? - (default: true) +- `effect` \- the potion effect a player should get when carrying the flag (default: none; possible value: SLOWx2 - +slowness, level 2) ; [see bukkit docs](https://hub.spigotmc.org/javadocs/spigot/org/bukkit/potion/PotionEffectType.html) diff --git a/doc/goals/pillars.md b/doc/goals/pillars.md index 474fe89d3..0374b1554 100644 --- a/doc/goals/pillars.md +++ b/doc/goals/pillars.md @@ -1,52 +1,56 @@ -# Pillars - ## Description - -This activates pillars being defined by a wool block / pillar. People can then click/destroy them. Future versions will include actually physically bringing pillar blocks to your base to score - ## Setup - -You have to define pillars. Prepare a WOOL block, this will be the base of the pillar. This base will be the operational block and will react to: - -- clicking -- breaking -- placing against - -(based on your settings) - -In order to do that, use /pa [arenaname] [teamname]pillar* - this enables setting. Finally set the block by clicking the WOOL block. - -Note that there are three kinds of pillars: - -- empty pillar - - starts empty (duh ;) ) - - gains points for everyone, when claimed - - naming: Any name containing "pillar" and NOT containing a team name! -- team pillar (filled) - - starts with the predefined fill height, claimed by the team name - - gains no points for the initial claimed team - - naming: Any name starting with the team name and containing "pillar" -- team pillar (not filled) - - starts empty, only gives points to the team name contained, if claimed - - naming: Any name not starting with the team name, containing pillar, and containing the team name that should NOT get points - - ## Config Settings - -- announcetick (true) - should the score be publicly announced? -- breakable (true) - should you break the base to unclaim and place to claim? -- claimall (false) - should a team win by claiming all pillars? -- onlyfree (true) - only get points for free pillars (only the first type) - -- announceoffset (3) - how many ticks should pass before announcing the current scores? -- emptyheight (1) - how high should free pillars start? -- maxclicks (10) - how many clicks do people need to claim/unclaim? (overrides break allowing!! set to 0 for breaking ;) ) -- maxheight (5) - what is the full height of a pillar? -- pillives (10) - how many points does a team need to win? -- teamheight (2) - how high should a claimed pillar be at start? -- tickpoints (1) - points per pillar per tick (in the future you can disable this, but you shouldnt do this now ;) ) -- tickinterval (20) - the interval (in ticks, 20 per second!) to check for pillar points - -## Supported Game Modes - -Only supports team game mode! - ## YouTube video - -[click me](http://www.youtube.com/watch?v=Xi7yNURxAjw) +# Pillars + +## Description + +This activates pillars being defined by a wool block / pillar. People can then click/destroy them. Future versions will include actually physically bringing pillar blocks to your base to score + +## Setup + +You have to define pillars. Prepare a WOOL block, this will be the base of the pillar. This base will be the operational block and will react to: + +- clicking +- breaking +- placing against + +(based on your settings) + +In order to do that, use /pa [arenaname] [teamname]pillar* - this enables setting. Finally set the block by clicking the WOOL block. + +Note that there are three kinds of pillars: + +- empty pillar + - starts empty (duh ;) ) + - gains points for everyone, when claimed + - naming: Any name containing "pillar" and NOT containing a team name! +- team pillar (filled) + - starts with the predefined fill height, claimed by the team name + - gains no points for the initial claimed team + - naming: Any name starting with the team name and containing "pillar" +- team pillar (not filled) + - starts empty, only gives points to the team name contained, if claimed + - naming: Any name not starting with the team name, containing pillar, and containing the team name that should NOT get points + + +## Config settings + +- announcetick (true) - should the score be publicly announced? +- breakable (true) - should you break the base to unclaim and place to claim? +- claimall (false) - should a team win by claiming all pillars? +- onlyfree (true) - only get points for free pillars (only the first type) + +- announceoffset (3) - how many ticks should pass before announcing the current scores? +- emptyheight (1) - how high should free pillars start? +- maxclicks (10) - how many clicks do people need to claim/unclaim? (overrides break allowing!! set to 0 for breaking ;) ) +- maxheight (5) - what is the full height of a pillar? +- pillives (10) - how many points does a team need to win? +- teamheight (2) - how high should a claimed pillar be at start? +- tickpoints (1) - points per pillar per tick (in the future you can disable this, but you shouldnt do this now ;) ) +- tickinterval (20) - the interval (in ticks, 20 per second!) to check for pillar points + +## Supported Game Modes + +Only supports team game mode! + +## YouTube video + +[click me](http://www.youtube.com/watch?v=Xi7yNURxAjw) diff --git a/doc/goals/playerdeathmatch.md b/doc/goals/playerdeathmatch.md index 2b576632c..3a6abd23b 100644 --- a/doc/goals/playerdeathmatch.md +++ b/doc/goals/playerdeathmatch.md @@ -1,21 +1,15 @@ -# PlayerDeathMatch - ## Description - -This goal adds a counter to players killing others. The first one to have the required number of kills wins the game. - ## Setup - -\- - ## Config Settings - -- tdlives - how many kills does a team need to win? - -## Warnings - -\- - -## Supported Game Modes - -Supports team and free game mode! - ## YouTube video - -[click me](http://www.youtube.com/watch?v=KqBueDNbpD8) +# PlayerDeathMatch + +> ℹ This goal supports **team** and **free** gamemodes + +## Description + +This goal adds a counter to players killing others. The first one to have the required number of kills wins the game. + +## Setup + +There is no special setup. + +## Config settings + +- `tdlives` - how many kills does a team need to win? diff --git a/doc/goals/playerkillreward.md b/doc/goals/playerkillreward.md index 0c744a63d..e4ad5917f 100644 --- a/doc/goals/playerkillreward.md +++ b/doc/goals/playerkillreward.md @@ -1,27 +1,28 @@ -# PlayerKillReward - ## Description - -This activates configurable battle gear being given to players on kill, or on special kills - ## Setup - -There are 5 default kill gears, you can alter them or set new ones with `/pa [arenaname] !kr [kills]` \- of course this means, you have to equip yourself with the gear ppl should have, -and do that command. - -If you want to remove a kill stage, just add another word after the kill number. - -Default kills: - -- 5 \- Leather Armor & Wooden Sword -- 4 \- Chain Armor & Stone Sword -- 3 \- Gold Armor & Iron Sword -- 2 \- Iron Armor & Diamond Sword -- 1 \- Diamond Armor & Diamond Sword - -Note that the Kill number is to be understood as "kills left to win" - ## Config Settings - -\- - -## Supported Game Modes - -Supports team and free game mode! +# PlayerKillReward + +> ℹ This goal supports **team** and **free** gamemodes + +## Description + +In this goal, players have to make kills to wins. When they kill someone, their remaining kill number decreases and +they get a new item set. + +## Setup + +By default, there are 5 default kill gears: +- 5 \- Leather Armor & Wooden Sword +- 4 \- Chain Armor & Stone Sword +- 3 \- Gold Armor & Iron Sword +- 2 \- Iron Armor & Diamond Sword +- 1 \- Diamond Armor & Diamond Sword + +> Note that the Kill number is to be understood as "kills left to win" + +You can alter them or set new ones by doing that: +- Equip your own inventory with wanted gears (place armor and off-hand in good slots) +- Type `/pa [arenaname] !kr [remainingKillNumber]` + +## Config settings + +- `graduallyDown` - on death, keep current number of remaining kills instead of resetting it (default: false) +- `onlyGive` - just give new items to players instead of replacing their inventory (default: false) diff --git a/doc/goals/playerlives.md b/doc/goals/playerlives.md index cc173d6b3..89930d339 100644 --- a/doc/goals/playerlives.md +++ b/doc/goals/playerlives.md @@ -1,21 +1,19 @@ -# PlayerLives - ## Description - -The basic arena goal. Players have individual lives. After a player has run out of lives, he is removed. - ## Setup - -\- - ## Config Settings - -- plives \- the amount of lives a player has before being removed out of the arena - -## Warnings - -\- - -## Supported Game Modes - -Supports team and free game mode! - ## YouTube video - -[FreeForAll](http://www.youtube.com/watch?v=xBIxHoKMu98) +# PlayerLives + +> ℹ This goal supports **team** and **free** gamemodes + +## Description + +The basic arena goal. Players have individual lives. After a player has run out of lives, he is removed. + +> 🚩 **Note:** +> Contrary to [playerDeathMatch](playerdeathmatch.md) goal, here players can lose lives because of external elements +> (lava, falling, drowning, etc) + +## Setup + +There is no special setup. + +## Config settings + +- `plives` \- the amount of lives a player has before being removed out of the arena (default: 3) \ No newline at end of file diff --git a/doc/goals/rescue.md b/doc/goals/rescue.md index 75ad89a3d..0e48637f4 100644 --- a/doc/goals/rescue.md +++ b/doc/goals/rescue.md @@ -1,21 +1,24 @@ -# Rescue - ## Description - -A team game! Each team has a preset place where you hold captive an other team's entity. Invade the other team's base and "rescue" your entity! - ## Setup - -Set the entityspawn with `/pa [team]rescue` and clicking the block on which the entity will be spawned - ## Config Settings - -- rescue.flagType \- the entity Type, default: VILLAGER -- rlives \- the rescue count to achieve -- rescue.mustBeSafe \- can a team only bring home the entity if the own captive is not stolen? -- rescue.effect \- the potion effect for when carrying a rescued entity - -## Warnings - -\- - -## Supported Game Modes - -Only supports team game mode! +# Rescue + +## Description + +A team game! Each team has a preset place where you hold captive an other team's entity. Invade the other team's base and "rescue" your entity! + +## Setup + +Set the entityspawn with `/pa [team]rescue` and clicking the block on which the entity will be spawned + +## Config settings + +- rescue.flagType \- the entity Type, default: VILLAGER +- rlives \- the rescue count to achieve +- rescue.mustBeSafe \- can a team only bring home the entity if the own captive is not stolen? +- rescue.effect \- the potion effect for when carrying a rescued entity + +## Warnings + +\- + +## Supported Game Modes + +Only supports team game mode! diff --git a/doc/goals/sabotage.md b/doc/goals/sabotage.md index 9b791235d..440145ace 100644 --- a/doc/goals/sabotage.md +++ b/doc/goals/sabotage.md @@ -1,19 +1,15 @@ -# Sabotage - ## Description - -This activates TNT blocks (to set) that can be ignited by players that carry proper gear. An ignited TNT kills the team to whom the TNT belongs. - ## Setup - -TNTs have to be added.In order to do that, use `/pa [arenaname] [teamname]tnt` \- this enables tnt setting. Do it by clicking the TNT at the team's base. -Don't click with your wand, just click with your hand or anything else. - ## Config Settings - -\- - -## Warnings - -\- - -## Supported Game Modes - -Only supports team game mode! +# Sabotage + +> ℹ This goal is designed for **team** gamemode + +## Description + +Each team has a TNT block in its base. If this block is ignited by other players, the team is eliminated. + +## Setup + +TNTs have to be added. + +In order to do that, for each team: +- Type `/pa [arenaname] [teamname]tnt` - this enables tnt selector +- Left-click with your hand on the TNT block \ No newline at end of file diff --git a/doc/goals/tank.md b/doc/goals/tank.md index bb6b9313d..dbaaae043 100644 --- a/doc/goals/tank.md +++ b/doc/goals/tank.md @@ -1,20 +1,19 @@ -# Tank - ## Description - -This is a simple round. One random tank is assigned, he has special gear and it's everyone against that tank. Either the tank wins by killing everyone else, or the rest wins by killing the tank. - -You can optionally give a special gear to the tank, set the class "%tank%" - ## Setup - -A special "tank" spawn has to be set. You know how to do that, right? `/pa [arena] spawn tank` - ## Config Settings - -- tank.tlives \- the amount of lives players and the tank have before being removed - -## Warnings - -\- - -## Supported Game Modes - -Only supports free game mode! +# Tank + +> ℹ This goal is designed for **free** gamemode + +## Description + +One random tank is assigned, he has special gear and, everyone is against them. +Either the tank wins by killing everyone else, or the rest wins by killing the tank. + +## Setup + +A special "tank" spawn has to be set. Just type [`/pa [arena] spawn tank`](../commands/spawn.md). + +Optionally, you can give a special gear to the tank by [setting the class](../commands/class.md) `%tank%`. + +## Config settings + +- `tank.tlives` \- the amount of lives players and the tank have before being removed (default: 1) + diff --git a/doc/goals/teamdeathconfirm.md b/doc/goals/teamdeathconfirm.md index 8fe879d8b..2fc9b5662 100644 --- a/doc/goals/teamdeathconfirm.md +++ b/doc/goals/teamdeathconfirm.md @@ -1,23 +1,19 @@ # TeamDeathMatch +> ℹ This goal is designed for **team** gamemode + ## Description -Team play. Team kills are counted by collecting the drops when a player is killed, the first team collecting the set amount of drops wins. +Team kills are counted by collecting the drops when a player is killed, the first team collecting the set amount of drops wins. The big difference to standard PVP is that a team can prevent the other team from scoring by collecting the drops themselves. ## Setup -\- - -## Config Settings - -- tdcitem \- the amount of (enemy) drops a team has to collect in order to win - -## Warnings - -\- +There is no special setup. -## Supported Game Modes +## Config settings -Only supports team game mode! +- `tdcitem` \- item type dropped on player death (default: WHITE_WOOL) +- `tdclives` \- the amount of (enemy) drops a team has to collect in order to win, i.e. number of team lives +(default: 10) diff --git a/doc/goals/teamdeathmatch.md b/doc/goals/teamdeathmatch.md index 5e3372a76..c4adbdfc8 100644 --- a/doc/goals/teamdeathmatch.md +++ b/doc/goals/teamdeathmatch.md @@ -1,21 +1,16 @@ -# TeamDeathMatch - ## Description - -Simple team play. Team kills are counted, the first team killing that many people wins. - ## Setup - -\- - ## Config Settings - -- tdlives \- the amount of kills a team has to achieve in order to win - -## Warnings - -\- - -## Supported Game Modes - -Only supports team game mode! - ## YouTube video - -[click me](http://www.youtube.com/watch?v=rQ1ljlc6SJM) +# TeamDeathMatch + +> ℹ This goal is designed for **team** gamemode + +## Description + +Simple team play. Team kills are counted, the first team killing enough players wins. + +## Setup + +There is no special setup. + +## Config settings + +- `tdlives` - the amount of kills a team has to achieve in order to win (default: 10) +- `suicideScore` - does suicide is taken into account in score calculation? (default: false) diff --git a/doc/goals/teamlives.md b/doc/goals/teamlives.md index be979d884..1d12a2fc7 100644 --- a/doc/goals/teamlives.md +++ b/doc/goals/teamlives.md @@ -1,18 +1,13 @@ -# TeamLives - ## Description - -Very basic. Teams have lives. Once a team runs out of lives, it loses. - ## Setup - -\- - ## Config Settings - -- teamlives.tlives \- the amount of lives a team has before being removed - -## Warnings - -\- - -## Supported Game Modes - -Only supports team game mode! +# TeamLives + +## Description + +Very basic. Teams have lives. Once a team runs out of lives, it loses. + +## Setup + +There is no special setup. + +## Config settings + +- `teamlives.tlives` \- the amount of lives a team has before being removed diff --git a/doc/goals/time.md b/doc/goals/time.md index df76bb67a..bb6a0188d 100644 --- a/doc/goals/time.md +++ b/doc/goals/time.md @@ -1,23 +1,18 @@ -# Time - ## Description - -Guess what it does. \- Yes! it adds a timer, that ends the arena after a certain time. Based on all other active goals, it calculates the winning team/player. - -The scores that each goal gives are subject to change so ... don't rely on the output there :) - ## Setup - -\- - ## Config Settings - -- goal: - - time: - - timedend: 0 # the time in seconds the match should last - - winner: none # the team name that should win as soon as the time runs out - -## Warnings - -\- - -## Supported Game Modes - -Supports team and free game mode! +# Time + +> ℹ This goal supports **team** and **free** gamemodes. + +## Description + +This goal adds a timer, that ends the arena after a certain time. Based on all other active goals, it calculates the winning team/player. + +It is recommended to use this goal with another one. + +## Setup + +There is no special setup + +## Config settings + +- `timedend` - duration of the match in seconds (default: 0 - disabled) +- `winner` - the team name that should win as soon as the time runs out (default: none) diff --git a/doc/history/0.1.md b/doc/history/0.1.md deleted file mode 100644 index b69259dab..000000000 --- a/doc/history/0.1.md +++ /dev/null @@ -1,16 +0,0 @@ -== PVP-Arena v0.1 Changelog - -* v0.1.13 - place bets on a match -* v0.1.12 - display stats with /pa users | /pa teams -* v0.1.11 - config: woolhead: put colored wool on heads! -* v0.1.10 - config: only start with even teams -* v0.1.9 - teleport location configuration -* v0.1.8 - lives! -* v0.1.7 - commands to show who is playing and on what team -* v0.1.6 - custom class: fight with own items -* v0.1.5 - class choosing not toggling -* v0.1.4 - arena disable via command * disable / * enable -* v0.1.3 - ingame config reload -* v0.1.2 - class permission requirement -* v0.1.1 - ready block configurable -* v0.1.0 - release version \ No newline at end of file diff --git a/doc/history/0.10.md b/doc/history/0.10.md deleted file mode 100644 index b8dbb9dc4..000000000 --- a/doc/history/0.10.md +++ /dev/null @@ -1,97 +0,0 @@ -== PVP-Arena v0.10 Changelog - -* v0.10.3.15 - LOGICALLY set the player location before saving the state (for laggy servers) -* v0.10.3.14 - Stop ppl from setting the flags as a SPAWN ... -* v0.10.3.13 - aim to fix CosmoVibe :p -* v0.10.3.12 - allow teleportation into arena regions that are NOT type BATTLE -* v0.10.3.11 - fix Flags. Period. -* v0.10.3.10 - fix BlockDestroy with explosions -* v0.10.3.9 - fix /pa ready -* v0.10.3.8 - add Ticket #227 - player time and auto igniting TNT -* v0.10.3.7 - fix DOM - points lead to winning, not to losing! -* v0.10.3.6 - re-add MODULES_COLORTEAMS_HIDENAME - who removed that?! -* v0.10.3.5 - fix Ticket #197 - readying up mechanism messed up -* v0.10.3.4 - aims to fix Ticket #193 - arena not ending -* v0.10.3.3 - Support TNT in BlockDestroy -* v0.10.3.2 - Several fixes -* v0.10.3.1 - StartRunnable now is on the main... thank you, TagAPI :p -* v0.10.3.0 - violations! -* v0.10.2.36 - ouch ... quick command fix! -* v0.10.2.35 - formatting ? -* v0.10.2.34 - correctly reset Domination and BlockDestroy on start -* v0.10.2.33 - stop people from destroying their own block in BlockDestroy ^^ -* v0.10.2.32 - add a special class being assigned when being the tank: %tank% -* v0.10.2.31 - No more restarts! Modules shall NOT rely on server restarts! - No more restarts! Modules shall NOT rely on server restarts! -* v0.10.2.30 - WorldEdit module announcements -* v0.10.2.29 - fix the arena end timer -* v0.10.2.28 - stop kicking everyone on start !!! -* v0.10.2.27 - add a debug line that might change everything -* v0.10.2.25 - properly fix players dying. Take that, logic!! -* v0.10.2.24 - try to hackfix the hackfix -* v0.10.2.23 - critical fix. WHO REMOVED THAT!!?? -* v0.10.2.22 - fix player death handling -* v0.10.2.21 - add goal: BlockDestroy -* v0.10.2.20 - add goal: PhysicalFlags -* v0.10.2.19 - Pull #4 - Don't return false! -* v0.10.2.18 - some small fixes -* v0.10.2.17 - ignore ready blocks unless not ready -* v0.10.2.16 - BetterFight: explosions on death ^^ -* v0.10.2.15 - add region flag NODAMAGE - yay! -* v0.10.2.14 - add "winner" config in case of timeout! -* v0.10.2.13 - add configurable GAMEMODE :) -* v0.10.2.12 - stop ignoring players being removed! -* v0.10.2.11 - fix AutoVote infinity :D -* v0.10.2.10 - /pa class display error, more debug -* v0.10.2.9 - RelayRunnable implementation -* v0.10.2.8 - rewrite respawn handling -* v0.10.2.7 - add TOUCHDOWN gamemode to Flags -* v0.10.2.6 - add configurable PlayerKillRewards -* v0.10.2.5 - add Goal "PlayerKillRewards" and fix NPE -* v0.10.2.4 - fix book saving and loading -* v0.10.2.3 - add lore saving and loading -* v0.10.2.2 - cancel region selection by redoing /pa [arena] region -* v0.10.2.1 - add configurable POTION EFFECT to flag carriers -* v0.10.2.0 - Debugger rewrite -* v0.10.1.21 - add LOUNGE region type functionality (kick ;) ) -* v0.10.1.20 - allow FFA players to win and lose via region :p -* v0.10.1.19 - I) fix arenas with flags being derpy II) secret. DONT use! -* v0.10.1.18 - attempt to save more than casual items. don't try this at home! - yet -* v0.10.1.17 - save armor when saving a class -* v0.10.1.16 - added default confirmation for /pa [arena] remove -* v0.10.1.15 - add "not enough EXP to choose class" (BetterClasses) -* v0.10.1.14 - addresses Ticket #119 -* v0.10.1.13 - add a configurable timer to start without PVP -* v0.10.1.12 - re-add timer scheduling (WIN,LOSE,DEATH regions) -* v0.10.1.11 - fix Sabotage -* v0.10.1.10 - fix Sabotage Spawn parsing -* v0.10.1.9 - fix Player death parsing -* v0.10.1.8 - fix ArenaRunnable setup -* v0.10.1.7 - fix first smart spawn -.- -* v0.10.1.6 - fix death announcements, clean up death handling -* v0.10.1.5 - finally fix the WarmupJoin module -* v0.10.1.4 - fix NPE about sign joining -* v0.10.1.3 - add /pa [arena] team! -* v0.10.1.2 - remove unused config nodes -* v0.10.1.1 - fix FFA respawning (locations) -* v0.10.1.0 - CraftBukkit 1.4.6 -* v0.10.0.21 - once and for all, fix deathmatches! -* v0.10.0.20 - this should work. fixed DeathMatch respawns! -* v0.10.0.19 - hopefully fix DeathMatch respawns :) -* v0.10.0.18 - fix NPE in DeathMatch :) -* v0.10.0.17 - allow re-joining for Lives and all DeathMatch modules -* v0.10.0.16 - properly check for BATTLE regions instead for "battlefield" -* v0.10.0.15 - fix smart spawning not being implemented in a smart way -* v0.10.0.14 - add debug for a strange bug when teleporting people -* v0.10.0.13 - stop telling people they are already part of arenas! -* v0.10.0.12 - reset fall distance to not kill people twice ;) -* v0.10.0.11 - fix BetterGears -* v0.10.0.10 - fix updating via /pa update mods | /pa update goals -* v0.10.0.9 - version bump for DBO -* v0.10.0.8 - wow, what a fail. sorry guys, updater fixed :D -* v0.10.0.7 - re-add automatic plugin update !! -* v0.10.0.6 - EndRunnable now is Sync - thanks, TagAPI :p -* v0.10.0.5 - activate lounge, spectator and internals by default -* v0.10.0.4 - fix the blacklist/whitelist removal message -* v0.10.0.3 - allow re-joining, if ppl know what they're doing -* v0.10.0.2 - avoid NPE in Time Goal -* v0.10.0.1 - module system rewrite \ No newline at end of file diff --git a/doc/history/0.2.md b/doc/history/0.2.md deleted file mode 100644 index c71c35517..000000000 --- a/doc/history/0.2.md +++ /dev/null @@ -1,4 +0,0 @@ -== PVP-Arena v0.2 Changelog - -* v0.2.1 - cleanup, comments, iConomy 6 support -* v0.2.0 - language support \ No newline at end of file diff --git a/doc/history/0.3.md b/doc/history/0.3.md deleted file mode 100644 index f1b40514f..000000000 --- a/doc/history/0.3.md +++ /dev/null @@ -1,17 +0,0 @@ -== PVP-Arena v0.3 Changelog - -* v0.3.14 - timed arena modes -* v0.3.13 - Telepass via Permission -* v0.3.12 - set flag positions -* v0.3.11 - set regions for lounges, spectator, exit -* v0.3.10 - CraftBukkit #1337 config version, rewrite -* v0.3.9 - Permissions, rewrite -* v0.3.8 - BOSEconomy, rewrite -* v0.3.7 - Bugfixes, Cleanup -* v0.3.6 - CTF Arena -* v0.3.5 - Powerups!! -* v0.3.4 - Rewrite -* v0.3.3 - Random spawns possible for every arena -* v0.3.2 - Classes now can store up to 6 players -* v0.3.1 - New Arena! FreeFight -* v0.3.0 - Multiple Arenas \ No newline at end of file diff --git a/doc/history/0.4.md b/doc/history/0.4.md deleted file mode 100644 index 3d177b4fe..000000000 --- a/doc/history/0.4.md +++ /dev/null @@ -1,7 +0,0 @@ -== PVP-Arena v0.4 Changelog - -* v0.4.4 - Random spawns per team, not shared -* v0.4.3 - max / min bet -* v0.4.2 - command blacklist -* v0.4.1 - command manager, arena information and arena config check -* v0.4.0 - mayor rewrite, improved help \ No newline at end of file diff --git a/doc/history/0.5.md b/doc/history/0.5.md deleted file mode 100644 index 67a6b8bf2..000000000 --- a/doc/history/0.5.md +++ /dev/null @@ -1,13 +0,0 @@ -== PVP-Arena v0.5 Changelog - -* v0.5.11 - CTF flag bug, command error msg improvement -* v0.5.10 - fight temp perms, custom class drops, spectate fix -* v0.5.9 - max players, max team pleayers -* v0.5.8 - private arenas, item reward fix -* v0.5.7 - bugfixes, spawn remove command, enable/disable save -* v0.5.6 - ready handling fix, min team size -* v0.5.5 - blacklist, update check -* v0.5.4 - Capture the Pumpkin arena! -* v0.5.3 - Backend rewrite, -* v0.5.2 - Bugfixes, configurable player start values -* v0.5.1 - rewrite, temporary sign bug fix \ No newline at end of file diff --git a/doc/history/0.6.md b/doc/history/0.6.md deleted file mode 100644 index fbfdc935c..000000000 --- a/doc/history/0.6.md +++ /dev/null @@ -1,83 +0,0 @@ -== PVP-Arena v0.6 Changelog - -* v0.6.41.1 - fix the Potion Type NPE -* v0.6.41.0 - possibility to customize the Arena prefix -* v0.6.40.26 - fix NPE when not selecting a region before trying to save the selection -* v0.6.40.25 - fix inventory protection -* v0.6.40.24 - fix region protection issues -* v0.6.40.20 - fix dead players still wearing their armor -* v0.6.40.19 - set debug ingame /pa debug [value] -* v0.6.40.18 - recognize players running outside of the arena -* v0.6.40.17 - fix woolhead removal for flag arenas -* v0.6.40.16 - fix ready block hit while countdown teleporting ppl inside the arena. Bad, bad players! -* v0.6.40.15 - hackfix Potion Effects not vanishing. Bad, bad API! -* v0.6.40.14 - fix resetting of player stats -.- -* v0.6.40.13 - fix abusing the spectator state -* v0.6.40.11 - fix a random NPE; fix WoolHead enforcement -* v0.6.40.10 - fix powerup type REPAIR and a NPE in flag arenas -* v0.6.40.9 - fix another issue with the startup countdown -* v0.6.40.8 - Backend organising by NodinChan, has NO effect on the plugin atm -* v0.6.40.7 - Fix NPE and fix LeaderBoards -* v0.6.40.6 - Tries to fix mcMMO damage messing up the arena ;) -* v0.6.40 - Multiple flags for CTF -* v0.6.39 - Enchantments -* v0.6.38 - Arena chat -* v0.6.37 - Item reward random -* v0.6.36.11 - fix a bug where players were able to start alone / with just one team -* v0.6.36.8 - fix various bugs -* v0.6.36.4 - add a proper arena start message ; add a PAKillEvent -* v0.6.36.3 - fix bet placing NPE -* v0.6.36.2 - add Vault support -* v0.6.36 - fix for every arena start bug caused by leaving / quitting players -* v0.6.35.3 - taught talking to DOM arena -* v0.6.35.2 - fix the CTF issues -* v0.6.35 - fix the death issues, finally -* v0.6.29.9 - fix the fire bug, finally -* v0.6.29.8 - create custom events properly -* v0.6.29.7 - reset team flags on arena startup to be colored -* v0.6.29.6 - fixed CTF NPE -* v0.6.29.5 - added config setting protection.restore to stop block restoring -* v0.6.29.4 - added teleport ignoring INSIDE the battlefield -* v0.6.29.3 - fixed countdown join bug, for real :D -* v0.6.29.2 - fixed sign restoring bug -* v0.6.29.1 - fixed inventory hack bug -* v0.6.29 - join teams with sign. Line 2: teamname -* v0.6.28.6 - cancel 5s countdown if player joins -* v0.6.28.5 - spawn camping just for battlefield & fighting players -* v0.6.28.4 - add config: protection.punish (default false) -* v0.6.28.3 - fix 2 NPEs happening when spawn camping or using /pa leave -* v0.6.28.2 - fix a very bad bug occurring after fixing an NPE -* v0.6.28.1 - fix various NPEs -* v0.6.28 - potion effects for PowerUps -* v0.6.27 - join range possible without set region -* v0.6.26.2 - fixed NPE -* v0.6.26.1 - added proper join event calling -* v0.6.26 - add custom events for other plugins to listen to -* v0.6.25 - get stats with /pa {name} stats [stattype] -* v0.6.24 - sort arena board by click -* v0.6.23 - config "hideName": remove names over head -* v0.6.22 - punish spawn camping -* v0.6.21 - [PUMPKIN|CTF|DOM] join arenas ingame -* v0.6.20 - arena start runnable (5s, if readycount > x%), interrupted by player join -* v0.6.19 - fixed players joining from vehicles -* v0.6.18 - added entry fee "pay" message -* v0.6.17 - force joining from a special region, if one arena has set "join" region -* v0.6.16 - "explicitPermission" to enable need of "pvparena.join.[arenaname]" -* v0.6.15 - new debug system -* v0.6.14 - main config: onlyPVPinArena -> cancel all damage except arena! -* v0.6.13.2 - quitting ingame does not break anything -* v0.6.13.1 - fixed block destruction being possible -* v0.6.13 - EDIT mode /pa {name} edit -* v0.6.12 - "[player] killed" + " by [player/cause]" -* v0.6.11 - config: betWinFactor [2], betTeamWinFactor [1], betPlayerWinFactor [2] -* v0.6.10 - config: allowDrops [true] -* v0.6.9 - config: flagColors: set flag (head) colors -* v0.6.8 - config: woolFlagHead: change/set woolhead on flag grabbing -* v0.6.7 - config: autoclass: [classname] -* v0.6.6 - team chat: add player name -* v0.6.5 - [Spout] wool lock (inv change cancel) -* v0.6.4 - [Spout] color name over head -* v0.6.3 - game mode: death match, spheric regions, block repair, powerup spawn -* v0.6.2 - leaderboards RELOADED, spawn protection, flag coloring/whitening, inv drops -* v0.6.1 - sign update/check, announcements, death!, arena end timer -* v0.6.0 - huge rewrite \ No newline at end of file diff --git a/doc/history/0.7.md b/doc/history/0.7.md deleted file mode 100644 index 3a1e1ae41..000000000 --- a/doc/history/0.7.md +++ /dev/null @@ -1,90 +0,0 @@ -== PVP-Arena v0.7 Changelog - -* v0.7.25.2 - cancel woolhead removal when needed -* v0.7.25.1 - properly handle piston event protection -* v0.7.25.0 - rewrite of /pa {arenaname} info -* v0.7.24.0 - attempt to improve the statistics usage -* v0.7.23.4 - fixed the woolhead removal - again -* v0.7.23.3 - fix an issue with death events -* v0.7.23.2 - fix late joining -* v0.7.23.1 - fix freefight type issues, fix classitems messing causing NPEs -* v0.7.23.0 - /pa [name] alive - list alive players -* v0.7.22.2 - fix PotionEffects not being removed properly -* v0.7.22.1 - more intelligent and extroverted help system -* v0.7.22.0 - add readying of all teams with checkEachTeam: false -* v0.7.21.0 - fix many issues inside modules -* v0.7.20.13 - fix an NPE on non pvp death -* v0.7.20.12 - add cylindric arena region shape -* v0.7.20.11 - fix custom class not working -* v0.7.20.10 - fix the end timer not deactivating PVP for losers -* v0.7.20.8 - fix issues.... -* v0.7.20.7 - fix stuff and update for tank arena mode -* v0.7.20.6 - fix alot of permissions issues oO -* v0.7.20.5 - fix the wool head not being correctly secured -* v0.7.20.4 - fix the ready up bug -* v0.7.20.3 - fix various bugs -* v0.7.20.2 - fix various bugs -* v0.7.20.1 - fix teams/ctf/pumpkin lounge setting not working -* v0.7.20.0 - feature freeze, future updates will just add/update modules or fix bugs -* v0.7.19.5 - fix messy code about random spawns -* v0.7.19.4 - fix teams/ctf/pumpkin spawn setting not working -* v0.7.19.3 - fix region NPE -* v0.7.19.2 - fix missing messages -* v0.7.19.1 - fix multiple enchantments -* v0.7.19.0 - command handling rewrite -* v0.7.18.0 - region modules -* v0.7.17.4 - fix chest restoring -* v0.7.17.3 - make the countdown timer configurable -* v0.7.17.2 - fix arenaboards displaying the global stats for players during a match -* v0.7.17.1 - fix fluids and block burning not being cancellable/replaced properly -* v0.7.17.0 - (more) correctly calculate armor in order to detect death -* v0.7.16.1 - fix when teleporting players -* v0.7.16.0 - more colors! -* v0.7.15.0 - /pa readylist - to see people not being flagged as ready -* v0.7.14.1 - add a delay to teleporting, making the player teleporting thread safe -* v0.7.14.0 - teleport to spawns with /pa tp [spawnname] -* v0.7.13.1 - FIRST restore blocks, then restore inventories! -* v0.7.13.0 - add config setting to force warming up on /pa join | /pa spectate -* v0.7.12.1 - fix /pa [name] remove [spawnname] -* v0.7.12.0 - multiple Enchantments -* v0.7.11.3 - add a different tracker -* v0.7.11.2 - fix the player handling / inventory issue -* v0.7.10.6 - fix the Loader -* v0.7.10.5 - fix watching players not belonging to the arena -* v0.7.10.4 - fix restoring of the team nameplate -* v0.7.10.3 - fix timed (team) arenas giving no rewards -* v0.7.10.2 - fix timed arenas totally f up -* v0.7.10.1 - fix CraftBukkitUpToDate compatibility -* v0.7.10.0 - add restoring of dispensers and furnaces -* v0.7.9.22 - change game.allowDrops priority. Custom class not needed! -* v0.7.9.21 - fix module loading -* v0.7.9.20 - fix modules not containing version -* v0.7.9.19 - fix player recognition -.- -* v0.7.9.18 - fix spheric regions not being saved properly -* v0.7.9.17 - fix all arena type ready methods -* v0.7.9.16 - fix CTF/Pumpkin interact cancelling -* v0.7.9.15 - hook inv shift click to protection.inventory -* v0.7.9.14 - fix ColorTeams -* v0.7.9.13 - fix CTF/Pumpkin arena returning "Flag set:" on many occasions ^^ -* v0.7.9.12 - fix mobs messing up the game. bad, bad mobs! -* v0.7.9.11 - fix an NPE with activated quit check -* v0.7.9.10 - fix ArenaBoards not working if spectators are present -* v0.7.9.9 - fix many issues with invisible armor, players etc by disabling the team coloring function -* v0.7.9.8 - fix team chat doubling -* v0.7.9.7 - add customisable end timer, add damage cancelling -* v0.7.9.6 - fix an NPE with /pa bet [player] -* v0.7.9.5 - fix an NPE possible on arena end -* v0.7.9.4 - fix more beta bugs -* v0.7.9.2 - fix various bugs -* v0.7.9 - rewrite concerning ArenaPlayer / Players -* v0.7.8 - ArenaModule: Announcements -* v0.7.7 - ArenaModule: TempPerms -* v0.7.6 - ArenaModule: PowerUps -* v0.7.5 - ArenaModule: VaultSupport -* v0.7.4 - ArenaModule: Economy -* v0.7.3 - ArenaModule: BlockRestore -* v0.7.2 - ArenaModule: ColorTeams -* v0.7.1 - ArenaModule: ArenaBoards -* v0.7.0.3 - Kick leads to arena leave -* v0.7.0.2 - Chest restoring -* v0.7 - another huge rewrite, modules that provide Arena Types \ No newline at end of file diff --git a/doc/history/0.8.md b/doc/history/0.8.md deleted file mode 100644 index 0e8d54b26..000000000 --- a/doc/history/0.8.md +++ /dev/null @@ -1,92 +0,0 @@ -== PVP-Arena v0.8 Changelog - -* v0.8.12.3 - trimmed some unneeded methods -* v0.8.12.2 - offline updating -* v0.8.12.1 - fix several NPEs -* v0.8.12.0 - fix disconnect exploit -* v0.8.11.28 - maybe fix the chatting the correct way ^^ -* v0.8.11.27 - fix 1.3.1 spamming about PlayerChatEvent. real fix incoming -* v0.8.11.26 - fix class saving -* v0.8.11.25 - fix regions being one block too short on each side -* v0.8.11.24 - fix non-fighters inside an arena being damaged. -* v0.8.11.23 - fix the loser's inventory disappearing issue -* v0.8.11.22 - fix general protection issues (greedy protection) -* v0.8.11.21 - fix joining teams with signs -* v0.8.11.20 - fix /pa [] class -* v0.8.11.19 - fix some spawn settings not working -* v0.8.11.18 - fix battlefield/arena end/win/lose issues -* v0.8.11.17 - add ingame class preview / edit / saving / removing -* v0.8.11.16 - also restrict blockplace on block whitelist/blacklist -* v0.8.11.15 - attempt to fix losers being counted as winners, adding PALoseEvent on the way -* v0.8.11.14 - fix several issues about players logically hurting themselves (ender pearls etc) -* v0.8.11.13 - prevent teleporting INTO an arena -* v0.8.11.12 - fix arena join messages -* v0.8.11.11 - unknown -* v0.8.11.10 - fix multiple join regions need you to be in all join regions oO -* v0.8.11.9 - fix losing making you leave the match -* v0.8.11.8 - fix deaths and kills not being registered -* v0.8.11.7 - fix players being kicked from arena -* v0.8.11.6 - add proper CUSTOM announcement implementation -* v0.8.11.5 - zip NPE bug? -* v0.8.11.4 - fix spectator check -* v0.8.11.3 - fix other issues -* v0.8.11.2 - fix a player death NPE -* v0.8.11.1 - fix StartRunnable issues -* v0.8.11.0 - add PAWinEvent -* v0.8.10.14 - revert inventory handling -* v0.8.10.13 - change and fix update check -* v0.8.10.12 - allow module update deactivation -* v0.8.10.11 - properly reset inventories! -* v0.8.10.10 - reset Potion Effects on respawn -* v0.8.10.9 - add MultiInv compatibility -* v0.8.10.8 - fix NPE about resetPlayer -* v0.8.10.7 - add config setting to change default command -* v0.8.10.6 - fix custom classes inventory handling -* v0.8.10.5 - re-activate the escape check -* v0.8.10.4 - fix inventory being removed for custom classes at the end... -* v0.8.10.3 - properly ignore alpha and beta builds from update nag -* v0.8.10.2 - fix WIN and LOSE region not triggering timers -* v0.8.10.1 - fix spawn setting not working for some modules -* v0.8.10.0 - add WIN and LOSE regions -* v0.8.9.0 - finish region protection -* v0.8.8.9 - fix Projectile Exception (Ticket 338) -* v0.8.8.8 - fix the region selection spam -* v0.8.8.7 - add message coloring -* v0.8.8.6 - fix synchronisation issues -* v0.8.8.5 - fix "youescaped" bug -* v0.8.8.4 - fix NPE in statistics handling -* v0.8.8.3 - fix /pa update [type] -* v0.8.8.2 - fix /pa uninstall * -* v0.8.8.1 - block break NPE -* v0.8.8.0 - timer rewrite to fix many issues -* v0.8.7.2 - fix minor display bug -* v0.8.7.1 - fix NPE when players disconnect while being told something -* v0.8.7.0 - add /pa update, /pa install and /pa uninstall -* v0.8.6.20 - fix TimerInfo visibility -* v0.8.6.19 - support arena name guessing -* v0.8.6.18 - enhance /pa version flexibility -* v0.8.6.17 - give proper error when using unsupported region types -* v0.8.6.16 - fixed other regions not being initialized properly -* v0.8.6.15 - fixed cubic regions not being initialized properly -* v0.8.6.14 - fixed /pa reload messing up when an arena was running -* v0.8.6.13 - better information about missing game modes -* v0.8.6.12 - add proper error for old pa create command -* v0.8.6.11 - distinguish tnt block damage from player block damage -* v0.8.6.10 - remove mobs and animals on region reset -* v0.8.6.9 - fix spawn access (players taking the enemy flag at other positions) -* v0.8.4.8 - add hook parseRespawn to Modules -* v0.8.4.7 - fix woolHead support -* v0.8.4.6 - teach the countdowns to talk! (continued) -* v0.8.4.5 - fix the player not being reset properly after a fight -* v0.8.4.4 - teach the countdowns to talk! -* v0.8.4.3 - add hook to add required spawns via modules -* v0.8.4.2 - revert hook for sabotage arena, fix Player velocity on respawn -* v0.8.4.1 - add hook for sabotage arena, ArenaType.onEntityExplode -* v0.8.4.0 - read default classes from config.yml, if set -* v0.8.3.0 - add blacklist/whitelist for block breaking -* v0.8.2.3 - fix droppings inside the spectator area -* v0.8.2.2 - only track plugin if used (if arenas defined) -* v0.8.2.1 - add arena wide command whitelist -* v0.8.2.0 - rewrite in order to fix the player teleporting / ghosting issue -* v0.8.1.0 - major fix - more to come, but this is a severe bug fix -* v0.8.0.0 - major rewrite of player death handling, fixes many things \ No newline at end of file diff --git a/doc/history/0.9.md b/doc/history/0.9.md deleted file mode 100644 index 57b7068e1..000000000 --- a/doc/history/0.9.md +++ /dev/null @@ -1,203 +0,0 @@ -== PVP-Arena v0.9 Changelog - -* v0.9.9.18 - /pa [arena] region [regionname] border - YAY! -* v0.9.9.17 - don't spawn players on flags. derp :p -* v0.9.9.16 - activate region force join - hooray! -* v0.9.9.15 - enhance the battlefield quit process: add "death" instead of kick -* v0.9.9.14 - add SPAWN regions that >enforce< random spawning -* v0.9.9.13 - broadcast when a player / team is ready -* v0.9.9.12 - allow data values for blacklist and whitelist -* v0.9.9.11 - SET - stop being so damn PICKY about cases! -* v0.9.9.10 - regions are now safe when the arena is off/disabled :p -* v0.9.9.9 - add /pa togglemodule/!tm [module] !!! -* v0.9.9.8 - add running commands in ALL arenas /pa ALL [...] -* v0.9.9.7 - fix node collision: battlefieldguard=> BFGACTIVE -* v0.9.9.6 - fix spectating cause an NPE -* v0.9.9.5 - fix internal modules vanishing on reload -* v0.9.9.4 - fix CLASS help -* v0.9.9.3 - add module hooks to BattlefieldJoin start -* v0.9.9.2 - add BetterGears - COLORED DYES -* v0.9.9.1 - fix the place/break whitelist / blacklist ! -* v0.9.9.0 - fix /pa install | uninstall | update -* v0.9.8.25 - support TEAM based PlayerLives goal !! -* v0.9.8.24 - support TANK gamemode - welcome back !! -* v0.9.8.23 - activate MOBS protection, and teach Listeners some RESPECT -* v0.9.8.22 - rewrite spawning (FREE) - new config settings! -* v0.9.8.21 - split the announcing of "join the arena!" (ADVERT) and "let the fight begin" (START) -* v0.9.8.20 - make sure PA loads after SKINS dependencies -* v0.9.8.19 - re-introduce arena.getWorld() -* v0.9.8.18 - update Skins language -* v0.9.8.17 - allow setting classes to have empty inventory -* v0.9.8.16 - update importer (weapondamage), remove unnecessary WORLD node from config! -* v0.9.8.15 - fix an ConcurrentModificationException about region restoring -* v0.9.8.14 - fix #97 - Other -- Additional grammar issues - ITERVAL !!!!! -* v0.9.8.13 - add /pa [arena] start -* v0.9.8.12 - add proper functionality to /pa [arena] spectate -* v0.9.8.11 - finally implement the SOFT version of a player leave - FIX ppl spectating after death -* v0.9.8.10 - fix the ArenaRunnable implementation ("XXX has not been scheduled yet") -* v0.9.8.9 - restructure the player removal to allow proper removement by modules -* v0.9.8.8 - add #96 - Feature Request - Ability to disable armor durability -* v0.9.8.7 - properly update the config if nodes are missing -* v0.9.8.6 - add #92 - Feature Request - List number of players per team -* v0.9.8.5 - fix #85 - Other - Grammar fix for capturing a flag? -* v0.9.8.4 - support WorldEdit auto loading and saving of BATTLE regions -* v0.9.8.3 - add module hooking into class selection -* v0.9.8.2 - add config node and langage for BetterClasses -* v0.9.8.1 - re-add module arena start handling -* v0.9.8.0 - rewrite the arena start. use with caution! -* v0.9.7.14 - fix part of #101 - free team can be colored other than WHITE -* v0.9.7.13 - fix #103 - Bug - FFA games not ending! -* v0.9.7.12 - fix #98 - Bug - Fire continuation after leaving/death -* v0.9.7.11 - remove debug -* v0.9.7.10 - quick fix for players not being properly set to fighting state -* v0.9.7.9 - more output and less team resetting -* v0.9.7.8 - properly update the gamemode when it is being set -* v0.9.7.7 - never code when your brain is infected! -* v0.9.7.6 - fix fixes causing broken commands -* v0.9.7.5 - fix #84 - Bug - Disconnecting with flag does not reset flag -* v0.9.7.4 - add missing classes -* v0.9.7.3 - fix #90 - Bug - Class signs with player names not working properly. -* v0.9.7.2 - fix #89 - Bug - Unable to join arena on a specific team -* v0.9.7.1 - fix Sabotage spawning a second destructive TNT -* v0.9.7.0 - welcome back, Sabotage! -* v0.9.6.30 - remove calling of the unused ArenaGoal.commitJoin method -* v0.9.6.29 - add soft depends to fix loading issues -* v0.9.6.28 - place every flag block on the player's head for now -* v0.9.6.27 - prevent removing your head gear when carrying a flag -* v0.9.6.26 - attempt to fix disconnecting players not resetting carried flags -* v0.9.6.25 - reset WoolHeads even if inventories should not be reset -* v0.9.6.24 - fix regions activating all protections on server start -* v0.9.6.23 - fix players being able to re-join a match -* v0.9.6.20 - fix regions being messed on restarting -* v0.9.6.19 - more debug -* v0.9.6.18 - Items -* v0.9.6.17 - aiming to fix the player drops being dropped at the respawn position instead of the death position -* v0.9.6.16 - fix non-pvp deaths messing up the Flags goal -* v0.9.6.15 - fix .10 -* v0.9.6.14 - fix the FFA game mode team count logic -* v0.9.6.13 - globally activate head gear removal prevention -* v0.9.6.12 - fix saved players not being physically reset -* v0.9.6.11 - quick debug NPE fix -* v0.9.6.10 - re-enable Debug override -* v0.9.6.9 - fix inventory loss because of disconnect and server crash, finally -* v0.9.6.8 - there are more signs! -* v0.9.6.7 - allow readying up and using signs in the lounge -* v0.9.6.6 - add a bit more of debug -* v0.9.6.5 - fix an NPE in the InventoryRefillRunnable -* v0.9.6.4 - fix issue #81 -* v0.9.6.3 - fix the last commit which in fact broke more than it should fix -* v0.9.6.2 - fix refillInventory -* v0.9.6.1 - fix the Location->Block calculation -* v0.9.6.0 - add /pa import [arenaname] - v0.8 import! -* v0.9.5.21 - fix TeamDeathMatch kill announcement #2 -* v0.9.5.20 - fix TeamDeathMatch kill announcement -* v0.9.5.19 - add default spawn "exit" to possible spawns -* v0.9.5.18 - reactivate /pa reload -* v0.9.5.17 - enhance and finish the help system -* v0.9.5.16 - fix issue #72.1 | block offset in negative X/Z ranges - fix issue #72.1 | block offset in negative X/Z ranges -* v0.9.5.15 - fix issue #71 -* v0.9.5.14 - hotfix -* v0.9.5.13 - finish .11 -* v0.9.5.12 - fix players being said to be in an arena when they aren't -* v0.9.5.11 - fix players being able to mess up the lounge / spectator / battlefield before starting -* v0.9.5.10 - attempt to fix the player status error with BattlefieldJoin (no lounges) -* v0.9.5.9 - last player(s) teleport bug -* v0.9.5.8 - fix wrong player death handling at the end of the arena -* v0.9.5.7 - enhancing help messages to reflect shorthand commands -* v0.9.5.6 - update all modules. This is information and order :p -* v0.9.5.5 - integrate NodinChan's loader, the update is just. f. -* v0.9.5.4 - fix StandardLounge + FreeForAll -* v0.9.5.3 - fix Runnables being cancelled when not being running -* v0.9.5.2 - fix tracker / stats deactivation derpyness -* v0.9.5.1 - fix player reset (first restore, then teleport) -* v0.9.5.0 - add /pa round -* v0.9.4.1 - add /pa stats -* v0.9.4.0 - add /pa help -* v0.9.3.52 - add language and config for the duel module -* v0.9.3.51 - properly tell a player that an arena is disabled -* v0.9.3.50 - don't ask... -* v0.9.3.48 - fix a blockrestore bug about regions -* v0.9.3.47 - fix joining not cancelling the start countdown, finally -* v0.9.3.46 - reanimate StandardSpectator -* v0.9.3.45 - fix two language issues -* v0.9.3.44 - add some little debug to StartRunnable -* v0.9.3.43 - revert InventoryRefillRunnable to be a simple Runnable -* v0.9.3.42 - correctly display /pa list - depending on game mode, fix player damage on teleport -* v0.9.3.41 - use BukkitRunnables instead of Runnables -* v0.9.3.40 - fix respawning players not being restored under certain circumstances -* v0.9.3.39 - fix the Timers -* v0.9.3.38 - fix #29 - Inventory not being restored on respawn. Hilarious collateral damage! -* v0.9.3.37 - fix the Flag goal not activating spawn setting -* v0.9.3.36 - fix a bug about timers ^^ -* v0.9.3.35 - add a tiny bit more debug -* v0.9.3.34 - aim to fix #57 and #46 -* v0.9.3.33 - fix players DCing / being kicked getting double refund (and other things) -* v0.9.3.32 - fix the next NPE ^^ -* v0.9.3.31 - quick fix for a sleeping NPE -* v0.9.3.30 - possibly resolve #46 - Bug -- Stuck in the floor? -* v0.9.3.29 - try to fix ticket #55 - Bug -- Min/Max player limit not working -* v0.9.3.28 - hopefully fix ticket #58 - NPE while joining when the arena is full -* v0.9.3.27 - fix ticket #59 - Bug -- Champion team is announced numerous times -* v0.9.3.26 - startup error fix -* v0.9.3.25 - fix bug #56 -* v0.9.3.24 - yet another attempt to fix the spawn bug -* v0.9.3.23 - fix tickets #48, #52 -* v0.9.3.22 - a new attempt to fix the spawn bug -* v0.9.3.21 - fix several small things -* v0.9.3.20 - aims to fix the spawn issues -* v0.9.3.19 - fix some more color issues -* v0.9.3.18 - fix bug #41 -* v0.9.3.17 - fix players not always getting told they are ready -* v0.9.3.16 - fix players being able to drop stuff in the lounge ^^ -* v0.9.3.15 - separate edit mode and arena lock state -* v0.9.3.14 - fix the start countdown -* v0.9.3.13 - fix a NPE about player chatting, language tweaks -* v0.9.3.12 - fix playerLeave -* v0.9.3.11 - remove debug StackTrace for ticket #32 -* v0.9.3.10 - fix the SpawnManager choking on block locations -* v0.9.3.9 - fix IllegalStateException for configParse -* v0.9.3.8 - aim to fix ticket #31 -* v0.9.3.7 - fix tickets #25, #32 -* v0.9.3.6 - fix tickets #33, #34, add debug StackTrace for Ticket #32 -* v0.9.3.5 - language fixes -* v0.9.3.4 - and another one. aiming to fix arenas not announcing players leaving the arena -* v0.9.3.3 - for mibby -* v0.9.3.2 - fix /pa reload resetting configs - finally :/ -* v0.9.3.1 - fix an NPE (BlockChange), remove EDIT calling STOP, fix the command whitelist -* v0.9.3.0 - PACheckResult -> rewrite -> PACheck | new check, commit, parse system -* v0.9.2.12 - fix the even check, ticket #28 -* v0.9.2.11 - fix people not being able to ready themselves up in special cases -* v0.9.2.10 - remove debug, fix #19 and #20 -* v0.9.2.9 - fix the startup, affecting VAULT (entryfee), announcements (join message) and more -* v0.9.2.8 - fix several little issues -* v0.9.2.7 - resolve #3, #4, #5, #7, #8, #9, #18 -* v0.9.2.6 - final fix of #2,#11,#15,#16,#17 -* v0.9.2.5 - fix spam of "No arenas found!" -* v0.9.2.4 - fix Issues #2,#11,#15,#16,#17 -* v0.9.2.3 - fix Issue #12,#13 -* v0.9.2.2 - fix a NPE -* v0.9.2.1 - fix a display bug about the Protection command help -* v0.9.2.0 - inventory issue fixed! -* v0.9.1.X - beta test release -* v0.9.0.0 - major organisation rewrite -** <<<<< changes since v0.8.12.5 >>>>> -** use NC-BukkitLib instead of NC-LoaderLib -** the region modules are not "Regions", they are "RegionShapes" ;) -** attach the chatting determination to the player, not to an arena -** remove ArenaType, add ArenaGoal (one type => multiple goals) -** remove lives from the main plugin, attach this logic to the arena goals -** remove positions from the arena, attach to player -** enormous rewrite considering renaming, restructuring, improvements during 1.0 development -** intense command rewrite -** <<<<< updated commits of v0.8.12.5 >>>>> -** allow other-world-spawns -** flatfile inventories for restoring -** [PVP Arena] [arenaname] -> format properly -** arena welcome message per arena -** check what to repair on interact / hit (dont reset every freaking block :p ) -** intelligent and case insensitive arena guessing -** ready up with /pa ready -** splash damage/healing affects teams correctly -** teleport -> 2L -> inv save -** inv restore -> 2L -> teleport -** rewards: "rewards-min-players" \ No newline at end of file diff --git a/doc/history/1.0.md b/doc/history/1.0.md deleted file mode 100644 index c5e1be38e..000000000 --- a/doc/history/1.0.md +++ /dev/null @@ -1,284 +0,0 @@ -== PVP-Arena v1.0 Changelog - -=== Changelog - -* v1.0.9.292 - maybe support CrackShot and other plugins utilizing "only" projectiles -* v1.0.9.291 - add more goal specific events -* v1.0.9.290 - enhance duel module messaging -* v1.0.9.289 - add regiontypes! BL_INV / WL_INV => blacklist / whitelist inventory -* v1.0.9.288 - make /pa teams properly read the color variables -* v1.0.9.287 - compare changes or fix greedy replacements - derp -* v1.0.9.286 - if we have to care about case, we should do it the right way and constistently -* v1.0.9.285 - fix the install.yml error and add the new curse API updater -* v1.0.9.284 - don't remove a player from the has played list if we need to track them -* v1.0.9.283 - add a Vault setting to only allow betting during the first X seconds -* v1.0.9.281 - add language for chestfiller reset -* v1.0.9.279 - fix BattleFieldJoin putting ppl nowhere before the match started -* v1.0.9.278 - allow to enforce late joining only to initial players "onlyifhasplayed" -* v1.0.9.277 - remove import command. goodbye, v0.8 -* v1.0.9.276 - properly iterate through random spawns -* v1.0.9.275 - actually allow multiple block related goals -.- -* v1.0.9.274 - allow Potions to contain more than one effect - derp -* v1.0.9.271 - make PAJoinEvent and PAStartEvent cancellable -* v1.0.9.270 - add a DBO guideline compliant updater -* v1.0.8.269 - yippie, fixed? -* v1.0.8.268 - revert the replacement of the color code char. gg slipcor -* v1.0.8.267 - hackfix commands to work for players being in the LateLounge queue -* v1.0.8.266 - allow "quickloot" per arena, so players just click a chest to loot -* v1.0.8.265 - silently support BattlefieldManager [/spoiler] -* v1.0.8.264 - minor language format fix -* v1.0.8.263 - don't reset skulls because they receive no damage :P -* v1.0.8.262 - do not drop experience if there is none to drop -* v1.0.8.261 - seriously, bukkit - Y U F up? -* v1.0.8.260 - reset EXP on death (if dropping) -* v1.0.8.259 - drop orbs, because bukkit doesn't want to -* v1.0.8.258 - create pseudo teams before trying to teleport members to it -* v1.0.8.257 - properly implement Bukkit 1.6 API -* v1.0.8.256 - update to MC 1.6 - Bukkit 1.6.2-R0.1 -* v1.0.8.255 - never gonna give you up, #254 -* v1.0.8.254 - fix EXP not properly dropping on some occasions -* v1.0.8.253 - #252 - next try -* v1.0.8.252 - allow late join for PlayerKillReward -* v1.0.8.251 - fix late joining spawns and /pa [arena] teams -* v1.0.8.250 - support class spawns and fix issue #249, revealing that spawning was still broken -* v1.0.7.249 - remove dead code and properly add spawns & blocks when defining them -* v1.0.7.248 - attemt to fix issues #618 and #621 -* v1.0.7.247 - fix spawning, please - (begging works, fyi) -* v1.0.7.246 - add more debug, because everyone loves debugging :) -* v1.0.7.245 - properly check the TNT flag, not the FIRE flag -* v1.0.7.244 - [BREAKING?] - only for dev tests! - SpawnManager rewrite -* v1.0.7.243 - fix ValeraSTK's spawning - break others? no clue -* v1.0.7.242 - spawn debug enhancement (maybe fix) -* v1.0.7.241 - finally fix initial spawning (maybe) -* v1.0.7.240 - enhance the debug for Wahrheit -* v1.0.7.239 - Wahrheit will love this fix! -* v1.0.7.238 - fix an NPE in /pa stats -* v1.0.7.237 - apply default chat parameter -* v1.0.7.236 - allow Wahrheit to use multiple team spawns with PlayerLives -* v1.0.7.235 - allow to require a minimum game length to reward -* v1.0.7.234 - allow to find out how long an arena is running -* v1.0.7.233 - maybe fix the issue by supporting spawn maps? -* v1.0.7.232 - clarify debug for #578 -* v1.0.7.231 - stop punishing players that are left alone. Reward them! -* v1.0.7.230 - re-add announcement config language node -* v1.0.7.229 - try to fix tank spawning -* v1.0.7.228 - add infect death debug - investigating #578 -* v1.0.7.227 - add language node debug - for all the debugs I don't understand :P -* v1.0.7.226 - fix a minor language issue -* v1.0.7.225 - add "customReturnsGear" - allows to play with items but not bringing/taking things -* v1.0.7.224 - prevent death as promised -* v1.0.7.223 - support third party health boosts that vanish after joining -* v1.0.7.222 - maybe fix an issue about autoClass not working on some occasions? -* v1.0.7.221 - properly set the claimed determination map -* v1.0.7.220 - add announce offset and points limitation for DOM -* v1.0.7.219 - properly use wool byte instead of dye byte -* v1.0.7.218 - add autovote autostart - so PA manages ALL THE SERVERS -* v1.0.7.217 - stop breaking servers that didnt want stats in the first place -* v1.0.7.216 - reset stats for admins that /pa reload -* v1.0.7.215 - do not set to an empty path - sry... -* v1.0.7.214 - hell yeah. How about we save the player files? Derp! - thx, Uhehesh -* v1.0.7.213 - stop creating debug files if we don't need them. please... -* v1.0.7.212 - fix startup NPE due to Statistics -* v1.0.7.211 - properly support "none" as an item list -* v1.0.7.210 - for ravand and others: CONFIG: autovote only spams to JOIN regions -* v1.0.6.209 - properly apply #208 and always load the yml! -* v1.0.6.208 - properly load statistics from the player.yml - since when is this broken!? -* v1.0.6.207 - try to fix spawn calculation for the infect goal -* v1.0.6.206 - properly escape & before blindly handing it to the colorize method -* v1.0.6.205 - first check if the arena is running, then check for other errors -* v1.0.6.204 - be prepared for weird multi world setups (a bit better) -* v1.0.6.203 - add proper player name when debugging a player -* v1.0.6.202 - try to fix join edit mode determination - and fix 80% of the lag caused by joining -* v1.0.6.201 - allow to enforce the start countdown -* v1.0.6.200 - allow to restrict autovote to one world, or multiple worlds - allow to restrict autovote to one world, or multiple worlds -* v1.0.6.199 - reduce kill count of deathmatch goals for the DEATH region flag -* v1.0.6.198 - allow taking specific things out of the match -* v1.0.6.197 - add some language nodes for proper error/notice display -* v1.0.6.196 - enhance/clarify debug -* v1.0.6.195 - add the possibility to interact in lounge mode -* v1.0.6.194 - awesome feature: join a game before it has begun -* v1.0.6.193 - everyone loves derpy server implementations -* v1.0.6.192 - add config setting for respawnrelay spawn choosing -* v1.0.6.191 - allow to respawn to a specific spawn -* v1.0.6.190 - update Metrics to revision 7 -* v1.0.6.189 - adjust reward handling for FREE arenas to reflect the recent rewrites -* v1.0.6.188 - add language per arena; add items.excludeFromDrops -* v1.0.5.187 - prepare for a language rewrite, fix all warnings! -* v1.0.5.186 - allow to set config materials by "hand" and items by "inventory" -* v1.0.4.185 - enhance arena list command display -* v1.0.4.184 - add PAPlayerClassChangeEvent -* v1.0.4.183 - try fixing BlockDestroy ending -* v1.0.4.182 - fix NPE -* v1.0.4.181 - craftbukkit is a lie! -* v1.0.4.180 - add a warning if a player has a state when joining (no autoClass then?) -* v1.0.4.179 - properly call PAExitEvent and PALeaveEvent on timed end -* v1.0.4.178 - fix little NPE -* v1.0.4.177 - add a max radius to PlayerFinder -* v1.0.4.176 - try to fix PlayerKillReward -* v1.0.4.175 - properly remove spectators -* v1.0.4.174 - fix #473, #474, #478, #493, #498, #505 -* v1.0.4.173 - allow to debug to server.log, oldschool, if files are not working -* v1.0.4.172 - allow to disallow arena gameplay if player has a scoreboard -* v1.0.3.171 - revert an attempt to fix rewards (leading to double rewards and messed up players) -* v1.0.3.170 - finally allow of force joining players to a team -* v1.0.3.169 - properly start timers. this time for real. -* v1.0.3.168 - little region tick rewrite -* v1.0.3.167 - fix #486 -* v1.0.3.166 - allow disallowing of spectator talk -* v1.0.3.165 - verify that rewards were not already given -* v1.0.3.164 - various fixes -* v1.0.3.163 - properly put BlockDestroy loser to the lose location -* v1.0.3.162 - fix Valera's server. btw: v2.0 is a LIE! -* v1.0.3.161 - update player's inventories. just because we can -* v1.0.3.160 - revert #155; fixed properly in #159 -* v1.0.3.159 - spectators and players in lounge do NOT have lives! -* v1.0.3.158 - revert #156; fix readyup countdown messups -* v1.0.3.157 - only care about arena players teleporting OUT, not FROM OUTSIDE -* v1.0.3.156 - properly initiate spectators -* v1.0.3.155 - properly initiate late joining players -* v1.0.3.154 - hackfix lore - we need v2.0 ! -* v1.0.2.153 - check region ticks on everyone, not just fighters -* v1.0.2.152 - fix custom potions and colored description/lore -* v1.0.2.151 - catch a NPE about deaths -* v1.0.2.150 - properly read item descriptions -* v1.0.2.149 - never stop WATCH region timers. period. -* v1.0.2.148 - properly give rewards when time determines the winners -* v1.0.2.147 - remove arrows from players; this is said to cause crashes -* v1.0.2.146 - properly update plugin files that have been renamed -* v1.0.2.145 - add some more debug to 3 (arena) -* v1.0.2.144 - fix an announcement not happening in special cases -* v1.0.2.143 - add all the helmets! And check before replacing the helmet ;) -* v1.0.2.142 - force ready up people joining late on an arena that counts down to start -* v1.0.2.141 - fix NPE -* v1.0.2.140 - genius developer! Check if too far away before joining. -* v1.0.2.139 - check for worlds before comparing locations -* v1.0.2.138 - fix /pa shutup with arguments! -* v1.0.2.137 - don't spam the winning/losing message for every remaining infect player -* v1.0.2.136 - properly allow players to fly if they ... did Oo -* v1.0.2.135 - fix infected player display, attempt tp properly end the infected mode -* v1.0.2.134 - Only force arena configuration loading if configs were messed up -* v1.0.2.133 - Reload root config and all arena configs, even lost ones! -* v1.0.1.132 - Fix displayname loading -* v1.0.1.131 - STOP removing paintings on arena end. You idiot plugin! -* v1.0.1.130 - add legacy types "infect" and "liberation" -* v1.0.1.129 - add a way of not using plugins in "Skins" module -* v1.0.1.128 - properly set un-infected players' lives -* v1.0.1.127 - properly round decimal calculation -* v1.0.1.126 - support decimals in life display (for pillars) -* v1.0.1.125 - support autoClass definitions per team -* v1.0.1.124 - properly calculate losing players -* v1.0.1.123 - stop giving rewards to matches where more than half of the players win -* v1.0.1.122 - attempt to fix an NPE about colored items -* v1.0.1.121 - attempt to fix TNT ignite determination -* v1.0.1.120 - update blockrestore config to allow block restore disabling -* v1.0.1.119 - don't clear the killrewards map after one match. bad plugin! -* v1.0.1.118 - start join tasks when resetting an arena -* v1.0.1.117 - fix leaf decay determination -* v1.0.1.116 - fix block listener logic -* v1.0.1.115 - fix v#113 to support woolheads -* v1.0.1.114 - prevent exception when spawns are on different worlds -* v1.0.1.113 - properly clear inventory when changing via arenaclass command -* v1.0.1.112 - alter v110 fix to only apply for Snowballs. Fixes #375 -* v1.0.1.111 - properly start JOIN tick before arena start. Fixes #370 -* v1.0.1.110 - allow projectiles to knock back -* v1.0.1.109 - attempt to fix v108 and v102 -* v1.0.1.108 - more precise debugging -* v1.0.1.107 - properly start an arena with BattlefieldJoin and no regions -* v1.0.1.106 - more secret fixes -* v1.0.1.105 - fix getLives method of ArenaGoals -* v1.0.1.104 - more hacking for automation -* v1.0.1.103 - properly deny players joining an arena because of explicit perms missing -* v1.0.1.102 - properly save, fix and revert fly mode -* v1.0.1.101 - make y offset configurable and add nodamage timer on leave -* v1.0.1.100 - add /pa [arena] playerjoin [playername] {team} - join enforcing -* v1.0.1.99 - add API access to player's teams and team names -* v1.0.1.98 - properly print error message when arena is full; #343 -* v1.0.1.97 - properly implement the proper implementation of adding players to the life pool -* v1.0.1.96 - add the "CustomSpawn" module to define custom named spawns -* v1.0.1.95 - attempt to fix statistics madness -* v1.0.1.94 - Support CUSTOM POTIONS - fixes ticket #330 -* v1.0.1.93 - EventActions now is able to activate redstone! -* v1.0.1.92 - properly implement players adding to the life pool -* v1.0.1.91 - fix AIOOB error due to /pa install -* v1.0.1.90 - optimization and TagAPI fix for autovote -* v1.0.1.89 - enhance information about config messups -* v1.0.1.88 - allow giving/taking food for pvp killing -* v1.0.1.87 - add /pa [arena] shutup - disables arena announcements -* v1.0.1.86 - repair tools when breaking blocks -* v1.0.1.85 - pro tip: when altering the Config, save it! -* v1.0.1.84 - properly parse /pa round arguments -* v1.0.1.83 - fix /pa round error message -* v1.0.1.82 - allow modules to hook into tnt explosions in unprotected regions -* v1.0.1.81 - automatically ready ppl that join and select a class when an arena is starting -* v1.0.1.80 - fix BattlefieldJoin (direct joining) -* v1.0.1.79 - fix Infect goal. Strange noone witnessed this :p -* v1.0.1.78 - revert v0.10.0.3 (zOMG), fix re-join arenas messing up -* v1.0.1.77 - default to teamkill = true -> fixes 99% of all issues :p -* v1.0.1.76 - stop respawning players that have lost a TDM match! -* v1.0.1.75 - don't reset the (ready) countdown if player count is ok -* v1.0.1.74 - add Citizens support (don't remove NPCs) -* v1.0.1.73 - fix #295 - display proper help when trying to set spawn wrongly -* v1.0.1.72 - add SpecialJoin setting for player count display -* v1.0.1.71 - add [team]foodfurnace to only allow the team to use THAT furnace -* v1.0.1.70 - fix tank winning message -* v1.0.1.69 - fix /pa class load [classname] - remember: /pa class done ! -* v1.0.1.68 - and, yeah fixed /pa stats ! -* v1.0.1.67 - half-assed fix for arenaboards, so that they at least display SOMETHING -* v1.0.1.66 - fix the TNTBREAK flag, this (finally) prevents block damage -* v1.0.1.65 - support "My Worlds" worlds -* v1.0.1.64 - fix splash potions for free for all arenas -* v1.0.1.63 - repair bows if wanted -* v1.0.1.62 - finish JavaDocs for ArenaGoal and ArenaModule -* v1.0.1.61 - finish /pa info output -* v1.0.1.60 - add Walls MATERIAL and RespawnRelay SECONDS config setting -* v1.0.1.59 - enhance /pa info output -* v1.0.1.58 - update LateLounge to display queue position -* v1.0.1.57 - oups, default to NOT "claimall" for Pillars -* v1.0.1.56 - Add [m]PlayerFinder, [m]Walls, enhance Pillars -* v1.0.1.55 - Add GOAL: Food! -* v1.0.1.54 - save regions on region update. This should prevent WorldEdit messups when resizing. -* v1.0.1.53 - fix StringParser, bug about LORE affected player dumps and classes -* v1.0.1.52 - fix #271 - properly handle mis-set wand settings instead of spamming -* v1.0.1.51 - fix and improve arena creation, add proper message if no goal active -* v1.0.1.50 - allow colored prefixes, fix BlockDestroy destruction detection -* v1.0.1.49 - fix what NodinChan promised: You dun goofed! -* v1.0.1.48 - improve handling of admins sticking files into wrong folders -* v1.0.1.47 - fix #2 and #4 of Ticket #262 -* v1.0.1.46 - try fixing Ticket #209, correctly remove player from arena -* v1.0.1.45 - add LIBERATION! [ WIP! ] -* v1.0.1.44 - add INFECT! -* v1.0.1.43 - add class spawns! -* v1.0.1.42 - properly add a draw for team games -* v1.0.1.41 - revert former "fixes" + stop resetting configs! -* v1.0.1.40 - finally fix the timed end bug! -* v1.0.1.39 - attempt #3 to fix the timed end -* v1.0.1.38 - attempt #2 to fix the timed end -* v1.0.1.37 - properly reset ArenaPlayers on timed end -* v1.0.1.36 - properly reset ArenaPlayers that still have a team -* v1.0.1.35 - fix some little derping inside the goal winning management -* v1.0.1.34 - Turret module settings and spawn management! -* v1.0.1.33 - fix #251 - rather than triggering the end, check for remaining teams -* v1.0.1.32 - fix #209 - only replace BlockDestroy Block if more lives than blocks! -* v1.0.1.31 - Pillars config setting fix -* v1.0.0.30 - more pillar configuration! -* v1.0.0.29 - PILLAR goal! -* v1.0.0.28 - fix more issues with CB 1.7 and respawning -* v1.0.0.27 - override .equals() for PALocation and PABlockLocation -* v1.0.0.26 - fix an NPE due to disconnecting when the arena checks if it is ready -* v1.0.0.25 - fix WarmupJoin - anyone remember stupid messups? Now we know why. -* v1.0.0.24 - fix the Map.clone() issues in all goals -* v1.0.0.23 - what you say! -* v1.0.0.22 - rewrite part one: fix lives. affects ALL GOALS! -* v1.0.0.21 - fix a little NPE in BlockDestroy goal. REWRITE incoming! -* v1.0.0.20 - new attempt to fix the .clone() issue -* v1.0.0.19 - revert #18 - first sleep then code. night! -* v1.0.0.18 - .clone() Lesson 1: unlink field references -* v1.0.0.17 - wait. what? if this fixes it, Im gonna... -* v1.0.0.16 - add to /pa debug 102 -* v1.0.0.15 - add to /pa debug 9 -* v1.0.0.14 - support multiple destroyable blocks! -* v1.0.0.13 - fix #243 - trying to add a team -* v1.0.0.12 - don't send messages if empty -* v1.0.0.11 - fix an NPE when calculating the winner -* v1.0.0.10 - attempt to fix Ticket #193,#198,#209 -* v1.0.0.1 - update versions and readme \ No newline at end of file diff --git a/doc/history/1.1.md b/doc/history/1.1.md deleted file mode 100644 index 599f3824e..000000000 --- a/doc/history/1.1.md +++ /dev/null @@ -1,131 +0,0 @@ -== PVP-Arena v1.1 Changelog - -=== Changelog - -* v1.1.2.420 - add config settings for DBO ticket 815 -* v1.1.2.419 - don't trigger a score trigger for destroying your own block -* v1.1.2.418 - remove unneeded event, there is a static hook present! -* v1.1.2.417 - properly implement the event -* v1.1.2.416 - add "proper" (hackfix) API to use Announcements in other modules -* v1.1.2.415 - update classes for 1.7 -> ProjectileSource -* v1.1.2.414 - update to bukkit 1.7 -* v1.1.2.413 - fixed: add goal "PlayerDeathConfirm" - FUN FUN FUN !!! -* v1.1.2.412 - jenkins no likey switch? -* v1.1.2.411 - add goal "PlayerDeathConfirm" - FUN FUN FUN !!! -* v1.1.1.410 - take worlds into account when comparing region overlap -* v1.1.1.409 - expose shortcut definitions and values -* v1.1.1.408 - consoleoffduty: allow the console to use shortcuts by default -* v1.1.1.407 - actually allow usage of /pa duty -* v1.1.1.406 - revert 403 and 405 - sorry, moo :P -* v1.1.1.405 - fix 403 - maybe -* v1.1.1.404 - shortcut determination debug enhancement -* v1.1.1.403 - try to queue teleports at the end, for less invisibility?? -* v1.1.1.402 - adds /pa duty; adding github issue #41 -* v1.1.0.401 - address github issue #44 -* v1.1.0.400 - address github issue #42 - hooray for single arena shortcuts! -* v1.1.0.399 - address github issue #46 -* v1.1.0.398 - change inv clearing: NONE / SURVIVAL / CREATIVE / ALL -* v1.1.0.397 - fix issue #808 - team kills score in TDM -* v1.1.0.396 - properly / sanely initiate shortcut definition defaults -* v1.1.0.395 - make classes.yml copy-able - needs reordering if you already set global classes. sorry! -* v1.1.0.394 - add a "maxhealth" setting to alter starting health, and allow setting health to -1 for FULL health -* v1.1.0.393 - allow admins to create multiple battle regions and only need players to be in one of those -* v1.1.0.392 - allow for case insensitive ALL / FULL debug -* v1.1.0.391 - fix Liberation LOST determination -* v1.1.0.390 - add "items.keepOnRespawn" to ... duh... keep items on respawn -* v1.1.0.389 - add "clearCreative" setting to clear creative players before joining -* v1.1.0.388 - properly unkill PlayerDeathMatch losers -* v1.1.0.387 - properly mark users as such -* v1.1.0.386 - tweak liberation debug output -* v1.1.0.385 - properly return that there are not enough players -* v1.1.0.384 - finalize the finalization -* v1.1.0.383 - finalize the arena shortcut system -* v1.1.0.382 - don't remove liberation and TDM players on the final kill -* v1.1.0.381 - have playerdeathmatch and playerkillrewards reflect default arena ending behaviour -* v1.1.0.380 - double check each goal if the arena is counting down to end -* v1.1.0.379 - attempty to activate loggers per arena ... maybe? -* v1.1.0.378 - properly display warning on module enabling -* v1.1.0.377 - support tank late joining, addresses github issue #40 -* v1.1.0.376 - fix class saving and load messup - sorry ! -* v1.1.0.375 - sort all the things! -* v1.1.0.374 - ... -* v1.1.0.373 - don't ask -* v1.1.0.372 - fix spectators not being completely reset -* v1.1.0.371 - allow specification of armor slot (0!BONE -> bone hat) -* v1.1.0.370 - totally not break anything by fixing githubg issue #37 -* v1.1.0.369 - address github issue #39 - rotation -* v1.1.0.368 - together with Announcements v367, fix github issue #38 -* v1.1.0.367 - plugin for sale. I pay you 100 bucks! -* v1.1.0.366 - never code when not drunk! -* v1.1.0.365 - clarify missing goal/arena file message -* v1.1.0.364 - run the "score" goal when players destroy blockdestroy blocks -* v1.1.0.363 - address github issue #36 - arenas are saved lowercase! -* v1.1.0.362 - add global class definitions, classes.yml -* v1.1.0.361 - allow for case insensitive lazy usage of shortcuts -* v1.1.0.360 - add /pa [arena] template save|load [file] -* v1.1.0.359 - finish /pa reload, reloading the main config and all arenas+subs -* v1.1.0.358 - correctly place shortcuts instead of arena names, when enforcing -* v1.1.0.357 - add pvparena.override - to specifically allow/deny special privileges -* v1.1.0.356 - add new main config settings to allow for arena management -* v1.1.0.355 - fix playerlives goal lives calculation for team arenas -* v1.1.0.354 - support hoppers and droppers and stuff for FOOD goal! -* v1.1.0.353 - if this breaks all the things, blame moo ! -* v1.1.0.352 - attempt to add readme files to the jar -* v1.1.0.351 - really fix the NPE mentioned in #351 -* v1.1.0.350 - fix strange refill runnable NPE -* v1.1.0.349 - don't require a lounge for infected people! -* v1.1.0.348 - force reset an arena if the start event has been cancelled -* v1.1.0.347 - properly allow autovote to access running arenas -* v1.1.0.346 - sanely handle non global non arena notification runnables -* v1.1.0.345 - add an evil invisibility fix attempt -* v1.1.0.344 - finally finish! fix arrows staying stuck on players! -* v1.1.0.343 - still onyl for moo !!! -* v1.1.0.342 - only for moo !!! arrow debugging! -* v1.1.0.341 - suprise, #340 now works -* v1.1.0.340 - fix invisibility - configurably -* v1.1.0.339 - stop removing region runnables if they are needed -* v1.1.0.338 - support max health changing ingame by double checking max health -* v1.1.0.337 - allow to select classes and ready up with right click -* v1.1.0.336 - actually apply proper duration and level for flag carrier potion effefct -* v1.1.0.335 - allow hunger disabling (player.hunger) -* v1.1.0.334 - stop starvation in the lounge -* v1.1.0.333 - attempt to properly remove liberation losers -* v1.1.0.332 - attempt to tackle github issue #16 and github issue #19 -* v1.1.0.331 - implement #330 in a more sane way -* v1.1.0.330 - allow mods to notify admins that forgot to set their regions to BATTLE -* v1.1.0.329 - check if anyone IS liberated before stating and giving points! fixes github issue #32 -* v1.1.0.328 - fix liberation liberation formatting -* v1.1.0.327 - address github issue #22 - properly parse dead player's chat and refill inventory -* v1.1.0.326 - address github issue #22 - read the player's team name rather than trying to teleport to nulljail -* v1.1.0.325 - suppress an issue about non arena players damaging arena players or vice versa - github issue #27 -* v1.1.0.324 - stop using multiple end countdowns at at time, addresses github issue #23 -* v1.1.0.323 - address github issue #19 - refresh arena debuggers -* v1.1.0.322 - allow players to re-ready -* v1.1.0.321 - omnom on force start github issue #16, maybe even github issue #14 -* v1.1.0.320 - stop counting suicides as deathmatch points - addresses github issue #29 -* v1.1.0.319 - attempt to maintain WATCH region maintainance -* v1.1.0.318 - properly check before blocking commands -* v1.1.0.317 - undo #316; try again later -* v1.1.0.316 - little gamemode deprecation fix -* v1.1.0.315 - automatically assign joining to one arena if only one is running -* v1.1.0.314 - in 3+ team games, properly determine if there is a draw -* v1.1.0.313 - bettergears config addition: only replace armor if leather -* v1.1.0.312 - prevent a NPE apparently happening on perm removal -* v1.1.0.311 - offer bettergears armor customisation; revert #310 -* v1.1.0.310 - offer betterclasses armor customisation -* v1.1.0.309 - language fixes, partially fixes github issue #23 -* v1.1.0.308 - addresses github issue #21 - hackfix -* v1.1.0.307 - add specific vault reward settings -* v1.1.0.306 - fix GitHub issue #18 -* v1.1.0.305 - restructure logging creating - now per command - maybe -* v1.1.0.304 - allow re-readying to initiate an arena start -* v1.1.0.303 - fix the Time Goal ending and NPE derp -* v1.1.0.302 - end games where people leave a Time Goal only match -* v1.1.0.301 - FORCE START OVERRIDE! let's pray this does not break all the thingsthat -* v1.1.0.300 - if this does not disable flying, you are hacking, mibby -* v1.1.0.298 - attempt to enforce flymode removal -* v1.1.0.297 - merge code optimisations by Iaccidentally -* v1.1.0.296 - nope, backwards compatibility is too hard - more changes to come. Hands off! -* v1.1.0.295 - try to establish backwards compatibility -* v1.1.0.294 - finish the ArenaRegion rewrite. Use with caution!!! -* v1.1.0.293 - rewrite the ArenaRegion system. Hope noone created their own Shapes yet :O \ No newline at end of file diff --git a/doc/history/1.2.md b/doc/history/1.2.md deleted file mode 100644 index 64df2c55f..000000000 --- a/doc/history/1.2.md +++ /dev/null @@ -1,78 +0,0 @@ -== PVP-Arena v1.2 Changelog - -=== Changelog - -* v1.2.4.494 - remove some debug spam about dye and leather data -* v1.2.4.493 - properly make use of the "keepOnDeath" together with "dropsInventory" -* v1.2.4.492 - remove the remaining Exceptions -.- -* v1.2.4.491 - remove debug leftovers - sorry! -* v1.2.4.490 - address DBO ticket #874 - various fixes/additions -* v1.2.4.489 - finally correctly address the inventory restoring issues (keepItems should be fixed now!) -* v1.2.4.488 - add showRemainingLives - allow hiding of the remaining lives -* v1.2.4.487 - fix little Arcade related NPE -* v1.2.4.486 - add (hacky) support for Arcade; and: jenkins maven repo! -* v1.2.4.485 - possibly fix PlayerLives ending? -* v1.2.4.484 - shift death parsing order; attempt to fix respawnrelay - ticket #792 -* v1.2.4.482 - [DOM] change announceOffset to display logic, not to count logic; addresses github issue #66 -* v1.2.4.481 - fix TDM kill output. address github issue #65; revert fix build #465 -* v1.2.4.480 - address github issue #64 -* v1.2.4.479 - add Domination tickinterval (60) and tickreward (1); adds github issue #60 -* v1.2.4.478 - fix a respawn relay NPE, e.g. when a player leaves while respawning -* v1.2.4.477 - more Inventory dropping/restoring fixes -* v1.2.4.476 - WARNING - MAYBE BREAKING -* v1.2.3.475 - add config settings for global points system -* v1.2.3.474 - address ticket #866 -* v1.2.3.473 - forward allowed items instead of the (mostly cleared) event drops -* v1.2.3.472 - add respawnrelay specific debug -* v1.2.3.471 - rewrite the smart respawning -* v1.2.3.470 - fixed debug -* v1.2.3.469 - even more debug :/ -* v1.2.3.468 - godgodgodgo - I will! [smart respawn debug spam] -* v1.2.3.467 - default to VILLAGER instead of WOOL as Rescue Entity -* v1.2.3.466 - add "Rescue" language and config node -* v1.2.3.465 - mibby sais push, slipcor pushes! -* v1.2.3.464 - another instance of false proclamation of rewards -* v1.2.3.463 - add final liberation kill, don't tell the arena the rewards have been given too early -* v1.2.3.462 - address github issue #46 - buffer team players -* v1.2.3.461 - fix WorldGuard language nodes -* v1.2.3.461 - fix arena player class determination -* v1.2.3.460 - fix "custom" classes not being considered as such, fixes #828 -* v1.2.3.459 - allow inventory access for Flag Holders; fixes #828 -* v1.2.3.458 - add WorldGuard config settings -* v1.2.3.457 - add PlayerClass command implementation -* v1.2.3.456 - add player created classes [pvparena.create.class] -* v1.2.3.455 - add better named ArenaBoard headers -* v1.2.3.454 - support colored ArenaBoard signs -* v1.2.3.453 - add default goal config settings -* v1.2.3.452 - add the teleport lag y-offset to "old" (pre-join) locations -* v1.2.3.451 - add ' ' to the non printed messages. addresses github issue #59 -* v1.2.3.450 - finish github issue #53 [Infect] -* v1.2.3.449 - small fixes -* v1.2.3.448 - [WARNING] only for mibby & github issue #54 - might break player resets!! - force remove players from arenas -* v1.2.3.447 - anyone having an issue with us NOT kicking everyone if the arena fails to start? addresses github issue #44 -* v1.2.3.446 - add PATeamChangeEvent for infect, tank and other things like that -* v1.2.3.445 - fix github issue #57 - modules/goals do not add default config settings -* v1.2.3.444 - [WARNING] only for mibby & github issue #44 - rewrote the start check, might either fix it or break everything -* v1.2.3.443 - add ColorTeams->ScoreBoard to use the scoreboard coloring instead of TagAPI -* v1.2.3.442 - little fixes, thanks to samoatesgames -* v1.2.3.441 - add debug for github issue #44 - countdown ignoring uneven teams -* v1.2.3.440 - add debug for github issue #46 - "teamrewards" -* v1.2.3.439 - [BlockDissolve] add "startSeconds" to wait X seconds before removing -* v1.2.3.438 - properly maintain sorting when handing over sorted collections -* v1.2.3.437 - add debug for github issue #43 -* v1.2.3.436 - properly save the config after setting an inventory to a config node -* v1.2.3.435 - add BlockDissolve config values -* v1.2.3.434 - only add needed config nodes -* v1.2.2.433 - [g:TeamLives] only mark a player as lost when needed -* v1.2.2.432 - verify #431 -* v1.2.2.431 - properly remove player names that are longer than 15 characters -* v1.2.2.430 - nerf #429 -* v1.2.2.429 - add an error stacktrace while unsuccessfully handling a sign removal -* v1.2.2.428 - finish the old/new updater! -* v1.2.2.427 - fix a ClassCastException when using /pa info -* v1.2.2.426 - change the updater to my former way for several reasons. see documentation -* v1.2.2.425 - add alwaysJoinInBattle - allow people to join late, no matter what! -* v1.2.2.424 - fix issue #830 - only care about players not playing or players part of the current arena -* v1.2.2.423 - enforce inventory reset (if wanted) -* v1.2.2.422 - properly reset the "players that have played" counters -* v1.2.2.421 - prepare for 1.8 - STEP 1: use player UUIDs for stats \ No newline at end of file diff --git a/doc/history/1.3.0.md b/doc/history/1.3.0.md deleted file mode 100644 index 5278f1ef0..000000000 --- a/doc/history/1.3.0.md +++ /dev/null @@ -1,66 +0,0 @@ -== PVP-Arena v1.3.0 Changelog - -- v1.3.0.558 - fix github issue #83 -- v1.3.0.557 - fix github issue #61 -- v1.3.0.556 - fix github issue #64 -- v1.3.0.555 - add x-offset and z-offset, so one can change the default behaviour of putting ppl on the middle of a block -- v1.3.0.554 - fix an NPE in some places due to a return value of null should be expected! -- v1.3.0.553 - add chat.toGlobal to allow private talking players to talk to the public with a prefix -- v1.3.0.552 - add CRAFT RegionProtection to prevent item crafting -- v1.3.0.551 - add damage.fromOutsiders (false) to allow players (and other entities) to hurt fighters -- v1.3.0.550 - properly check for some things before adding players to a class via command -- v1.3.0.549 - try to fix long usernames staying on signs -- v1.3.0.548 - prevent a NPE -- v1.3.0.547 - call the leave event - I am shocked noone noticed that until yesterday -- v1.3.0.546 - reverse all the things and do what I promised the last 2 commits -- v1.3.0.545 - fix books! (for real) -- v1.3.0.544 - fix books! -- v1.3.0.543 - trying again -- v1.3.0.542 - attempt to fix some data reading issues (for ink sacks and wool blocks) -- v1.3.0.541 - fix some display issues about max team players -- v1.3.0.540 - attempt to fix special character issues -- v1.3.0.539 - allow to take suicides into account for TDM -- v1.3.0.538 - still on github issue #78 - never remove perms! -- v1.3.0.537 - fix missing perms message, addressing github issue #78 -- v1.3.0.536 - finish github issue #78 - typo messup -- v1.3.0.535 - address github issue #78 - add language nodes for missing perms -- v1.3.0.534 - prevent tamed animals belonging to an arena player from teleporting -- v1.3.0.533 - finally fix github issue #76 - inventory reset messup -- v1.3.0.532 - address github issue #76 -- v1.3.0.531 - address github issue #64 -- v1.3.0.530 - add "classSwitchAfterRespawn", defaulting to false -- v1.3.0.529 - revert #523 - I don't care anymore - this HAS to fix it, otherwise I give up on development :P -- v1.3.0.528 - revert #519 - second attempt at fixing an issue on several implementations -- v1.3.0.527 - revert #518 - this fixed dbo issue #912 (duplications on Cauldron) but caused items disappearing on other implementations -- v1.3.0.526 - add more config settings for PlayerKillReward -- v1.3.0.525 - address DBO issue #923 -- v1.3.0.524 - address DBO issue #921 -- v1.3.0.522 - fix integer/integer divisions -.- -- v1.3.0.521 - clarify custom class determination debug -- v1.3.0.520 - clarify damage debug values -- v1.3.0.519 - forcefully place players where they joined if the player is disconnecting -- v1.3.0.518 - forcefully remove items when a player leaves the arena -- v1.3.0.517 - address DBO issue #907 - don't try to teleport null/dead players -- v1.3.0.516 - try fixing NOCAMP damage -- v1.3.0.515 - [IDEA] various fixes -- v1.3.0.511 - address DBO issue #888 - reset chat color if desired -- v1.3.0.510 - add mobs fighting by your side. Give classes a spawn egg with displayname "SPAWN" -- v1.3.0.509 - properly build #507 prefix -- v1.3.0.507 - add materialprefixes to the global config, for special Material names (bukkit:SAND) -- v1.3.0.506 - add '*' command for the whitelist to allow all commands -- v1.3.0.505 - add per command permissions - defaulting to old behaviour -- v1.3.0.504 - don't drop inventory if not desired -- v1.3.0.503 - fix the UUID interpretation; use player names for creation, not the UUID -.- -- v1.3.0.502 - how about we actually RUN the runnable? -- v1.3.0.501 - force /pa leave on final player death if no specate module present -- v1.3.0.500 - address ticket #869, #884, #792 - - add time.resetDelay (default: -1 --> off) - delay for resetting players (TP & inventory) - - support single SPAWN regions for team matches - - support lore and displayname for keepItems -- v1.3.0.499 - address ticket 792, 879, 881 - - attempt to fix the Food Goal to properly handle player deaths - - require explicit perms for /pa arenaclass (if desired) -- v1.3.0.498 - properly initiate late joining PlayerDeathMatch players -- v1.3.0.497 - check for explicit class perms, even though we have no Sign! -- v1.3.0.496 - minor fixes -- v1.3.0.495 - add Command Tab support; Big Command rewrite!! \ No newline at end of file diff --git a/doc/history/1.3.1.md b/doc/history/1.3.1.md deleted file mode 100644 index c5c6fdf8a..000000000 --- a/doc/history/1.3.1.md +++ /dev/null @@ -1,47 +0,0 @@ -== PVP-Arena v1.3.1 Changelog - -- v1.3.1.49 - fix an NPE on server shutdown -- v1.3.1.48 - update all the things in the doc -- v1.3.1.46 - pull #106 - thanks a TON to @Oruss7 for putting together this load of information! -- v1.3.1.45 - the final update for 1.7.9 - unless critical errors arrive. I need to get ready for 1.9 -- v1.3.1.44 - prevent an NPE in the WarmupJoin module -- v1.3.1.43 - revert the last commit and furthermore clarify and verify correctly. Modules build incoming -- v1.3.1.42 - fix a logic messups in an internal join check -- v1.3.1.41 - duel module finished -- v1.3.1.40 - allow to disable the Duel force ready & start -- v1.3.1.39 - duel module language finish -- v1.3.1.38 - finish off github issue #118 -- v1.3.1.37 - more shurtcut arena list fixes -- v1.3.1.36 - try to fix the round arena status check -- v1.3.1.35 - apply former fix for arena listing -- v1.3.1.34 - override only_shortcuts with allow_ungrouped to allow joining arenas not grouped under shortcuts -- v1.3.1.33 - properly format and save spawn offsets -- v1.3.1.32 - properly format and save spawn offsets -- v1.3.1.31 - properly allow for 5 arguments of /pa spawn -- v1.3.1.30 - fix github issues #115, #118 -- v1.3.1.29 - address github issue #112 -- v1.3.1.28 - how about we don't delete the spawn after offsetting it? -.- -- v1.3.1.26 - github issue #104 - EXPERIMENTAL! -- v1.3.1.25 - this time for real - we need to tell people they CAN decline :) -- v1.3.1.24 - add final language for github issue #97 -- v1.3.1.23 - add config for github issue #86 -- v1.3.1.22 - release build -- v1.3.1.21 - and more language nodes -- v1.3.1.20 - prepare Dual fixes and commit some language/message fixes -- v1.3.1.19 - fix another Exception in the time goal -- v1.3.1.18 - properly output unclaiming vs contesting flags in domination goal - language file consistency fixed -- v1.3.1.17 - fix some language derps and move the delayed class change to where it makes more sense -- v1.3.1.16 - fix github issue #108 - contesting (unclaiming) too late -- v1.3.1.15 - add github issue #100 - player.healforkill - true/false :) -- v1.3.1.14 - use the SNAPSHOT distinction and address github issue #85 -- v1.3.1.13 - hide the not-really stat type NULL (player name) -- v1.3.1.12 - fix github issue #95 by adding a null check -- v1.3.1.11 - clarify language for RespawnRelay and fix a little Exception in the Time goal -- v1.3.1.10 - address github issue #88 - properly keep players as DEAD when being relayed -- v1.3.1.9 - address github issue #87 - add THORNS damage handling -- v1.3.1.8 - properly deal with inventory protection -- v1.3.1.7 - how about we don't spam EVERYthing but spam after collecting everything, and inform people that we have prevented something? -- v1.3.1.6 - fix some mathematical and logical derps -- v1.3.1.5 - really add INVENTORY check - properly define new Infect commands [setprotect|getprotect] -- v1.3.1.4 - allow goals to deny BREAK, PLACE, TNT, TNTBREAK, DROP, INVENTORY, PICKUP, CRAFT - proof of concept! -- v1.3.1.1 - link to new jenkins. Thanks to @graywolf336 \ No newline at end of file diff --git a/doc/history/1.3.2.md b/doc/history/1.3.2.md deleted file mode 100644 index 6d0af568e..000000000 --- a/doc/history/1.3.2.md +++ /dev/null @@ -1,79 +0,0 @@ -== PVP-Arena v1.3.2 Changelog - -- v1.3.2.137 - address github issue #205 -- v1.3.2.136 - add language response for ChestFiller -- v1.3.2.135 - add documentation about ChestFiller changes, add some more config nodes that are now properly loaded with defaults automatically -- v1.3.2.134 - address github issue #201 - properly call PAJoinEvent, this never was implemented correctly. Sorry! -- v1.3.2.133 - prepare ChestFiller addition by adding language and documentation -- v1.3.2.132 - prepare ChestFiller addition by adding config node -- v1.3.2.131 - remove FallingAnvils hooks and documentation - it did not work out :/ -- v1.3.2.130 - stop spamming, please. Aims at fixing github issue #154 -- v1.3.2.129 - address github issue #209 - oups -- v1.3.2.128 - add a module method "parseStartCountDown" to possibly override the remaining seconds to go -- v1.3.2.127 - fix github issue #204 by removing all traces of the nonexisting command "import" -- v1.3.2.126 - address github issue #202 - remove "error" and only write it to debug -- v1.3.2.125 - address github issue #155, prevent double dropping of inventory. Hope this does not break anything :P -- v1.3.2.124 - address github issue #154 - just remove tick 4, it's not that important anyways. And remove the blocklist spam :) -- v1.3.2.122 - furthermore fix the uninstall routine -- v1.3.2.121 - address github issue #131 - I think I found the bug! -- v1.3.2.120 - address github issue #203 by firstly fixing the NPE and adding more info to the uninstalling error (Main server log!) -- v1.3.2.119 - prevent double instantiation of arenas - use with caution! :P -- v1.3.2.118 - [CheckPoints] - address github issue #197 -- v1.3.2.117 - [BetterFight] add config setting to restrict explosions only to one-hit deaths -- v1.3.2.116 - add CheckPoint goal (github issue #184) - have fun testing! -- v1.3.2.115 - add "refillforkill" - restocks the inventory with the class items -- v1.3.2.114 - address github issue #191 - prevent NPE due to NULL item in class items -- v1.3.2.113 - add more debug to investigate fire charge ignition issues -- v1.3.2.112 - continue fix for Scoreboards being double reset in modules -- v1.3.2.111 - prepare fix for Scoreboards being double reset in modules -- v1.3.2.110 - address github issue #185 by fixing WorldEdit documentation and messages -- v1.3.2.109 - address github issue #186 -- v1.3.2.107 - address github issue #178 - prevent enderpearl teleport when not alive and fighting -- v1.3.2.106 - [TeamDeathMatch] fix a double broadcast of the winning team -- v1.3.2.105 - fix the documentation for EventAction config -- v1.3.2.103 - furthermore attempt to fix #175 by adding a teleport lock variable -- v1.3.2.102 - support multiple WATCH and LOUNGE regions - addresses github issue #175 -- v1.3.2.101 - finish github issue #174 -- v1.3.2.100 - address github issue #174 -- v1.3.2.99 - add Beacons settings and documentation -- v1.3.2.97 - add Titles API hooks, documentation will follow -- v1.3.2.96 - add a configuration node to change the schematics folder for WorldEdit - adds github issue #129 -- v1.3.2.95 - add region command documentation - thanks @Oruss7 -- v1.3.2.94 - add Language for special Duel/Vault hooking -- v1.3.2.93 - add config settings and documentation for the FallingAnvils module -- v1.3.2.92 - [forcewin] how about we load the command so it can be used? -- v1.3.2.91 - add /pa [arena] forcewin, shorthand !fw - forces a player / team to win -- v1.3.2.90 - fix some more errors about the new command. Works now :) -- v1.3.2.89 - fix the shorthand and the doc linking -- v1.3.2.88 - add /pa [arena] classchest [class] - shorthand !cc - fixed class chests containing the items -- v1.3.2.87 - address github issue #168, NPE on StructureGrowEvent -- v1.3.2.85 - revert deprecation of ArenaModule.getArena() - failsafe(r) loading of modules and goals - arenas will not appear lost any more! -- v1.3.2.84 - address github issue #161, properly read ambiguous ready block definition -- v1.3.2.83 - address github issue #159 - do not instanciate the tracker if disabled -- v1.3.2.82 - address github issue #158 by adding 'shortcut_shuffle' -- v1.3.2.81 - address github issue #154, maybe even issue #86 - only check necessarily flagged regions and BATTLE regions, with include-check -- v1.3.2.80 - properly fix build #68 -- v1.3.2.79 - add TELEPORT protection to allow teleport prevention (it was silently allowed if only happening IN the region, without command) -- v1.3.2.78 - change WALLS config setting command to "wallseconds", it interfered with the most probable arena name -- v1.3.2.77 - revert the CommandPreProcessEvent and rather fix the underlying problem, the command whitelist being too greedy. Added a config setting to use comand list as wildcards -- v1.3.2.76 - enforce player and teamplayer max values, move CommandPreProcessEvent to priority low to fix MobArena join related exploits -- v1.3.2.75 - properly save an ArenaGoal name to the round map (instead of its instance) -- v1.3.2.74 - fix a NPE in the EndRunnable when using rounds -- v1.3.2.73 - add a new command "regionclear" to manage region clearing exceptions -- v1.3.2.72 - add language and documentation for the WorldEdit addition -- v1.3.2.71 - add WorldEdit config to specify regions to autoload/autosave -- v1.3.2.70 - allow data values in MATERIAL definitions (only works with /pa set [node] hand) -- v1.3.2.69 - properly apply rewards when teamrewards is used -- v1.3.2.68 - remove repo pushing to maybe fix building for now -- v1.3.2.64 - fix issue #143 - thanks to Oruss7! -- v1.3.2.63 - add some message output when class changing fails -- v1.3.2.62 - prepare module class change hooking -- v1.3.2.61 - address github issue #114 - add LibsDisguises support -- v1.3.2.60 - fix CTF being messed up by people continuing to play -- v1.3.2.59 - fix update check -- v1.3.2.58 - /pa help - it still shows the colored standard reply even with sub-arguments -- v1.3.2.57 - address github issue #135 - language addition -- v1.3.2.56 - address github issue #141 - add config calcoffset to tweak block dissolve greediness -- v1.3.2.55 - fix Spectate Spectators being told they cannot teleport when switching view -- v1.3.2.54 - new Module: Spectate - uses the 1.8 SPECTATOR GameMode -- v1.3.2.51 - update to Java 7 \ No newline at end of file diff --git a/doc/history/1.3.3.md b/doc/history/1.3.3.md deleted file mode 100644 index 17572ca81..000000000 --- a/doc/history/1.3.3.md +++ /dev/null @@ -1,112 +0,0 @@ -== PVP-Arena v1.3.3 Changelog - -- v1.3.3.248 - /pa reload ymls | reload main config, language and help ymls -- v1.3.3.247 - do not duplicate offhand items and don't try to set objectives that are not needed (because of disabled scoreboard) -- v1.3.3.246 - address github issue #280, reload global language and help nodes on /pa reload -- v1.3.3.245 - revert player names appearing on scoreboards, maybe properly display 0 team lives left? -- v1.3.3.244 - catch an NPE about scoreboards and dead/offline players and fix a scoreboard crash vulnerability -- v1.3.3.243 - eventually delay scoreboard display to arena start, delay inventory reset to when a player gets put back to their exit spawn, delay fire tick reset -- v1.3.3.242 - properly reset scoreboard when simply leaving by command -- v1.3.3.241 - address github issue #278 - support "hand" placeholder for multiple-item-definitions too -- v1.3.3.240 - address github issue #276 by catching the NPE even deeper -- v1.3.3.239 - fix inventory double drop bug when losing the last life -- v1.3.3.238 - allow for default death messaeges by setting both deathmessage config nodes to false -- v1.3.3.237 - address github issue #271 - do not remove/use player list scoreboard if scoreboard is disabled -- v1.3.3.236 - address github issue #273 - add Elytra to chestplate definition list -- v1.3.3.235 - address github issue #274 - fix player leaving handling in general -- v1.3.3.234 - properly require permission for /pa command -- v1.3.3.233 - address github issue #273 - single item definitions (maybe more) gets lost until restart -- v1.3.3.232 - add github issue #258 - liberation scoreboard separation of jailed players -- v1.3.3.231 - add github issue #198 - particle display of domination claim radius -- v1.3.3.230 - add github issue #237 - items on kill, settable via command and "inventory" handle! -- v1.3.3.229 - address github issue #254 - update Arrow Hack for Spigot > 1.9 -- v1.3.3.228 - address github issue #151 and try to add a custom scoreboard entry to show round progress -- v1.3.3.227 - fix scoreboard removal and fix a bug that caused doubled starting method call -- v1.3.3.226 - allow longer scoreboard entries (48 characters for now) -- v1.3.3.225 - reintroduce custom scoreboard entries -- v1.3.3.224 - address github issue #264 - ArenaClass equipping debug triggers NPE -- v1.3.3.223 - address github issue #267 - critical fix about gamemodes -- v1.3.3.222 - fix grabbing the flag giving you no wool head -- v1.3.3.221 - refresh debug instance for global debug when stopping / changing debug output -- v1.3.3.220 - further ID fixes, and fix a but about GameMode setting and one about players being able to join an arena when it is restoring -- v1.3.3.219 - finish the item ID burial -- v1.3.3.218 - stop supporting item IDs in configs - configs shall be updated! -- v1.3.3.217 - do not nag people to update if updater type DOWNLOAD is selected - addresses github issue #244 -- v1.3.3.216 - address a bug about invisibility being nullified by internal scoreboard -- v1.3.3.215 - address issue #238 by adding refillCustomInventory - defaulting to true -- v1.3.3.214 - address issue #255 - Remove arrows stuck to everyone -- v1.3.3.213 - address issue #256 - Exception about ScoreBoards when shutting down -- v1.3.3.212 - fix issue #252 by catching a NPE -- v1.3.3.211 - revert c67e4a6 - never mess with flying speed or walking speed again plz :P -- v1.3.3.210 - revert 4f75803 - never mess with flying speed or walking speed again plz :P -- v1.3.3.209 - final attempt to get rid of the speed issue - deactivate with -10 -- v1.3.3.208 - address issues with commit 4f75803 -- v1.3.3.207 - address github issues #245 and #248 -- v1.3.3.206 - finish the spawn region fix -- v1.3.3.205 - continue attemmpt to fix region spawning -- v1.3.3.204 - revert the last commit and try to fix region spawning -- v1.3.3.203 - try to fix an issue about respawning players not getting reset properly -- v1.3.3.202 - try to finish off github issue #212 by delaying scoreboard slot selection and player removal -- v1.3.3.201 - allow to disable all gamemode changes; make "takeOutOfGame" actually work -- v1.3.3.200 - prevent the plugin from messing up player restoring in certain reset cases -- v1.3.3.199 - address github issue #238 - allow to keep ALL items on respawn -- v1.3.3.198 - add "teleportonkill" to allow force respawn of killers -- v1.3.3.197 - address github issue #238 - allow to keep ALL items on respawn -- v1.3.3.196 - address github issue #240 - message consistency -- v1.3.3.195 - address github issue #241 - don't use Location, use Vectors for offset -- v1.3.3.194 - fix github issue #232 - Potions disappearing when readying up -- v1.3.3.193 - fix StatisticsManager to actually be persistent. SORRY! -- v1.3.3.192 - add config for github issue #220 -- v1.3.3.191 - fix github issue #188 - I found the right way to deactivate collision -- v1.3.3.190 - address github issue #120 - limiting class changes -- v1.3.3.189 - address github issue #99 - can we finally bury this? ^^ -- v1.3.3.188 - [FFA] allow to punish being killed by other things than a player: punishsuicide -- v1.3.3.187 - allow to set keepOnRespawn to "all" to, yes, keep all items -- v1.3.3.186 - implement ColorTeams and ScoreBoards modules into core - addresses github issue #212 -- v1.3.3.185 - add an announcement verification hack to WarmupJoin -- v1.3.3.184 - revert build #177 (saturation lock), does not work anyways -- v1.3.3.183 - very important module fix - player resetting was broken! -- v1.3.3.182 - reduce command whitelist case sensitivity -- v1.3.3.181 - reduce command case sensitivity -- v1.3.3.180 - allow modules to know whether to soft reset a player -- v1.3.3.179 - fix config node typo -- v1.3.3.178 - allow to quick leave with caps lock -- v1.3.3.177 - add saturation lock, to prevent regains going crazy -- v1.3.3.176 - apply global and specific teleport offset when resetting player -- v1.3.3.175 - fix github issue #230 -- v1.3.3.174 - little thing about #230 and add more debug to see why it might not work yet -- v1.3.3.173 - address github issue #222, again -- v1.3.3.172 - finish github issue #225 -- v1.3.3.171 - add github issue #230 - apply the teleport protection to the lounge, too, to prevent teleport warnings -- v1.3.3.170 - try to fix disabling breaking arena shortcut rotation -- v1.3.3.169 - maybe fix an issue that shortcut rotation doesn't work when the arenas are disabled at start -- v1.3.3.168 - partially revert breaking #222 even more -- v1.3.3.167 - address github issue #227 - reset killer's items to KILLER's class -- v1.3.3.166 - maybe finally tackle github issue #222 -- v1.3.3.165 - properly implement github issue #225 -- v1.3.3.164 - finish up github issue #203 -- v1.3.3.163 - address github issue #224 -- v1.3.3.162 - address all remnants of issue #203 -- v1.3.3.161 - address github issue #224 - double output in the lounge -- v1.3.3.160 - I got an idea, how about we actually implement issue #188 ?! oh and add issue #225 -- v1.3.3.159 - address github issue #222 -- v1.3.3.158 - continue fixing the issue mentioned in build #153 -- v1.3.3.157 - address github issue #222, again -- v1.3.3.156 - change the updating process and block installing/updating when there is no install.yml due to "update.files" (you can allow this setting and disable automatic updates with updatemode "none" or "announce") -- v1.3.3.155 - remove spectral arrows from the potion meta list, those don't seem to have potion effects -- v1.3.3.153 - try to fix the issue of lounge players not being able to interact where they should -- v1.3.3.152 - try to implement github issue #188 -- v1.3.3.151 - add config setting for github issue #188 -- v1.3.3.150 - address github issue #131 - if it's not fixed, I at least added debug -- v1.3.3.149 - address github issue #215 by removing a never launched minigame API and make sure to get the proper shortcut name, if possible -- v1.3.3.148 - finally fix github issue #205 -- v1.3.3.147 - prevent inventory dropping even if custom class is active -- v1.3.3.146 - found the little bug that caused github issue #205 ! -- v1.3.3.145 - partially revert d8d9bf174027aadc6ccd641b6cef7b660f435f25 to address github issue #205 -- v1.3.3.144 - potions are operational. Please update your class definitions (if you did not use class chests) -- v1.3.3.143 - please use the same logic for saving and loading -- v1.3.3.142 - potions should work now. Please redo all your potionish classes (potions, splash potions, lingering, arrows, etc) -- v1.3.3.141 - try to fix armor supply -- v1.3.3.140 - properly fix Potion creation/saving broken by Spigot 1.9 API changes -- v1.3.3.139 - properly fix Inventory handling broken by Spigot 1.9 API changes -- v1.3.3.138 - move to Spigot 1.9.4 \ No newline at end of file diff --git a/doc/history/1.3.4.md b/doc/history/1.3.4.md deleted file mode 100644 index e26bb8668..000000000 --- a/doc/history/1.3.4.md +++ /dev/null @@ -1,52 +0,0 @@ -== PVP-Arena v1.3.4 Changelog - -- v1.3.4.298 - attempt to properly back up NBT data of player's items in case of an unnatural leaving of the arena -- v1.3.4.297 - address github issue #351 - add yet another delay to fix Spigot -- v1.3.4.296 - address github issue #329 - actually change the scoreboard title :O -- v1.3.4.295 - fix the fact that the scoreboard did not update on losing the last life. Thanks to @Oruss7 -- v1.3.4.294 - add team size and total team count when joining -- v1.3.4.293 - address github issue #332 - display first checkpoint message, and display numbers starting from 1 -- v1.3.4.292 - address github issue #329 - use arena prefix instead of name, if still too long, shorten manually -- v1.3.4.291 - added debug to PotionSplashEvent for someone to have evidence to report a bug -- v1.3.4.290 - when setting up a region, check that it has actual resulting volume before saving -- v1.3.4.289 - address github issue #324 - call home asynchronously -- v1.3.4.288 - stop igniting your own TNT - and tell people that it is not okay -- v1.3.4.287 - update EventActions docs to properly reflect the node names -- v1.3.4.286 - update EventActions docs and fix github issue #314 by not stopping arenas twice on reload! -- v1.3.4.285 - allow to update spawn and blocks on the fly -- v1.3.4.284 - fix docs [remove colorteams and scoreboard] and add language and docs for BetterClass "respawnCommand" -- v1.3.4.283 - add EventActions addition (classchange hook) -- v1.3.4.282 - address github issue #305 - check max health before setting health -- v1.3.4.281 - address github issue #302 - prevent NPE for spectators when joining the arena -- v1.3.4.280 - remove debug output of time message nodes -- v1.3.4.279 - add github issue #249 - playSound (???) to add particle effect, DONE -- v1.3.4.278 - add github issue #124 - add timer configs to add/remove/change timer interval messages -- v1.3.4.277 - add github issue #117 - BossBar for Domination -- v1.3.4.276 - do not setup a scoreboard if spectating is cancelled/not possible -- v1.3.4.275 - allow right clicking blocks when LOST attempt 2 -- v1.3.4.274 - allow right clicking blocks when LOST and add Region Protection Tutorial -- v1.3.4.273 - update player equip function to support offhand slots -- v1.3.4.272 - properly protect and not overprotect, affected: MOBS [block lightning], TNT [prevent entity damage], GROW [actually block block growth] -- v1.3.4.271 - remove metrics and update the readme with new region shape tutorial -- v1.3.4.270 - do not add spectator names to the scoreboard -- v1.3.4.269 - update the spectator scoreboard -- v1.3.4.268 - create a scoreboard for spectators -- v1.3.4.267 - address github issue #291 by adding "perms.spectatorinteract" to allow spectators to interact -- v1.3.4.266 - remove debug and address github issue #292 by checking if a player already joined an arena before doing anything -- v1.3.4.265 - how I miss those debug times. IS THE PLAYER FLYING OR NOT!??!! -- v1.3.4.264 - why not try without delay? -- v1.3.4.263 - change fly mode saving and restoring -- v1.3.4.262 - do not restore flying state if specating on death -- v1.3.4.261 - delay flying mode setting by 5 ticks when restoring a player -- v1.3.4.260 - address github issue #290 - catch NPE about Spawn Eggs -- v1.3.4.259 - finish off github issue #280 by adding a proper message about reloading the languages -- v1.3.4.258 - finish the fix for issue #198 by supporting beacon block definitions -- v1.3.4.257 - address github issue #198 - make particle circle function goal independant -- v1.3.4.256 - address github issue #285 - catch NPE by checking for missing round argument -- v1.3.4.255 - address github issue #263 - properly cancel interact event - I assumed that they come uncancelled - wrong -- v1.3.4.254 - who ordered .lck files? Not me! Byebye! [debugging file handler not closed] -- v1.3.4.253 - hotfix about cancelling PlayerItemConsumeEvent - sorry @mibby, fasting is over now! -- v1.3.4.252 - fix issue #263 by cancelling PlayerItemConsumeEvent - since when is this a necessity? The interact event was cancelled :P -- v1.3.4.251 - fix spawn alignment glitches, some of which were fixed by restarting the server, fix double messages around right clicking -- v1.3.4.250 - update some things to the latest API - fix CheckPoints spawn set logic, fix PlayerDeathMatch required kill display -- v1.3.4.249 - update to Spigot 1.11 - address github issue #218 \ No newline at end of file diff --git a/doc/items.md b/doc/items.md index 2de209fac..1c1eab366 100644 --- a/doc/items.md +++ b/doc/items.md @@ -1,7 +1,11 @@ +# Items in configuration files -If you are brave, you can set items for inventories or enhancements directly in -arena config files. It's quite verbose but not really hard. If you aren't at ease with YAML -config files, please use [/pa class](commands/class.md) commands. +With PvPArena, all your arena configuration is stored in a [dedicated config file](configuration.md). For some reasons, +it could be useful to check it or edit it directly. This document will try to explain how you can edit list of items +for inventories or enhancements directly in arena config files. + +This is an **advanced level** tutorial, so if you aren't at ease with YAML config files, please use +[/pa class](commands/class.md) and [/pa set](commands/set.md) commands. JavaDoc : [Bukkit Material ENUMs](https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/Material.html) diff --git a/doc/languages.md b/doc/languages.md index 7382ccab1..7d691c83b 100644 --- a/doc/languages.md +++ b/doc/languages.md @@ -1,10 +1,18 @@ -These are the language files for PVP Arena, not (all) created or updated by me. +# Languages -Download the file and set lang: en to lang: value inside the config.yml +Here are the language files for PVP Arena, not (all) created or updated by me. -download | lang: value | language | author | date +Download the file and set `lang:` parameter inside the config.yml to +value of the second column. + +download | lang: value | language | author | last update ------------- | ------------- | ------------- | ------------- | ------------- -[link](../lang/lang_en.yml) | 'en' (default) | English | slipcor | 2013/09/11 +[link](../lang/lang_en.yml) | 'en' (default) | English | slipcor/Eredrim | 2020 [link](../lang/lang_es-es.yml) | 'es-es' | Español | Anubis3467 | 2014/09/11 -[link](../lang/lang_fr.yml) | 'fr' | Français | Fizzweapon | 2013/08/22 -[link](../lang/lang_ru.yml) | 'ru' | Russki | llNeosGamer | 2013/04/13 \ No newline at end of file +[link](../lang/lang_fr.yml) | 'fr' | Français | Eredrim | 2020 +[link](../lang/lang_ru.yml) | 'ru' | Russki | llNeosGamer | 2013/04/13 + +
+ +> 💡 **Did you know ?** +> You can propose your own language file by [creating an issue](https://github.com/Eredrim/pvparena/issues). \ No newline at end of file diff --git a/doc/mods/powerups.md b/doc/mods/powerups.md index a3d5463fb..8742aa829 100644 --- a/doc/mods/powerups.md +++ b/doc/mods/powerups.md @@ -13,7 +13,7 @@ Unzip the module files (files tab, "PA Files v*.*.*") into the /pvparena/files f ## Setup -Sorry, but you have to add a freaking block to your arena config under `module.powerups.items`. Eg: +Sorry, but you have to add a freaking block to your arena config under `module.powerups.items`. E.g.: ```yaml items: diff --git a/doc/modules.md b/doc/modules.md index d1dbb4a7b..9f9ea4b31 100644 --- a/doc/modules.md +++ b/doc/modules.md @@ -1,13 +1,16 @@ -## PVP Arena Modules +# PVP Arena Modules -### Installation +## About -Unzip the module files (files tab, "PA Files v\*.\*.\*") into the /pvparena/files folder and install them via -`/pa install [modname]`, **activate per arena via** -`/pa [arenaname] !tm [modname]` +PvPArena modules are ways to enhance your arenas. They could modify a lot of things like configuration, fights, classes +or spectating... +To manage your arena mods (download, install, remove, etc), please check [documentation](commands/modules.md) of +`/pa modules` command. -### PVP Arena Mods +To enable a module for an arena, use [`/pa togglemod`](commands/togglemod.md) command. + +## PVP Arena Mods Hook into many different aspects of the game! @@ -66,4 +69,4 @@ PVP Arena exists since 2011 and Minecraft servers evolution make modules follow- updates will be to make a great check-up of all of them and fix all eventual issues. Anyway, don't hesitate to test legacy modules by yourself, a big part of them work normally or have trivial issues. Obviously -if you encounter one, you can report it 😉 \ No newline at end of file +if you encounter one, you can [report it](https://github.com/Eredrim/pvparena/issues) 😉 \ No newline at end of file diff --git a/doc/permissions.md b/doc/permissions.md index 89619397e..c9eb4f9af 100644 --- a/doc/permissions.md +++ b/doc/permissions.md @@ -1,4 +1,4 @@ -# Permission Nodes +# Permission nodes The following nodes can be used: @@ -10,18 +10,23 @@ pvparena.create| Allows you to create and administrate your arenas (default: op) pvparena.telepass| Allows you to teleport while in an arena (default: op) pvparena.user | Allows you to use the arena (default: true) -If you activate **explicitClassNeeded** you have to add permissions e.g. (proper class name case !!) + +### Specific class permissions + +If you activate `explicitClassNeeded` you have to add permissions e.g. (proper class name case !!) Node | Definition ------------- | ------------- pvparena.class.Ranger | Give Ranger class permission pvparena.class.Tank | Give Tank class permission -If you activate **explicitArenaNeeded** you have to add permissions e.g. (all lowercase!) +### Specific arena permissions + +If you activate `explicitArenaNeeded` you have to add permissions e.g. (all lowercase!) Node | Definition ------------- | ------------- pvparena.join.ctf | Give ctf join permission pvparena.join.spleef | Give spleef join permission -PVP Arena uses the SuperPerms interface \ No newline at end of file +PVP Arena uses the SuperPerms interface, i.e. default bukkit permissions interface. \ No newline at end of file diff --git a/doc/regions.md b/doc/regions.md index cb4ba5625..15a469d0e 100644 --- a/doc/regions.md +++ b/doc/regions.md @@ -1,47 +1,57 @@ # Regions -Regions allow further functions to be added to your game play. +Regions enhance your game play by adding protections, triggers or special configurations. -You can list existing arena regions with `/pa [arena] regions` +You can list existing arena regions with [`/pa [arena] regions`](commands/regions.md) ## Region Creation -All following commands assume you either have edit mode enabled or just one arena in place ! +*All following commands assume you either have edit mode enabled or just one arena in place.* + +Start creating an arena region with [`/pa region`](commands/region.md). -Start creating an arena region with `/pa !r` Now select a region by holding your arena wand (a STICK by default) and left click for position 1 and right click for position 2. Detailed information about the special region shapes, i.e. which points to select, check out the tutorial. -After selecting those points, use `/pa !r [regionname] [regionshape]` to save the region. -Region Shapes +After selecting those points, use [`/pa !r [regionname] [regionshape]`](commands/region.md) to save the region. -The following (self explanatory) region shapes exist: +The following region shapes exist: - CUBOID (default) - SPHERIC - CYLINDRIC -Of course, different shapes cover different areas. Note that a cylinder means a room like a can, so a standing cylinder. +Of course, different shapes cover different areas. Note that a cylinder means an area like a can, so a standing cylinder. -To remove a region, use `/pa region remove [regionname]` +To remove a region, use [`/pa !r [regionname] remove`](commands/region.md) ## Region Types -Set a region's type with `/pa !rt [regionname] [regiontype]` +Set a region's type with [`/pa !rt [regionname] [regiontype]`](commands/regiontype.md) The following Region Types exist: - CUSTOM (default) => does nothing -- WATCH => is the place where spectators should be, BattleFieldGuard will kick spectators not being part inside of one WATCH region -- LOUNGE => is the place where fighters select their class. It currently has no use, but might do in the future +- WATCH => the place where spectators should be, BattleFieldGuard will kick spectators not being part inside of one WATCH region +- LOUNGE => the place where fighters select their class. Required to allow players interactions in the lounge. - BATTLE => the most important type. It adds battlefield reservation (for overlapping arenas, only caring about that actually battle region), region protection, restoring and check if fighters are in the right place. - EXIT => the region where players should be after exiting the arena, no functionality atm - JOIN => the region where players should be when joining, see Configuration page, enforcement is disabled by default - SPAWN => a spawn region where players are randomly placed in when spawning or respawning -- BL_INV => blacklist inventory access -- WL_INV => whitelist inventory access +- BL_INV => block chest access to any team which name is included in the region name, same for classes +- WL_INV => restrict chest access to each team which name is included in the region name, same for classes + +#### Usage of BL_INV and WL_INV + +For these regions types, the name of the region is important. It is read by the plugin to understand access restrictions. + +Example: +* Region name is `RedBlueRanger` and region type is `WL_INV` => allows Red or Blue teams or Ranger class to access chests. +* Region name is `xxblueyy` and region type is `BL_INV`=> disallow chest access to the blue team ## Region Flags -Further customisation of region functionality with `/pa !rf [regionname] [regionflag]` +You can enable special player interactions with players by using regions flags. +Just use the command [`/pa !rf [regionname] [regionflag]`](commands/regionflags.md). + Those are valid Region Flags: - NOCAMP - players that don't move inside this region will be hurt @@ -52,7 +62,10 @@ Those are valid Region Flags: ## Region Protection -The BATTLE Region parses region protection flags (other regions can assigned protections, too, but atm they don't really use them). Set them via `/pa !p [regionname] [protection]` - you can add on, off, yes, no, true, false to specify a setting, or just as just told to toggle the state. Note that there is an "ALL" protection node that triggers/sets all protection nodes +The BATTLE Region parses region protection flags (other regions can assigned protections, too, but atm they don't +really use them). Set them via [`/pa !p [regionname] [protection]`](commands/protection.md) - you can add on, off, yes, +no, true, false to specify a setting, or just as just told to toggle the state. + Valid protections are: - BREAK - prevent player block breaking @@ -69,3 +82,7 @@ Valid protections are: - PICKUP - prevent player item pickup - TELEPORT - prevent player teleportation +Example: `/pa !p main break on` - disallow players to break blocks in "main" region of your arena + +> 🚩 **Tip:** +> There is an "ALL" protection argument that toggle all protections diff --git a/doc/update-checker.md b/doc/update-checker.md new file mode 100644 index 000000000..3c03d5b48 --- /dev/null +++ b/doc/update-checker.md @@ -0,0 +1,15 @@ +# Update Checker + +If you want you can be informed of plugin or modules updates. Each release version was pushed on github since 1.14.0. +The update checker will call the github APIs and announce an update to OPs on login. You can configure it to +automatically download updates. + +```yaml + update: + plugin: announce + modules: announce + # valid values: + # download: download updates and announce when update is installed + # announce: only announce, do not download + # everything else will disable the update check +``` diff --git a/readme.md b/readme.md index 37c5363a8..60a6bdcdf 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ *** [What is PVP Arena?](#What-is-PVP-Arena?) | [Dependencies](#Dependencies) | [Downloads](#Downloads) | -[Installation](#Installation) | [Documentation](#Documentation) | [Update Checker](#Update-Checker) | +[Installation](#Installation) | [Documentation](#Documentation) | [Support](#Support) | [Telemetry](#Telemetry) | [Credits](#Credits) ***
@@ -72,26 +72,21 @@ Place PVP Arena `.jar` file in the plugin repository of your server and restart. - [Regions](doc/regions.md) - [Goals](doc/goals.md) - [Modules](doc/modules.md) -- [Items](doc/items.md) +- [Items in config files](doc/items.md) - [Languages](doc/languages.md) - [Configuration](doc/configuration.md) +- [Update checker](doc/update-checker.md) +- [FAQ](doc/faq.md) *** -## Update Checker -If you wan't you can be informed of plugin or modules updates. Each release version was pushed on github since 1.14.0. -The update checker will call the github APIs and announce an update to OPs on login. You can configure it to -automatically download updates. - -```yaml - update: - plugin: announce - modules: announce - # valid values: - # download: download updates and announce when update is installed - # announce: only announce, do not download - # everything else will disable the update check -``` +## Support + +You can contact us to ask your questions or just discuss, you can go here: +- [Spigot Forums](https://www.spigotmc.org/threads/pvp-arena.113406/) +- [Discord server](https://discord.gg/KsXG2By) + +To report issues and make suggestion, please use our [Github issues page](https://github.com/Eredrim/pvparena/issues). *** From 8e44f3034b454114310f677a275a3107c77b75ff Mon Sep 17 00:00:00 2001 From: Eredrim Date: Fri, 14 Aug 2020 15:12:15 +0200 Subject: [PATCH 41/43] v1.15 - update bstats dependency --- pom.xml | 3 +-- src/net/slipcor/pvparena/PVPArena.java | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index ad8f4de22..c0b519f93 100644 --- a/pom.xml +++ b/pom.xml @@ -35,7 +35,7 @@ org.bstats bstats-bukkit - 1.5 + 1.7 compile @@ -81,7 +81,6 @@ org.bstats - net.slipcor.pvparena diff --git a/src/net/slipcor/pvparena/PVPArena.java b/src/net/slipcor/pvparena/PVPArena.java index 1ea210cde..54f419bbb 100644 --- a/src/net/slipcor/pvparena/PVPArena.java +++ b/src/net/slipcor/pvparena/PVPArena.java @@ -51,6 +51,7 @@ public class PVPArena extends JavaPlugin { public static PVPArena instance; private static Debug debugger; + private static final int BSTATS_PLUGIN_ID = 5067; private ArenaGoalManager agm; private ArenaModuleManager amm; @@ -372,7 +373,7 @@ public void onEnable() { debugger = new Debug(1); //Enable bStats - Metrics metrics = new Metrics(this); + Metrics metrics = new Metrics(this, BSTATS_PLUGIN_ID); saveDefaultConfig(); if (!getConfig().contains("shortcuts")) { From 0e30ff29418a47378469be5f61bc28276c629071 Mon Sep 17 00:00:00 2001 From: Eredrim Date: Fri, 14 Aug 2020 22:15:54 +0200 Subject: [PATCH 42/43] v1.15 - edit only the flag block in CTF when a flag is caught --- src/net/slipcor/pvparena/goals/GoalFlags.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/net/slipcor/pvparena/goals/GoalFlags.java b/src/net/slipcor/pvparena/goals/GoalFlags.java index d6f106994..ddb16dd35 100644 --- a/src/net/slipcor/pvparena/goals/GoalFlags.java +++ b/src/net/slipcor/pvparena/goals/GoalFlags.java @@ -333,9 +333,8 @@ public PACheck checkInteract(final PACheck res, final Player player, final Block } this.applyEffects(player); - this.takeFlag(new PABlockLocation(block.getLocation())); - this.getFlagMap().put(aTeam, player.getName()); // TODO move to - // "commit" ? + this.takeFlag(new PABlockLocation(vFlag.toLocation(block.getWorld()))); + this.getFlagMap().put(aTeam, player.getName()); return res; } From da985625a9da2b1d5ee44d03517b9df9b29e8c86 Mon Sep 17 00:00:00 2001 From: Eredrim Date: Sat, 15 Aug 2020 16:33:26 +0200 Subject: [PATCH 43/43] v1.15 - release --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c0b519f93..7977927a7 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ net.slipcor pvparena - 1.15.0-SNAPSHOT + 1.15.0 PVP Arena https://github.com/Eredrim/pvparena