diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..695b0e9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# We don't want to add the Eclipse files. +.project +.classpath + +# We can also do without .class files. +*.class + +# And we definitely don't need OS files. +.DS_Store* +Thumbs.db + +# Exclude some folders +bin/ +build/ +misc/ +lib/ +test/ +.settings/ \ No newline at end of file diff --git a/MobArena.jar b/MobArena.jar index 3d29c79..1ec76a8 100644 Binary files a/MobArena.jar and b/MobArena.jar differ diff --git a/README b/README.md similarity index 79% rename from README rename to README.md index 082487a..f2765b7 100644 --- a/README +++ b/README.md @@ -1,3 +1 @@ -(Project is currently on hold until I can find more time.) - Please read the [Wiki](https://github.com/garbagemule/MobArena/wiki/Installing-MobArena) for details on how to set up MobArena, and remember to read the [FAQ](https://github.com/garbagemule/MobArena/wiki/FAQ) before posting questions! diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..5dbcaa3 --- /dev/null +++ b/build.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/language files/cz/announcements.properties b/language files/cz/announcements.properties new file mode 100644 index 0000000..a2e961b --- /dev/null +++ b/language files/cz/announcements.properties @@ -0,0 +1,58 @@ +ARENA_START=Necht zacne masakr!|Arena zacala! +ARENA_END=Arena skoncila.|Arena skoncila. +ARENA_DOES_NOT_EXIST=Takova arena neexistuje. Napis /ma arenas pro seznam aren.|Arena nesla najit. +JOIN_NOT_ENABLED=Areny jsou v tuto chvili vypnute.|Areny nejsou zapnute. +JOIN_IN_OTHER_ARENA=Uz jsi v arene! Musis tuhle opustit nez pujdes do jine.|Jsi v jine arene. +JOIN_ARENA_NOT_ENABLED=Tato arena neni dostupna.|Tato arena je vypnuta. +JOIN_ARENA_NOT_SETUP=Tato arena jeste nebyla nastavena.|Arena neni nastavena. +JOIN_ARENA_EDIT_MODE=Tato arena se zrovna upravuje.|Arena se upravuje. +JOIN_ARENA_PERMISSION=Nemas opravneni ke vstupu do teto areny.|K tomuhle nemas opravneni! +JOIN_FEE_REQUIRED=Insufficient funds. Price: %|Price: % +JOIN_FEE_PAID=Price to join was: %|Paid: % +JOIN_ARENA_IS_RUNNING=Tato arena uz zacala, musis pockat az skonci.|Arena uz probiha, zkus to pozdeji! +JOIN_ALREADY_PLAYING=Uz hrajes!|Uz hrajes! +JOIN_ARG_NEEDED=Musis upresnit arenu. Napis /ma arenas pro seznam aren. +JOIN_TOO_FAR=YJsi prilis daleko od areny aby ses mohl pripojit/sledovat.|Prilis daleko od areny. +JOIN_EMPTY_INV=Musis si nejdriv vyprazdnit inventar.|Vyprazdni si inventar. +JOIN_PLAYER_LIMIT_REACHED=V arene je uz maximum hracu.|Uz nejsou volna mista. +JOIN_STORE_INV_FAIL=Tvuj inventar se nepodarilo ulozit. Zkus to znovu. +JOIN_EXISTING_INV_RESTORED=Tvuj inventar byl navracen. +JOIN_PLAYER_JOINED=Pridal ses do areny. Uzi si to!|Pridal ses do areny. +LEAVE_NOT_PLAYING=Nejsi v arene.|Nejsi v arene. +LEAVE_PLAYER_LEFT=Opustils arenu. Diky za boj!|Opustils arenu. +PLAYER_DIED=% zemrel!|% padl v boji! +SPEC_PLAYER_SPECTATE=Uzi si show!|Uzi si podivanou! +SPEC_NOT_RUNNING=Tato arena neprobiha.|Arena neprobiha. +SPEC_ARG_NEEDED=Musis upresnit arenu. Napis /ma arenas pro seznam aren.|Je pozadovano jmeno areny. +SPEC_EMPTY_INV=Musis si nejdriv vyprazdnit inventar.|Vyprazdni si inventar. +SPEC_ALREADY_PLAYING=Nemuzes byt divakem kdyz jsi bojovnikem!|Vzdyt uz bojujes! +NOT_READY_PLAYERS=Nepripraveni hraci: % +FORCE_START_RUNNING=Arena uz zacala. +FORCE_START_NOT_READY=Boj nemuze zacit, ani jeden hrac neni pripraveny. +FORCE_START_STARTED=Arena zacala, at se vam to libi nebo ne. +FORCE_END_EMPTY=V arene nikdo neni. +FORCE_END_ENDED=Arena ukoncena. +FORCE_END_IDLE=Nebyl jsi dost rychly! +REWARDS_GIVE=Tady jsou vsechyn tve odmeny! +LOBBY_DROP_ITEM=Ne ne ne, tady se o veci delit nesmi!|Veci se tu hazet nesmi. +LOBBY_PLAYER_READY=Jsi pripraven!|Jsi pripraven! +LOBBY_PICK_CLASS=Nejdriv si vyber typ bojovnika!|Vyber si typ bojovnika! +LOBBY_NOT_ENOUGH_PLAYERS=Tak malo bojovniku do areny nemuze. Je potreba alespon % hracu.|Je potreba vice bojovniku! +LOBBY_RIGHT_CLICK=Klikni levym, ne pravym.|Klikni levym. +LOBBY_CLASS_PICKED=Rozhodl ses, ze budes %!|% +LOBBY_CLASS_RANDOM=Na zacatku boje ti bude nahodne pridelen typ bojovnika. +LOBBY_CLASS_PERMISSION=Nemas opravneni byt timto typem bojovnika!|Smula, ale k tomu nemas opravneni! +WARP_TO_ARENA=Nemuzes se objevit v arene uprostred boje! +WARP_FROM_ARENA=Warping not allowed in the arena! +Vlna_DEFAULT=Vlna #%!|Vlna #%! +Vlna_SPECIAL=Vlna #%! [SPECIAL]|Vlna #%! [SPECIAL] +Vlna_SWARM=Vlna #%! [SWARM]|Vlna #%! [SWARM] +Vlna_BOSS=Vlna #%! [BOSS]|Vlna #%! [BOSS] +Vlna_BOSS_ABILITY=Boss pouzil schopnost: %!|Boss: % +Vlna_BOSS_LOW_HEALTH=Boss je temer mrtvy!|Bossovi uz nezbyva moc zivota! +Vlna_REWARD=Ziskal jsi tuto odmenu: %|Byl jsi odmenen: % +MISC_LIST_PLAYERS=Bojovnici stale na nohou: % +MISC_LIST_ARENAS=Dostupne areny: % +MISC_COMMAND_NOT_ALLOWED=Tenhle prikaz v arene pouzit nemuzes! +MISC_NO_ACCESS=K tomuto prikazu nemas pristup. +MISC_NONE= diff --git a/language files/da/announcements.properties b/language files/da/announcements.properties new file mode 100644 index 0000000..42d61f2 --- /dev/null +++ b/language files/da/announcements.properties @@ -0,0 +1,51 @@ +ARENA_START=Lad massakren begynde! +ARENA_END=Arena slut. +ARENA_DOES_NOT_EXIST=Arenaen findes ikke. Skriv /ma arenas for en liste. +JOIN_PLAYER_JOINED=Du joinede arenaen! +JOIN_NOT_ENABLED=MobArena er ikke aktiveret. +JOIN_IN_OTHER_ARENA=Du er allerede i en arena. Forlad den først. +JOIN_ARENA_NOT_ENABLED=Arenaen er deaktiveret. +JOIN_ARENA_NOT_SETUP=Arenaen er ikke blevet sat op endnu. +JOIN_ARENA_PERMISSION=Du har ikke rettigheder til den arena! +JOIN_FEE_REQUIRED=Du er for fattig. Pris: % +JOIN_FEE_PAID=Prisen for at joine var: % +JOIN_ARENA_IS_RUNNING=Arenaen er allerede startet. +JOIN_ALREADY_PLAYING=Du spiller allerede! +JOIN_ARG_NEEDED=Arenanavn påkrævet. Skriv /ma arenas for en liste. +JOIN_TOO_FAR=Du er for langt fra denne arena til at kunne joine. +JOIN_EMPTY_INV=Du skal tømme dit inventory før du kan joine arenaen. +JOIN_PLAYER_LIMIT_REACHED=Der kan ikke være flere spillere i arenaen. +JOIN_STORE_INV_FAIL=Kunne ikke gemme dit inventory. Prøv igen. +LEAVE_PLAYER_LEFT=Du forlod arenaen. +LEAVE_NOT_PLAYING=Du er ikke i en arena. +PLAYER_DIED=% døde! +SPEC_PLAYER_SPECTATE=Nyd forestillingen! +SPEC_NOT_RUNNING=Arenaen er ikke startet. +SPEC_ARG_NEEDED=Arenanavn påkrævet. Skriv /ma arenas for en liste. +SPEC_EMPTY_INV=Du skal tømme dit inventory først. +SPEC_ALREADY_PLAYING=Du spiller allerede! +NOT_READY_PLAYERS=Ikke klar: % +FORCE_START_STARTED=Arena tvunget til at starte. +FORCE_START_RUNNING=Arenaen er allerede startet. +FORCE_START_NOT_READY=Ingen spillere er klar. +FORCE_END_ENDED=Arena tvunget til at slutte. +FORCE_END_EMPTY=Der er ingen i arenaen. +FORCE_END_IDLE=Du var ikke hurtig nok! +REWARDS_GIVE=Her er alle dine præmier! +LOBBY_CLASS_PICKED=Du har valgt % som din klasse! +LOBBY_CLASS_RANDOM=Du får tildelt en klasse ved arena start. +LOBBY_CLASS_PERMISSION=Du har ikke rettigheder til den klasse! +LOBBY_PLAYER_READY=Du er markeret som klar! +LOBBY_DROP_ITEM=Du kan ikke dele items i lobbyen! +LOBBY_PICK_CLASS=Du skal først vælge en klasse! +LOBBY_RIGHT_CLICK=Slå skiltene; ikke højre-klik. +WARP_TO_ARENA=Du kan ikke warpe til arenaen efter, den er startet. +WARP_FROM_ARENA=Du kan ikke warpe fra arenaen. +WAVE_DEFAULT=Bølge #%! +WAVE_SPECIAL=Bølge #%! [SPECIEL] +WAVE_REWARD=Du har lige vundet en præmie: % +MISC_LIST_ARENAS=Tilgængelige arenaer: % +MISC_LIST_PLAYERS=Levende spillere: % +MISC_COMMAND_NOT_ALLOWED=Du kan ikke bruge den kommando i arenaen. +MISC_NO_ACCESS=Du har ikke adgang til den kommando. +MISC_NONE= diff --git a/language files/de/announcements.properties b/language files/de/announcements.properties new file mode 100644 index 0000000..04993f3 --- /dev/null +++ b/language files/de/announcements.properties @@ -0,0 +1,53 @@ +ARENA_START=Lasst die Spiele beginnen +ARENA_END=Arena beendet +ARENA_DOES_NOT_EXIST=Diese Arena existiert nicht tippe /ma um alle Arenen anzuzeigen. +JOIN_PLAYER_JOINED=Du bist nun in der Arena. +Viel Spass! +JOIN_NOT_ENABLED=Die Mobarena wurde deaktiviert +JOIN_IN_OTHER_ARENA=Du bist momentan in einer Arena, verlasse diese jetzt. +JOIN_ARENA_NOT_ENABLED=Diese Arena ist nicht aktiviert. +JOIN_ARENA_NOT_SETUP=Diese Arena wurde noch nicht eingerichtet. +JOIN_ARENA_PERMISSION=Du bist nicht berechtigt diese Arena zu betretten. +JOIN_FEE_REQUIRED=Ungenügender Kontostand. Preis: % +JOIN_FEE_PAID=Der Preis um bei zu tretten: % +JOIN_ARENA_IS_RUNNING=Der Kampf in dieser Arena ist bereits zu gange. +JOIN_ALREADY_PLAYING=Du spielst bereits! +JOIN_ARG_NEEDED=Du must den Namen der Arena eingeben. Gib /ma arenas ein für eine Liste. +JOIN_TOO_FAR=Du bist zu weit weg um bei zu tretten oder zu zuschauen. +JOIN_EMPTY_INV=Du must dein Inventar leeren um der Arena bei zu tretten. +JOIN_PLAYER_LIMIT_REACHED=Die Spieler Limite ist erreicht. +JOIN_STORE_INV_FAIL=Momentan nicht möglich dein Inventar zu speichern. Probiere es noch einmal. +LEAVE_PLAYER_LEFT=Du hast die Arena verlassen. Vielen Dank fürs Spielen! +LEAVE_NOT_PLAYING=Du kannst die Arena nicht verlassen wenn du nich in der Arena bist! Du Depp. +PLAYER_DIED=% ist gestorben! +SPEC_PLAYER_SPECTATE=Amüsier dich am Kampf! +SPEC_NOT_RUNNING=Diese Arena läuft im Moment nicht. +SPEC_ARG_NEEDED=Du must den Namen der Arena eingeben. Gib /ma arenas ein für eine Liste. +SPEC_EMPTY_INV=Du must dein Inventar leeren um der Arena bei zu tretten! +SPEC_ALREADY_PLAYING=Du kannst dir nicht selber zuschauen wie du kämpfst! +NOT_READY_PLAYERS=Noch nicht bereit sind: % +FORCE_START_STARTED=Gezwungener Start des Kampfes. +FORCE_START_RUNNING=Die Arena wurde bereits gestartet. +FORCE_START_NOT_READY=Kann den Start des Kampfes nicht erzwingen, keine Spieler vorhanden. +FORCE_END_ENDED=Gezwunges Kampf Ende. +FORCE_END_EMPTY=Niemand ist in der Arena. +FORCE_END_IDLE=Du warst nicht schnell genug! +REWARDS_GIVE=Hier sind deine Preise! +LOBBY_CLASS_PICKED=Du hast % als deine Kampfklasse gewählt! +LOBBY_CLASS_RANDOM=Du wirst beim Start des Spiels einer zufälligen Kampfklasse zugeortnet. +LOBBY_CLASS_PERMISSION=Du hast keine Berechtigung diese Kampfklasse zu wählen! +LOBBY_NOT_ENOUGH_PLAYERS=Nicht genung Spieler um den Kampf zu starten. Es benötigt mindestens % Spieler. +LOBBY_PLAYER_READY=Du hast dich als bereit gemeldet! +LOBBY_DROP_ITEM=Du darfts momentant deine Tools nicht an andere weitergeben! +LOBBY_PICK_CLASS=Du must zuerst eine Kampfklasse auswählen! +LOBBY_RIGHT_CLICK=Du must das Schild schlagen. Nicht rechtsklicken. +WARP_TO_ARENA=Du kannst dich jetzt nich in die Arena teleportieren! +WARP_FROM_ARENA=Du darfst dich jetzt nicht aus der Arena teleportiern! +WAVE_DEFAULT=Sei bereit für die %. Welle! +WAVE_SPECIAL=Mach dich für eine spezielle %. Welle bereit! +WAVE_REWARD=Du hast einen Preis: % +MISC_LIST_ARENAS=Verfügbare Arenas: % +MISC_LIST_PLAYERS=Live Spieler: % +MISC_COMMAND_NOT_ALLOWED=Du darfst diesen Befehl nicht in der Arena benutzen! +MISC_NO_ACCESS=Du hast keinen Zugriff auf diesen Befehl. +MISC_NONE= diff --git a/language files/fr/announcements.properties b/language files/fr/announcements.properties new file mode 100644 index 0000000..6f2b9d3 --- /dev/null +++ b/language files/fr/announcements.properties @@ -0,0 +1,51 @@ +ARENA_START=Que le massacre commence ! +ARENA_END=L'arène est terminée. +ARENA_DOES_NOT_EXIST=Cette arène n'existe pas. Entrez "/ma arenas" pour la liste. +JOIN_PLAYER_JOINED=Vous avez rejoint l'arène. Prennez plaisir ! +JOIN_NOT_ENABLED=MobArena n'est pas actif. +JOIN_IN_OTHER_ARENA=Vous êtes déjà dans l'arène! Quittez-la avant. +JOIN_ARENA_NOT_ENABLED=Cetta arène n'est pas active. +JOIN_ARENA_NOT_SETUP=Cette arène n'a pas encore été configurée. +JOIN_ARENA_PERMISSION=Vous n'avez pas la permission pour rejoindre cette arène. +JOIN_FEE_REQUIRED=Pas assez d'argent. Prix: % +JOIN_FEE_PAID=Le prix pour rejoindre était de: % +JOIN_ARENA_IS_RUNNING=L'arène est déjà occupée. +JOIN_ALREADY_PLAYING=Vous êtes déjà en train de jouer. +JOIN_ARG_NEEDED=Vous devez spécifier une arène. Entrez "/ma arenas" pour la liste. +JOIN_TOO_FAR=Vous êtes trop loins de l'arène pour pouvoir joindre en tant que joueur ou specateur. +JOIN_EMPTY_INV=Vous devez vider votre inventaire afin de joindre l'arène. +JOIN_PLAYER_LIMIT_REACHED=La limite de joueur pour cette arène a été atteinte. +JOIN_STORE_INV_FAIL=La sauvegarde de l'inventaire a échouée. Essayez encore. +LEAVE_PLAYER_LEFT=Vous avez quitté l'arène. Merci d'avoir joué ! +LEAVE_NOT_PLAYING=Vous n'êtes pas dans l'arène. +PLAYER_DIED=% est mort ! +SPEC_PLAYER_SPECTATE=Profitez bien du spectacle ! +SPEC_NOT_RUNNING=Cette arène n'est pas en cours. +SPEC_ARG_NEEDED=Vous devez spécifier une arène. Entrez "/ma arenas" pour la liste. +SPEC_EMPTY_INV=Vous devez vider votre inventaire. +SPEC_ALREADY_PLAYING=Vous ne pouvez pas être spectateur en tant que joueur de l'arène ! +NOT_READY_PLAYERS=Non prêt: % +FORCE_START_STARTED=Début forcé de l'arène. +FORCE_START_RUNNING=L'arène a commencée. +FORCE_START_NOT_READY=Ne peut pas forcer le début, il n'y a pas de joueurs prêts. +FORCE_END_ENDED=Fin forcée de l'arène. +FORCE_END_EMPTY=Il n'y a personne dans l'arène. +FORCE_END_IDLE=Vous n'avez pas été assez rapide ! +REWARDS_GIVE=Voici vos récompenses ! +LOBBY_CLASS_PICKED=Vous avez choisi % comme classe ! +LOBBY_CLASS_RANDOM=Une classe aléatoire va vous être attribuée. +LOBBY_CLASS_PERMISSION=Vous n'avez pas les permissions pour utiliser cette classe ! +LOBBY_PLAYER_READY=Vous avez été marqué comme prêt ! +LOBBY_DROP_ITEM=Pas de partage avant le début de l'arène ! +LOBBY_PICK_CLASS=Vous devez d'abord choisir une classe ! +LOBBY_RIGHT_CLICK=Vous devez frapper le panneau, pas cliquer du droit dessus. +WARP_TO_ARENA=Vous ne pouvez pas vous téléporter à l'arène pendant la bataille ! +WARP_FROM_ARENA=La téléportation est interdite dans l'arène ! +WAVE_DEFAULT=Soyez prêt pour la vague #% ! +WAVE_SPECIAL=Soyez prêt pour la vague #% ! [SPECIALE] +WAVE_REWARD=Vous avez gagné une récompense: % +MISC_LIST_ARENAS=Les arènes disponibles: % +MISC_LIST_PLAYERS=Les joueurs en live: % +MISC_COMMAND_NOT_ALLOWED=Vous ne pouvez pas utiliser cette commande dans l'arène ! +MISC_NO_ACCESS=Vous n'avez pas accès à cette commande. +MISC_NONE= diff --git a/language files/nl/announcements.properties b/language files/nl/announcements.properties new file mode 100644 index 0000000..64b86b5 --- /dev/null +++ b/language files/nl/announcements.properties @@ -0,0 +1,52 @@ +ARENA_START=Laat de slachting beginnen! +ARENA_END=Arena voltooid. +ARENA_DOES_NOT_EXIST=Die arena bestaat niet. Typ /ma arenas voor een lijst. +JOIN_PLAYER_JOINED=U heeft toegetreden tot deze arena. Veel plezier! +JOIN_NOT_ENABLED=MobArena staat niet aan. +JOIN_IN_OTHER_ARENA=U bevindt zich al in een arena! Vertaal die eerst. +JOIN_ARENA_NOT_ENABLED=Deze arena staat niet aan. +JOIN_ARENA_PERMISSION=U heeft geen permissie om deze arena toe te treden. +JOIN_ARENA_NOT_SETUP=Deze arena is nog niet ingesteld. +JOIN_FEE_REQUIRED=Onvoldoende geld. Prijs: % +JOIN_FEE_PAID=Prijs om toe te treden is: % +JOIN_ARENA_IS_RUNNING=Deze arena is al bezig. +JOIN_ALREADY_PLAYING=U bent al aan het spelen! +JOIN_ARG_NEEDED=U moet een arena specificeren. Typ /ma arenas voor een lijst. +JOIN_TOO_FAR=U bent te ver weg van de arena om toe te treden/toe te kijken. +JOIN_EMPTY_INV=U moet uw inventaris eerst legen om toe te treden tot deze arena. +JOIN_PLAYER_LIMIT_REACHED=De speler limiet van deze arena is berijkt. +JOIN_STORE_INV_FAIL=Inventaris opslaan mislukt. Probeer het opnieuw. +LEAVE_PLAYER_LEFT=U verliet de arena. Bedankt voor het spelen! +LEAVE_NOT_PLAYING=U bent niet in de arena. +PLAYER_DIED=% ging dood! +SPEC_PLAYER_SPECTATE=Geniet van de show! +SPEC_NOT_RUNNING=Deze arena is niet actief. +SPEC_ARG_NEEDED=U moet een arena specificeren. Typ /ma arenas voor een lijst. +SPEC_EMPTY_INV=Leeg uw inventaris eerst! +SPEC_ALREADY_PLAYING=Kan niet toekijken als je in de arena zit! +NOT_READY_PLAYERS=Niet klaar: % +FORCE_START_STARTED=Geforceerd arena te starten. +FORCE_START_RUNNING=Arena is al begonnen. +FORCE_START_NOT_READY=Kan arena niet geforceerd starten, geen spelers zijn klaar. +FORCE_END_ENDED=Geforceerd arena te beëindigen. +FORCE_END_EMPTY=Niemand is in deze arena. +FORCE_END_IDLE=U was niet snel genoeg! +REWARDS_GIVE=Hier zijn al uw beloningen! +LOBBY_CLASS_PICKED=U heeft % gekozen als uw klasse! +LOBBY_CLASS_RANDOM=U krijgt een willekeurige klasse als de arena start. +LOBBY_CLASS_PERMISSION=U heeft geen permissie om deze klasse te gebruiken! +LOBBY_NOT_ENOUGH_PLAYERS=Niet genoeg spelers om te beginnen. Op zijn minst % spelers nodig. +LOBBY_PLAYER_READY=U bent gemarkeerd als klaar! +LOBBY_DROP_ITEM=Delen niet toegestaan ​​op dit moment! +LOBBY_PICK_CLASS=U moet eerst een klasse kiezen! +LOBBY_RIGHT_CLICK=Sla het bord. Geen klik met de rechtermuisknop. +WARP_TO_ARENA=Kan niet teleporteren naar een arena tijdens een gevecht! +WARP_FROM_ARENA=Teleporteren niet toegestaan ​​in de arena! +WAVE_DEFAULT=Maak U klaar voor golf #%! +WAVE_SPECIAL=Maak U klaar voor golf #%! [SPECIAAL] +WAVE_REWARD=U heeft zojuist een beloning verdiend: % +MISC_LIST_ARENAS=Beschikbare arenas: % +MISC_LIST_PLAYERS=Live spelers: % +MISC_COMMAND_NOT_ALLOWED=U kan dit commando niet gebruiken in de arena! +MISC_NO_ACCESS=U heeft geen toegang tot dit commando. +MISC_NONE= \ No newline at end of file diff --git a/language files/pirate/announcements.properties b/language files/pirate/announcements.properties new file mode 100644 index 0000000..0afaf05 --- /dev/null +++ b/language files/pirate/announcements.properties @@ -0,0 +1,51 @@ +ARENA_START=Hearts alive, men! +ARENA_END=Land ho! +ARENA_DOES_NOT_EXIST=Thar be no ship by that name! +JOIN_PLAYER_JOINED=Ahoy, matey! +JOIN_NOT_ENABLED=We be swabbing down the decks on all ships, matey. +JOIN_IN_OTHER_ARENA=Ye're already at sea, scallywag! +JOIN_ARENA_NOT_ENABLED=We be swabbing down the decks on this ship, matey. +JOIN_ARENA_NOT_SETUP=Arrrgh! We be missing the top sail! +JOIN_ARENA_PERMISSION=Arrgh! Ye can't board this ship, scurvy dog! +JOIN_FEE_REQUIRED=Ye don't own enough doubloons, matey! Price: % +JOIN_FEE_PAID=Booty ye gave up to join: % +JOIN_ARENA_IS_RUNNING=That ship has sailed, landlubber! +JOIN_ALREADY_PLAYING=Ye be aboard already, ye scurvy dog! +JOIN_ARG_NEEDED=Which ship are ye boarding? Type /ma arenas for a list, arrgh! +JOIN_TOO_FAR=Ye be too far from the docks, landlubber! +JOIN_EMPTY_INV=Throw ye belongings overboard, scallywag! +JOIN_PLAYER_LIMIT_REACHED=Thar be too many men aboard this ship already, landlubber! +JOIN_STORE_INV_FAIL=Ye belongings didn't fit in the storage deck, arrgh! +LEAVE_PLAYER_LEFT=Ye abandonned the ship! Arrrgh! +LEAVE_NOT_PLAYING=Ye're already on land, matey! +PLAYER_DIED=% walked the plank! +SPEC_PLAYER_SPECTATE=Welcome to the Crow's Nest! Grab ye spyglass! +SPEC_NOT_RUNNING=Thar be no one aboard that ship! +SPEC_ARG_NEEDED=Which ship are ye boarding? Type /ma arenas for a list, arrgh! +SPEC_EMPTY_INV=Throw ye belongings overboard, scallywag! +SPEC_ALREADY_PLAYING=Ye don't need ye spyglass aboard this ship, harr! +NOT_READY_PLAYERS=Landlubbers: % +FORCE_START_STARTED=Set sail! +FORCE_START_RUNNING=The ship has already set sail! +FORCE_START_NOT_READY=Thar be no scurvy dogs ready to set sail! +FORCE_END_ENDED=Forced the men to walk the plank! +FORCE_END_EMPTY=Thar be no one aboard the ship! +FORCE_END_IDLE=Arrrgh! Too slow, matey! +REWARDS_GIVE=Here's ye booty, seadog! +LOBBY_CLASS_PICKED=Ye be the %! +LOBBY_CLASS_RANDOM= +LOBBY_CLASS_PERMISSION=Ye can't use that cutlass, scurvy dog! +LOBBY_PLAYER_READY=Ready to sail! Arrrgh! +LOBBY_DROP_ITEM=Don't be sharing ye rum yet, scallywag! +LOBBY_PICK_CLASS=Grab ye cutlass first, matey! +LOBBY_RIGHT_CLICK=Ye can't be right-clickin', landlubber. +WARP_TO_ARENA=Ye can't board this ship, wench! +WARP_FROM_ARENA=Walk the plank if ye want to leave, arrrgh! +WAVE_DEFAULT=Wave %: Blow them all down! +WAVE_SPECIAL=Wave %: Thar she blows! +WAVE_REWARD=Ye earned yerself some booty: % +MISC_LIST_ARENAS=Ships: % +MISC_LIST_PLAYERS=Buccaneers: % +MISC_COMMAND_NOT_ALLOWED=Ye can't be usin' that command on the ship, landlubber! +MISC_NO_ACCESS=Only the captain uses these commands, wench! +MISC_NONE= diff --git a/resources/plugin.yml b/resources/plugin.yml index eab0b29..c4ceb5c 100644 --- a/resources/plugin.yml +++ b/resources/plugin.yml @@ -1,7 +1,8 @@ name: MobArena +author: garbagemule main: com.garbagemule.MobArena.MobArena -version: 0.94.4.4 -softdepend: [Spout,Permissions,MultiVerse,XcraftGate,Towny,Heroes,MagicSpells] +version: 0.94.4.49 +softdepend: [Spout,MultiVerse,XcraftGate,Towny,Heroes,MagicSpells,Vault] commands: ma: description: Base command for MobArena @@ -18,18 +19,20 @@ commands: http://pastebin.com, and then paste the link in the IRC or on the forums. permissions: - mobarena.use: - description: Gives access to usage commands - default: true - children: - mobarena.use.join: true - mobarena.use.spec: true - mobarena.use.leave: true mobarena.use.join: + description: Join command default: true mobarena.use.spec: + description: Spec command default: true mobarena.use.leave: + description: Leave command + default: true + mobarena.use.arenalist: + description: Arena list command + default: true + mobarena.use.playerlist: + description: Arena list command default: true mobarena.admin: @@ -39,9 +42,8 @@ permissions: mobarena.admin.enable: true mobarena.admin.kick: true mobarena.admin.restore: true - mobarena.admin.force.end: true - mobarena.admin.force.start: true - mobarena.admin.config.reload: true + mobarena.admin.force: true + mobarena.admin.teleport: true mobarena.admin.enable: description: Enable and disable MobArena and/or arenas. default: false @@ -51,14 +53,11 @@ permissions: mobarena.admin.restore: description: Restore a player's inventory. default: false - mobarena.admin.force.end: - description: Force end an arena. + mobarena.admin.force: + description: Force start or end an arena. default: false - mobarena.admin.force.start: - description: Force start an arena. - default: false - mobarena.admin.config.reload: - description: Reload the config-file. + mobarena.admin.teleport: + description: Immune to teleport blocking rules. default: false mobarena.setup: @@ -68,7 +67,7 @@ permissions: mobarena.setup.arena: true mobarena.setup.setarena: true mobarena.setup.addarena: true - mobarena.setup.delarena: true + mobarena.setup.removearena: true mobarena.setup.protect: true mobarena.setup.editarena: true mobarena.setup.setregion: true @@ -78,13 +77,11 @@ permissions: mobarena.setup.expandlobbyregion: true mobarena.setup.setwarp: true mobarena.setup.spawnpoints: true - mobarena.setup.addspawn: true - mobarena.setup.delspawn: true mobarena.setup.containers: true - mobarena.setup.addcontainer: true - mobarena.setup.delcontainer: true mobarena.setup.leaderboards: true mobarena.setup.checkdata: true + mobarena.setup.classes: true + mobarena.setup.config: true mobarena.setup.autogenerate: true mobarena.setup.autodegenerate: true mobarena.setup.arena: @@ -96,8 +93,8 @@ permissions: mobarena.setup.addarena: description: Add a new arena node. default: false - mobarena.setup.delarena: - description: Delete an arena. + mobarena.setup.removearena: + description: Remove an arena. default: false mobarena.setup.protect: description: Turn arena protection on/off. @@ -126,27 +123,21 @@ permissions: mobarena.setup.spawnpoints: description: List all spawnpoints. default: false - mobarena.setup.addspawn: - description: Add a new spawnpoint. - default: false - mobarena.setup.delspawn: - description: Delete a spawnpoint. - default: false mobarena.setup.containers: description: List all containers. default: false - mobarena.setup.addcontainer: - description: Add a new container. - default: false - mobarena.setup.delcontainer: - description: Delete a container. - default: false mobarena.setup.leaderboards: description: Set up leaderboards. default: false mobarena.setup.checkdata: description: Check which points need to be set up. default: false + mobarena.setup.classes: + description: Allows setting up classes from in-game + default: false + mobarena.setup.config: + description: Save or reload the config-file + default: false mobarena.setup.autogenerate: description: Auto-generate an arena. default: false diff --git a/resources/res/classes.yml b/resources/res/classes.yml new file mode 100644 index 0000000..d9c6bf4 --- /dev/null +++ b/resources/res/classes.yml @@ -0,0 +1,15 @@ +Knight: + items: diamond_sword, potion:8197:3 + armor: 306,307,308,309 +Tank: + items: iron_sword, potion:8229:2 + armor: 310,311,312,313 +Archer: + items: wood_sword, bow, arrow:256, potion:8197:3, bone + armor: 298,299,300,301 +Chemist: + items: stone_sword, potion:16428:30, potion:16388:8, potion:16389:20, potion:8197:3, potion:8226:1 + armor: 314,315,316,317 +Oddjob: + items: stone_sword, flint_and_steel, netherrack:2, tnt:4, potion:8197:3 + armor: 298,299,300,301 \ No newline at end of file diff --git a/resources/res/config.yml b/resources/res/config.yml index 02c8644..f8ac1a9 100644 --- a/resources/res/config.yml +++ b/resources/res/config.yml @@ -1,113 +1,4 @@ -### MobArena Configuration File -### Please visit the MobArena Wiki here: http://goo.gl/F5TTc for more details -### on how to set up this file. -### Note that you CAN'T use tabs in this file! Always use spaces! - -### GLOBAL SETTINGS -# These settings are arena-independent and count in all arenas. Note that if -# enabled: false in the global settings, MobArena is disabled globally, and -# arena-specific enabled-values do not matter. If true, however, the per-arena -# enabled-values count. -global-settings: - enabled: true - allowed-commands: /list, /pl - update-notification: true - -### CLASS SETUP -# Items can be written as either their data value (numbers) or their Material -# type (names); check the Wiki for links to lists of both. -# The notation is :. If no amount is given, 1 is assumed. Sub- -# types can be created -# Item SUBTYPES (wool/dye colors) are written as ::, -# but here, the amount is REQUIRED, even if it is just 1. -# Note: If you want to specify only one item, but apostrophes around that one -# item, e.g.: items: '278' -# Note: For every bone a class has, one PET WOLF will spawn upon arena start, -# which will assist the player in the arena session. -classes: - Knight: - items: diamond_sword, grilled_pork:2 - armor: 306,307,308,309 - Tank: - items: iron_sword, grilled_pork:3, apple - armor: 310,311,312,313 - Archer: - items: wood_sword, bow, arrow:256, grilled_pork, bone - armor: 298,299,300,301 - Chef: - items: stone_sword, bread:6, grilled_pork:4, mushroom_soup, cake:5 - armor: 314,315,316,317 - Oddjob: - items: stone_sword, flint_and_steel, netherrack:2, tnt:4, pork:3 - armor: 298,299,300,301 - -### ARENA SETUP -# The arena setup is split into 4 different sections per arena: settings, -# waves, rewards and coords (not shown until coords are set up). -# Please refer to the Wiki for descriptions of all these settings. -# Note: The REWARDS use the same notation as the items in the CLASS SETUP -# section. However, only -one- item from the list is picked (at random) when -# the rewards are given. -arenas: - default: - settings: - world: '' - enabled: true - protect: true - entry-fee: '' - logging: true - clear-wave-before-next: false - detonate-creepers: false - detonate-damage: false - lightning: true - auto-equip-armor: true - force-restore: false - soft-restore: false - soft-restore-drops: false - require-empty-inv-join: false - require-empty-inv-spec: false - hellhounds: false - pvp-enabled: false - monster-infight: false - allow-teleporting: false - spectate-on-death: true - share-items-in-arena: true - min-players: 0 - max-players: 0 - max-join-distance: 0 - repair-delay: 5 - first-wave-delay: 5 - wave-interval: 20 - special-modulo: 4 - max-idle-time: 0 - waves: - recurrent: - def1: - type: default - priority: 1 - frequency: 1 - monsters: - zombies: 10 - skeletons: 10 - spiders: 10 - creepers: 10 - wolves: 10 - spec1: - type: special - priority: 2 - frequency: 4 - monsters: - powered-creepers: 10 - zombie-pigmen: 10 - angry-wolves: 10 - humans: 10 - rewards: - waves: - every: - '3': feather, bone, stick - '5': dirt:4, gravel:4, stone:4 - '10': iron_ingot:10, gold_ingot:8 - after: - '7': minecart, storage_minecart, powered_minecart - '13': iron_sword, iron_pickaxe, iron_spade - '16': diamond_sword \ No newline at end of file +# Layout +global-settings: {} +classes: {} +arenas: {} \ No newline at end of file diff --git a/resources/res/global-settings.yml b/resources/res/global-settings.yml new file mode 100644 index 0000000..146e44b --- /dev/null +++ b/resources/res/global-settings.yml @@ -0,0 +1,3 @@ +enabled: true +allowed-commands: /list, /pl +update-notification: true \ No newline at end of file diff --git a/resources/res/magicspells.yml b/resources/res/magicspells.yml index 996d8fb..b33693e 100644 --- a/resources/res/magicspells.yml +++ b/resources/res/magicspells.yml @@ -1,17 +1,16 @@ -# MobArena disabled MagicSpells spells +# MobArena disabled MagicSpells spells # Use this file to disable the MagicSpells spells you don't want your players # to use during arena sessions. Make sure to put a hyphen (-) before every # spell, and try to keep the indentation proper. - # Spells that will be disabled for the entire arena session. disabled-spells: - carpet - blink # Spells that will be disabled only while a boss is present. -disabled-only-on-bosses: +disabled-on-bosses: - purge # Spells that will be disabled only during swarm waves. -disabled-only-on-swarms: +disabled-on-swarms: - purge \ No newline at end of file diff --git a/resources/res/rewards.yml b/resources/res/rewards.yml new file mode 100644 index 0000000..ef24487 --- /dev/null +++ b/resources/res/rewards.yml @@ -0,0 +1,9 @@ +waves: + every: + '3': feather, bone, stick + '5': dirt:4, gravel:4, stone:4 + '10': iron_ingot:10, gold_ingot:8 + after: + '7': minecart, storage_minecart, powered_minecart + '13': iron_sword, iron_pickaxe, iron_spade + '16': diamond_sword \ No newline at end of file diff --git a/resources/res/settings.yml b/resources/res/settings.yml new file mode 100644 index 0000000..a93c5f7 --- /dev/null +++ b/resources/res/settings.yml @@ -0,0 +1,33 @@ +world: '' +enabled: true +protect: true +logging: true +entry-fee: '' +clear-wave-before-next: false +clear-boss-before-next: false +lightning: true +auto-equip-armor: true +soft-restore: false +soft-restore-drops: false +require-empty-inv-join: false +require-empty-inv-spec: false +hellhounds: false +pvp-enabled: false +monster-infight: false +allow-teleporting: false +spectate-on-death: true +auto-respawn: true +share-items-in-arena: true +min-players: 0 +max-players: 0 +max-join-distance: 0 +first-wave-delay: 5 +wave-interval: 15 +final-wave: 0 +monster-limit: 100 +monster-exp: false +keep-exp: true +food-regen: false +lock-food-level: true +spout-class-select: false +player-time-in-arena: world \ No newline at end of file diff --git a/resources/res/waves.yml b/resources/res/waves.yml new file mode 100644 index 0000000..ea946e3 --- /dev/null +++ b/resources/res/waves.yml @@ -0,0 +1,32 @@ +recurrent: + def1: + type: default + priority: 1 + frequency: 1 + monsters: + zombies: 10 + skeletons: 10 + spiders: 10 + creepers: 10 + wolves: 10 + spec1: + type: special + priority: 2 + frequency: 4 + monsters: + powered-creepers: 10 + zombie-pigmen: 10 + angry-wolves: 10 + blazes: 10 +single: + swarm1: + type: swarm + wave: 6 + monster: slime + amount: low + boss1: + type: boss + wave: 10 + monster: cave_spider + health: high + abilities: arrows, root-target, throw-nearby \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/Arena.java b/src/com/garbagemule/MobArena/Arena.java deleted file mode 100644 index d5fcc2e..0000000 --- a/src/com/garbagemule/MobArena/Arena.java +++ /dev/null @@ -1,302 +0,0 @@ -package com.garbagemule.MobArena; - -import java.util.*; -import java.util.concurrent.PriorityBlockingQueue; - -import org.bukkit.Bukkit; -import org.bukkit.GameMode; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.entity.Wolf; -import org.bukkit.inventory.ItemStack; -import org.bukkit.permissions.PermissionAttachment; -//import org.bukkit.util.config.Configuration; - -import com.garbagemule.MobArena.leaderboards.Leaderboard; -import com.garbagemule.MobArena.repairable.Repairable; -import com.garbagemule.MobArena.repairable.RepairableComparator; -import com.garbagemule.MobArena.util.Config; -import com.garbagemule.MobArena.waves.BossWave; -import com.garbagemule.MobArena.waves.Wave; - -public abstract class Arena -{ - private MobArena plugin; - - // Setup fields - protected String name; - protected World world; - protected boolean enabled, protect, running, setup, lobbySetup, autoEquip, forceRestore, softRestore, softRestoreDrops, emptyInvJoin, emptyInvSpec, pvp, monsterInfight, allowWarp; - - protected boolean edit, waveClear, detCreepers, detDamage, lightning, hellhounds, specOnDeath, shareInArena, spoutSelect; - protected Location p1, p2, l1, l2, arenaLoc, lobbyLoc, spectatorLoc; - protected Map spawnpoints, spawnpointsBoss, containers; - protected String logging; - - // Wave/reward/entryfee fields - protected int spawnTaskId, sheepTaskId, waveDelay, waveInterval, specialModulo, spawnMonstersInt, maxIdleTime, finalWave; - protected MASpawnThread spawnThread; - protected Map> everyWaveMap, afterWaveMap; - protected Map classMap; - protected Map> classItems, classArmor; - protected Map> classPerms; - protected Map attachments; - protected List entryFee; - - // Player sets - protected Set arenaPlayers, lobbyPlayers, readyPlayers, specPlayers; - - // Wave stuff - protected TreeSet singleWaves, singleWavesInstance; - protected TreeSet recurrentWaves; - protected BossWave bossWave; - protected Wave currentWave; - - // Arena sets/maps - protected Set hasPaid, rewardedPlayers, notifyPlayers, randoms; - protected Set monsters, explodingSheep, plaguedPigs, madCows; - protected Set blocks; - protected Set pets; - protected Map petMap; - protected LinkedList repairables, containables; - - // Spawn overriding - protected int spawnMonsters; - protected boolean allowMonsters, allowAnimals; - - // Other settings - protected int minPlayers, maxPlayers, joinDistance; - protected Set classes = new HashSet(); - protected Map locations = new HashMap(); - protected Map healthMap = new HashMap(); - protected Map hungerMap = new HashMap(); - protected Map modeMap = new HashMap(); - - // Logging - protected ArenaLog log; - protected Map arenaPlayerMap; - protected Leaderboard leaderboard; - - protected MAListener eventListener; - - protected PriorityBlockingQueue repairQueue; - - public Arena() { - - } - - /** - * Primary constructor. Requires a name and a world. - */ - public Arena(String name, World world) - { - if (world == null) - throw new NullPointerException("[MobArena] ERROR! World for arena '" + name + "' does not exist!"); - - this.name = name; - this.world = world; - plugin = (MobArena) Bukkit.getServer().getPluginManager().getPlugin("MobArena"); - - arenaPlayers = new HashSet(); - lobbyPlayers = new HashSet(); - notifyPlayers = new HashSet(); - readyPlayers = new HashSet(); - specPlayers = new HashSet(); - rewardedPlayers = new HashSet(); - hasPaid = new HashSet(); - monsters = new HashSet(); - explodingSheep = new HashSet(); - plaguedPigs = new HashSet(); - madCows = new HashSet(); - blocks = new HashSet(); - pets = new HashSet(); - petMap = new HashMap(); - classMap = new HashMap(); - randoms = new HashSet(); - repairables = new LinkedList(); - containables = new LinkedList(); - attachments = new HashMap(); - arenaPlayerMap = new HashMap(); - - running = false; - edit = false; - - allowMonsters = world.getAllowMonsters(); - allowAnimals = world.getAllowAnimals(); - spawnMonsters = MAUtils.getSpawnMonsters(world); - - eventListener = new MAListener(this, plugin); - repairQueue = new PriorityBlockingQueue(100, new RepairableComparator()); - } - - public abstract boolean startArena(); - - public abstract boolean endArena(); - - public abstract void forceStart(); - - public abstract void forceEnd(); - - public abstract void playerJoin(Player p, Location loc); - - public abstract void playerReady(Player p); - - public abstract void playerLeave(Player p); - - public abstract void playerDeath(Player p); - - public abstract void playerSpec(Player p, Location loc); - - public abstract void playerKill(Player p); - - public abstract void restoreInvAndGiveRewardsDelayed(final Player p); - - public abstract void restoreInvAndGiveRewards(final Player p); - - public abstract void storePlayerData(Player p, Location loc); - - public abstract void storeContainerContents(); - - public abstract void restoreContainerContents(); - - public abstract void movePlayerToLobby(Player p); - - public abstract void movePlayerToSpec(Player p); - - public abstract void movePlayerToEntry(Player p); - - public abstract void repairBlocks(); - - public abstract void queueRepairable(Repairable r); - - - - /*//////////////////////////////////////////////////////////////////// - // - // Items & Cleanup - // - ////////////////////////////////////////////////////////////////////*/ - - public abstract void assignClass(Player p, String className); - - public abstract void assignRandomClass(Player p); - - public abstract void assignClassPermissions(Player p); - - public abstract void removeClassPermissions(Player p); - - - - /*//////////////////////////////////////////////////////////////////// - // - // Initialization & Checks - // - ////////////////////////////////////////////////////////////////////*/ - - public abstract void load(Config config); - - public abstract void restoreRegion(); - - public abstract void serializeConfig(); - - public abstract void deserializeConfig(); - - public abstract boolean serializeRegion(); - - public abstract boolean deserializeRegion(); - - /** - * Check if a location is inside of the cuboid region - * that p1 and p2 span. - */ - public abstract boolean inRegion(Location loc); - - /** - * Check if a location is inside of the arena region, expanded - * by 'radius' blocks. Used with explosions. - */ - public abstract boolean inRegionRadius(Location loc, int radius); - - - - /*//////////////////////////////////////////////////////////////////// - // - // Getters & Misc - // - ////////////////////////////////////////////////////////////////////*/ - - public abstract boolean inArena(Player p); - - public abstract boolean inLobby(Player p); - - public abstract boolean isEnabled(); - - public abstract boolean isRunning(); - - public abstract boolean isPvpEnabled(); - - public abstract boolean isLightningEnabled(); - - public abstract boolean isBossWave(); - - public abstract String configName(); - - public abstract String arenaName(); - - public abstract MobArena getPlugin(); - - public abstract World getWorld(); - - public abstract Wave getWave(); - - public abstract void setWave(Wave wave); - - public abstract void setBossWave(BossWave bossWave); - - public abstract Set getClasses(); - - public abstract List getAllSpawnpoints(); - - public abstract List getSpawnpoints(); - - public abstract Location getBossSpawnpoint(); - - public abstract int getPlayerCount(); - - public abstract void addBlock(Block b); - - public abstract void addMonster(LivingEntity e); - - public abstract void addExplodingSheep(LivingEntity e); - - public abstract List getAllPlayers(); - - public abstract List getLivingPlayers(); - - public abstract Set getArenaPlayers(); - - public abstract Collection getArenaPlayerSet(); - - public abstract List getArenaPlayerStatistics(Comparator comparator); - - public abstract List getNonreadyPlayers(); - - public abstract Set getMonsters(); - - public abstract Set getPets(); - - public abstract void resetIdleTimer(); - - public abstract void addTrunkAndLeaves(Block b); - - public abstract boolean canAfford(Player p); - - public abstract boolean takeFee(Player p); - - public abstract boolean canJoin(Player p); - - public abstract boolean canSpec(Player p); -} diff --git a/src/com/garbagemule/MobArena/ArenaClass.java b/src/com/garbagemule/MobArena/ArenaClass.java new file mode 100644 index 0000000..0af5dbb --- /dev/null +++ b/src/com/garbagemule/MobArena/ArenaClass.java @@ -0,0 +1,283 @@ +package com.garbagemule.MobArena; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.permissions.PermissionAttachment; + +public class ArenaClass +{ + private String name; + private ItemStack helmet, chestplate, leggings, boots; + private List items, armor; + private Map perms; + private int pets; + + /** + * Create a new, empty arena class with the given name. + * @param name the class name + */ + public ArenaClass(String name) { + this.name = name; + + this.items = new ArrayList(); + this.armor = new ArrayList(4); + this.perms = new HashMap(); + this.pets = 0; + } + + /** + * Get the name of the arena class. + * @return the class name + */ + public String getName() { + return name; + } + + /** + * Get the Material type of the first item in the items list. + * If the items list is empty, the method returns Material.STONE + * @return the type of the first item, or STONE if the list is empty + */ + public Material getLogo() { + if (items.isEmpty()) { + return Material.STONE; + } + return items.get(0).getType(); + } + + /** + * Set the helmet slot for the class. + * @param helmet an item + */ + public void setHelmet(ItemStack helmet) { + this.helmet = helmet; + } + + /** + * Set the chestplate slot for the class. + * @param chestplate an item + */ + public void setChestplate(ItemStack chestplate) { + this.chestplate = chestplate; + } + + /** + * Set the leggings slot for the class. + * @param leggings an item + */ + public void setLeggings(ItemStack leggings) { + this.leggings = leggings; + } + + /** + * Set the boots slot for the class. + * @param boots an item + */ + public void setBoots(ItemStack boots) { + this.boots = boots; + } + + /** + * Add an item to the items list. + * If the item is a weapon-type, its durability will be set to "infinite". + * If the item is a bone, the pets counter will be incremented. + * @param stack an item + */ + public void addItem(ItemStack stack) { + if (stack == null) return; + + if (isWeapon(stack)) { + stack.setDurability(Short.MIN_VALUE); + } + else if (stack.getType() == Material.BONE) { + pets += stack.getAmount(); + } + + items.add(stack); + } + + /** + * Replace the current items list with a new list of all the items in the given list. + * This method uses the addItem() method for each item to ensure consistency. + * @param stacks a list of items + */ + public void setItems(List stacks) { + this.items = new ArrayList(stacks.size()); + for (ItemStack stack : stacks) { + addItem(stack); + } + } + + /** + * Replace the current armor list with the given list. + * @param armor a list of items + */ + public void setArmor(List armor) { + this.armor = armor; + } + + /** + * Grants all of the class items and armor to the given player. + * The normal items will be added to the inventory normally, while the + * armor items will be verified as armor items and placed in their + * appropriate slots. If any specific armor slots are specified, they + * will overwrite any items in the armor list. + * @param p a player + */ + public void grantItems(Player p) { + PlayerInventory inv = p.getInventory(); + + // Fork over the items. + for (ItemStack stack : items) { + inv.addItem(stack); + } + + // Check for legacy armor-node items + if (!armor.isEmpty()) { + for (ItemStack piece : armor) { + ArmorType type = ArmorType.getType(piece); + if (type == null) continue; + + switch (type) { + case HELMET: + inv.setHelmet(piece); + break; + case CHESTPLATE: + inv.setChestplate(piece); + break; + case LEGGINGS: + inv.setLeggings(piece); + break; + case BOOTS: + inv.setBoots(piece); + break; + default: + break; + } + } + } + + // Check type specifics. + if (helmet != null) inv.setHelmet(helmet); + if (chestplate != null) inv.setChestplate(chestplate); + if (leggings != null) inv.setLeggings(leggings); + if (boots != null) inv.setBoots(boots); + } + + /** + * Add a permission value to the class. + * @param perm the permission + * @param value the value + */ + public void addPermission(String perm, boolean value) { + perms.put(perm, value); + } + + /** + * Get an unmodifiable map of permissions and values for the class. + * @return a map of permissions and values + */ + public Map getPermissions() { + return Collections.unmodifiableMap(perms); + } + + /** + * Grant the given player all the permissions of the class. + * All permissions will be attached to a PermissionAttachment object, which + * will be returned to the caller. + * @param plugin a MobArena instance + * @param p a player + * @return the PermissionAttachment with all the permissions + */ + public PermissionAttachment grantPermissions(MobArena plugin, Player p) { + if (perms.isEmpty()) return null; + + PermissionAttachment pa = p.addAttachment(plugin); + + for (Entry entry : perms.entrySet()) { + try { + pa.setPermission(entry.getKey(), entry.getValue()); + } + catch (Exception e) { + String perm = entry.getKey() + ":" + entry.getValue(); + String player = p.getName(); + + plugin.warning("[PERM00] Failed to attach permission '" + perm + "' to player '" + player + " with class " + this.name + + "'.\nPlease verify that your class permissions are well-formed."); + } + } + return pa; + } + + /** + * Get the amount of pets this class is given upon starting the arena. + * @return the number of pets this class has + */ + public int getPetAmount() { + return pets; + } + + /** + * Used by isWeapon() to determine if an ItemStack is a weapon type. + */ + private static int[] weaponTypes = new int[]{256,257,258,267,268,269,270,271,272,273,274,275,276,277,278,279,283,284,285,286,290,291,292,293,294}; + + /** + * Returns true, if the ItemStack appears to be a weapon, in which case + * the addItem() method will set the weapon durability to the absolute + * maximum, as to give them "infinite" durability. + * @param stack an ItemStack + * @return true, if the item is a weapon + */ + private boolean isWeapon(ItemStack stack) { + int id = stack.getTypeId(); + + for (int type : weaponTypes) { + if (id == type) { + return true; + } + } + return false; + } + + /** + * Used by the grantItems() method to determine the armor type of a given + * ItemStack. Armor pieces are auto-equipped. + * Note: This enum is only necessary for backward-compatibility with the + * 'armor'-node. + */ + public enum ArmorType { + HELMET (298,302,306,310,314), + CHESTPLATE (299,303,307,311,315), + LEGGINGS (300,304,308,312,316), + BOOTS (301,305,309,313,317); + + private int[] types; + + private ArmorType(int... types) { + this.types = types; + } + + public static ArmorType getType(ItemStack stack) { + int id = stack.getTypeId(); + + for (ArmorType armorType : ArmorType.values()) { + for (int type : armorType.types) { + if (id == type) { + return armorType; + } + } + } + return null; + } + } +} diff --git a/src/com/garbagemule/MobArena/ArenaImpl.java b/src/com/garbagemule/MobArena/ArenaImpl.java new file mode 100644 index 0000000..f401b40 --- /dev/null +++ b/src/com/garbagemule/MobArena/ArenaImpl.java @@ -0,0 +1,1270 @@ +package com.garbagemule.MobArena; + +import java.util.*; +import java.util.Map.Entry; +import java.util.concurrent.PriorityBlockingQueue; + +import org.bukkit.ChatColor; +import org.bukkit.Chunk; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.block.ContainerBlock; +import org.bukkit.entity.CreatureType; +import org.bukkit.entity.Entity; +import org.bukkit.entity.ExperienceOrb; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.entity.Slime; +import org.bukkit.entity.Vehicle; +import org.bukkit.entity.Wolf; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.permissions.PermissionAttachment; +import org.bukkit.potion.PotionEffect; + +import com.garbagemule.MobArena.events.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.leaderboards.Leaderboard; +import com.garbagemule.MobArena.region.ArenaRegion; +import com.garbagemule.MobArena.repairable.*; +import com.garbagemule.MobArena.spout.Spouty; +import com.garbagemule.MobArena.time.Time; +import com.garbagemule.MobArena.time.TimeStrategy; +import com.garbagemule.MobArena.time.TimeStrategyLocked; +import com.garbagemule.MobArena.time.TimeStrategyNull; +import com.garbagemule.MobArena.util.*; +import com.garbagemule.MobArena.util.config.Config; +import com.garbagemule.MobArena.util.config.ConfigSection; +import com.garbagemule.MobArena.util.inventory.InventoryManager; +import com.garbagemule.MobArena.util.inventory.InventoryUtils; +import com.garbagemule.MobArena.waves.*; + +public class ArenaImpl implements Arena +{ + // General stuff + private MobArena plugin; + private String name; + private World world; + + // Settings section of the config-file for this arena. + private ConfigSection settings; + + // Run-time settings and critical config settings + private boolean enabled, protect, running, edit; + + // World stuff + private boolean allowMonsters, allowAnimals; + //private Difficulty spawnMonsters; + + // Warps, points and locations + private ArenaRegion region; + private Leaderboard leaderboard; + + // Player stuff + private InventoryManager inventoryManager; + private RewardManager rewardManager; + private Map arenaPlayerMap; + private Map playerData = new HashMap(); + + private Set arenaPlayers, lobbyPlayers, readyPlayers, specPlayers, deadPlayers; + private Set randoms; + + // Classes stuff + private Map classes; + private Map attachments; + + // Blocks and pets + private PriorityBlockingQueue repairQueue; + private Set blocks; + private LinkedList repairables, containables; + + // Monster stuff + private MonsterManager monsterManager; + + // Wave stuff + private WaveManager waveManager; + private Wave currentWave; + private MASpawnThread spawnThread; + private SheepBouncer sheepBouncer; + private Map> everyWaveMap, afterWaveMap; + + // Misc + private ArenaListenerImpl eventListener; + private List entryFee; + //private ArenaLog log; + private TimeStrategy timeStrategy; + + /** + * Primary constructor. Requires a name and a world. + */ + public ArenaImpl(MobArena plugin, Config config, String name, World world) { + if (world == null) + throw new NullPointerException("[MobArena] ERROR! World for arena '" + name + "' does not exist!"); + + this.name = name; + this.world = world; + this.plugin = plugin; + this.settings = new ConfigSection(config, "arenas." + name + ".settings"); + this.region = new ArenaRegion(new ConfigSection(config, "arenas." + name + ".coords"), this); + + this.enabled = settings.getBoolean("enabled", false); + this.protect = settings.getBoolean("protect", true); + this.running = false; + this.edit = false; + + this.inventoryManager = new InventoryManager(this); + this.rewardManager = new RewardManager(this); + + // Warps, points and locations + this.leaderboard = new Leaderboard(plugin, this, region.getLeaderboard()); + + // Player stuff + this.arenaPlayerMap = new HashMap(); + this.arenaPlayers = new HashSet(); + this.lobbyPlayers = new HashSet(); + this.readyPlayers = new HashSet(); + this.specPlayers = new HashSet(); + this.deadPlayers = new HashSet(); + this.randoms = new HashSet(); + + // Classes, items and permissions + this.classes = plugin.getArenaMaster().getClasses(); + this.attachments = new HashMap(); + + // Blocks and pets + this.repairQueue = new PriorityBlockingQueue(100, new RepairableComparator()); + this.blocks = new HashSet(); + this.repairables = new LinkedList(); + this.containables = new LinkedList(); + + // Monster stuff + this.monsterManager = new MonsterManager(); + + // Wave stuff + this.waveManager = new WaveManager(this, config); + this.everyWaveMap = MAUtils.getArenaRewardMap(plugin, config, name, "every"); + this.afterWaveMap = MAUtils.getArenaRewardMap(plugin, config, name, "after"); + + // Misc + this.eventListener = new ArenaListenerImpl(this, plugin); + this.entryFee = ItemParser.parseItems(settings.getString("entry-fee", "")); + this.allowMonsters = world.getAllowMonsters(); + this.allowAnimals = world.getAllowAnimals(); + + String timeString = settings.getString("player-time-in-arena", "world"); + Time time = Enums.getEnumFromString(Time.class, timeString); + this.timeStrategy = (time != null ? new TimeStrategyLocked(time) : new TimeStrategyNull()); + } + + + + /*///////////////////////////////////////////////////////////////////////// + // + // NEW METHODS IN REFACTORING + // + /////////////////////////////////////////////////////////////////////////*/ + + @Override + public ConfigSection getSettings() { + return settings; + } + + @Override + public World getWorld() { + return world; + } + + @Override + public void setWorld(World world) { + this.world = world; + } + + @Override + public boolean isEnabled() { + return enabled; + } + + @Override + public void setEnabled(boolean value) { + enabled = value; + } + + @Override + public boolean isProtected() { + return protect; + } + + @Override + public void setProtected(boolean value) { + protect = value; + } + + @Override + public boolean isRunning() { + return running; + } + + @Override + public boolean inEditMode() { + return edit; + } + + @Override + public void setEditMode(boolean value) { + edit = value; + } + + private int getMinPlayers() { + return settings.getInt("min-players"); + } + + private int getMaxPlayers() { + return settings.getInt("max-players"); + } + + private int getJoinDistance() { + return settings.getInt("max-join-distance"); + } + + @Override + public Material getClassLogo(String classname) { + ArenaClass arenaClass = classes.get(classname); + if (arenaClass == null) return Material.STONE; + + return arenaClass.getLogo(); + } + + @Override + public List getEntryFee() { + return entryFee; + } + + @Override + public Set>> getEveryWaveEntrySet() { + return everyWaveMap.entrySet(); + } + + @Override + public List getAfterWaveReward(int wave) { + return afterWaveMap.get(wave); + } + + @Override + public Set getPlayersInArena() { + return Collections.unmodifiableSet(arenaPlayers); + } + + @Override + public Set getPlayersInLobby() { + return Collections.unmodifiableSet(lobbyPlayers); + } + + @Override + public Set getReadyPlayersInLobby() { + return Collections.unmodifiableSet(readyPlayers); + } + + @Override + public Set getSpectators() { + return Collections.unmodifiableSet(specPlayers); + } + + @Override + public MASpawnThread getSpawnThread() { + return spawnThread; + } + + @Override + public WaveManager getWaveManager() { + return waveManager; + } + + /*@Override + public ArenaLog getLog() { + return log; + }*/ + + @Override + public Location getPlayerEntry(Player p) { + PlayerData mp = playerData.get(p); + return (mp != null ? mp.entry() : null); + } + + @Override + public ArenaListenerImpl getEventListener() { + return eventListener; + } + + @Override + public void setLeaderboard(Leaderboard leaderboard) { + this.leaderboard = leaderboard; + } + + @Override + public ArenaPlayer getArenaPlayer(Player p) { + return arenaPlayerMap.get(p); + } + + @Override + public Set getBlocks() { + return blocks; + } + + @Override + public void addBlock(Block b) { + blocks.add(b); + } + + @Override + public boolean removeBlock(Block b) { + return blocks.remove(b); + } + + @Override + public boolean hasPet(Entity e) { + return monsterManager.hasPet(e); + } + + @Override + public void addRepairable(Repairable r) { + repairables.add(r); + } + + @Override + public ArenaRegion getRegion() { + return region; + } + + @Override + public InventoryManager getInventoryManager() { + return inventoryManager; + } + + @Override + public RewardManager getRewardManager() { + return rewardManager; + } + + @Override + public MonsterManager getMonsterManager() { + return monsterManager; + } + + + + + + + + + + + + @Override + public boolean startArena() { + // Sanity-checks + if (running || lobbyPlayers.isEmpty() || !readyPlayers.containsAll(lobbyPlayers)) { + return false; + } + + // Fire the event and check if it's been cancelled. + ArenaStartEvent event = new ArenaStartEvent(this); + plugin.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return false; + } + + // Store all chest contents. + storeContainerContents(); + + // Populate arenaPlayers and clear the lobby. + arenaPlayers.addAll(lobbyPlayers); + lobbyPlayers.clear(); + readyPlayers.clear(); + + // Assign random classes. + for (Player p : randoms) { + assignRandomClass(p); + } + + // Then check if there are still players left. + if (arenaPlayers.isEmpty()) { + return false; + } + + // Teleport players, give full health, initialize map + for (Player p : arenaPlayers) { + p.teleport(region.getArenaWarp()); + //movePlayerToLocation(p, region.getArenaWarp()); + setHealth(p, 20); + p.setFoodLevel(20); + assignClassPermissions(p); + arenaPlayerMap.get(p).resetStats(); + } + + // Start spawning monsters (must happen before 'running = true;') + startSpawner(); + startBouncingSheep(); + + // Set the boolean. + running = true; + + // Spawn pets (must happen after 'running = true;') + spawnPets(); + + // Start logging + rewardManager.reset(); + //log = new ArenaLog(plugin, this); + //log.start(); + + // Initialize leaderboards and start displaying info. + leaderboard.initialize(); + leaderboard.startTracking(); + + Messenger.tellAll(this, Msg.ARENA_START); + + return true; + } + + @Override + public boolean endArena() { + // Sanity-checks. + if (!running || !arenaPlayers.isEmpty()) { + return false; + } + + // Fire the event and check if it's been cancelled. + ArenaEndEvent event = new ArenaEndEvent(this); + plugin.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return false; + } + + // Set the running boolean and disable arena if not disabled. + boolean en = enabled; + enabled = false; + running = false; + + // Stop tracking leaderboards + leaderboard.stopTracking(); + leaderboard.update(); + + // Finish logging + //log.end(); + /*if (logging != null) { TODO: FIX LOGGING! + log.saveSessionData(); + log.updateArenaTotals(); + }*/ + //log.clearSessionData(); + + // Stop spawning. + stopSpawner(); + + // Announce and clean arena floor, etc. + Messenger.tellAll(this, Msg.ARENA_END, true); + cleanup(); + + // Restore region. + if (settings.getBoolean("soft-restore", false)) { + restoreRegion(); + } + + // Restore chests + restoreContainerContents(); + + // Restore enabled status. + enabled = en; + + return true; + } + + @Override + public void forceStart() + { + if (running) + return; + + // Set operations. + Set tmp = new HashSet(); + tmp.addAll(lobbyPlayers); + tmp.removeAll(readyPlayers); + + // Force leave. + for (Player p : tmp) { + playerLeave(p); + } + + startArena(); + } + + @Override + public void forceEnd() { + for (Player p : getAllPlayers()) { + playerLeave(p); + } + + cleanup(); + } + + @Override + public boolean playerJoin(Player p, Location loc) + { + // Fire the event and check if it's been cancelled. + ArenaPlayerJoinEvent event = new ArenaPlayerJoinEvent(p, this); + plugin.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return false; + } + + takeFee(p); + storePlayerData(p, loc); + removePotionEffects(p); + MAUtils.sitPets(p); + setHealth(p, 20); + p.setFoodLevel(20); + p.setGameMode(GameMode.SURVIVAL); + movePlayerToLobby(p); + + arenaPlayerMap.put(p, new ArenaPlayer(p, this, plugin)); + + if (MobArena.hasSpout && settings.getBoolean("spout-class-select")) + Spouty.classSelectionScreen(plugin, this, p); + + Messenger.tellPlayer(p, Msg.JOIN_PLAYER_JOINED); + return true; + } + + @Override + public void playerReady(Player p) + { + readyPlayers.add(p); + + int minPlayers = getMinPlayers(); + if (minPlayers > 0 && lobbyPlayers.size() < minPlayers) + { + Messenger.tellPlayer(p, Msg.LOBBY_NOT_ENOUGH_PLAYERS, "" + minPlayers); + return; + } + + startArena(); + } + + @Override + //@SuppressWarnings("deprecation") + public boolean playerLeave(Player p) + { + // Fire the event and check if it's been cancelled. + ArenaPlayerLeaveEvent event = new ArenaPlayerLeaveEvent(p, this); + plugin.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + return false; + } + + removeClassPermissions(p); + removePotionEffects(p); + + if (inLobby(p) || inArena(p)) { + inventoryManager.clearInventory(p); + inventoryManager.restoreInventory(p); + rewardManager.grantRewards(p); + refund(p); + //p.updateInventory(); + } + else if (inSpec(p)) { + inventoryManager.restoreInventory(p); + //p.updateInventory(); + } + + movePlayerToEntry(p); + discardPlayer(p); + + endArena(); + return true; + } + + @Override + public void playerDeath(Player p) + { + // Fire the event + ArenaPlayerDeathEvent event = new ArenaPlayerDeathEvent(p, this); + plugin.getServer().getPluginManager().callEvent(event); + + arenaPlayers.remove(p); + + if (!settings.getBoolean("auto-respawn", true)) { + deadPlayers.add(p); + endArena(); + return; + } + + p.setHealth(20); + Delays.revivePlayer(plugin, this, p); + endArena(); + } + + @Override + public void playerRespawn(Player p) { + if (settings.getBoolean("auto-respawn", true)) { + return; + } + + deadPlayers.remove(p); + revivePlayer(p); + } + + @Override + @SuppressWarnings("deprecation") + public void revivePlayer(Player p) { + Delays.douse(plugin, p, 1); + removeClassPermissions(p); + removePotionEffects(p); + + if (settings.getBoolean("spectate-on-death", true)) { + movePlayerToSpec(p); + restoreInvAndExp(p); + } else { + restoreInvAndExp(p); + movePlayerToEntry(p); + discardPlayer(p); + } + p.updateInventory(); + } + + @Override + public Location getRespawnLocation(Player p) { + Location l = null; + if (settings.getBoolean("spectate-on-death", true)) { + l = region.getSpecWarp(); + } else { + //l = locations.get(p); + l = playerData.get(p).entry(); + } + return l; + } + + @Override + public void playerSpec(Player p, Location loc) + { + storePlayerData(p, loc); + MAUtils.sitPets(p); + movePlayerToSpec(p); + } + + private void spawnPets() + { + for (Map.Entry entry : arenaPlayerMap.entrySet()) { + ArenaClass arenaClass = entry.getValue().getArenaClass(); + int petAmount = arenaClass.getPetAmount(); + + if (petAmount <= 0) { + continue; + } + + // Remove the bones from the inventory. + Player p = entry.getKey(); + p.getInventory().removeItem(new ItemStack(Material.BONE, petAmount)); + + for (int i = 0; i < petAmount; i++) { + Wolf wolf = (Wolf) world.spawnCreature(p.getLocation(), CreatureType.WOLF); + wolf.setTamed(true); + wolf.setOwner(p); + wolf.setHealth(wolf.getMaxHealth()); + if (settings.getBoolean("hellhounds")) + wolf.setFireTicks(32768); + monsterManager.addPet(wolf); + } + } + } + + private void removePotionEffects(Player p) { + for (PotionEffect effect : p.getActivePotionEffects()) { + p.removePotionEffect(effect.getType()); + } + } + + private void startSpawner() + { + // Set the spawn flags to enable monster spawning. + world.setSpawnFlags(true, true); + //world.setDifficulty(Difficulty.NORMAL); + + // Create a spawner if one doesn't exist, otherwise reset it + if (spawnThread == null) { + spawnThread = new MASpawnThread(plugin, this); + } else { + spawnThread.reset(); + } + + // Schedule it for the initial first wave delay. + scheduleTask(spawnThread, settings.getInt("first-wave-delay", 5) * 20); + } + + /** + * Schedule a Runnable to be executed after the given delay in + * server ticks. The method is used by the MASpawnThread to + * repeatedly spawn new mobs instead of a scheduled repeating + * tasks, as well as the sheep bouncer. + */ + @Override + public void scheduleTask(Runnable r, int delay) { + plugin.getServer().getScheduler().scheduleSyncDelayedTask( + plugin, + r, + delay); + } + + private void stopSpawner() { + world.setSpawnFlags(allowMonsters, allowAnimals); + //world.setDifficulty(spawnMonsters); + } + + private void startBouncingSheep() + { + // Create a new bouncer if necessary. + if (sheepBouncer == null) { + sheepBouncer = new SheepBouncer(this); + } + + // Start bouncing! + scheduleTask(sheepBouncer, settings.getInt("first-wave-delay", 5) * 20); + } + + private void updateChunk(Location loc) + { + if (!arenaPlayers.isEmpty() || !world.getName().equals(loc.getWorld().getName())) + return; + + Chunk chunk = world.getChunkAt(loc); + if (!world.isChunkLoaded(chunk)) + world.loadChunk(chunk); + else + world.refreshChunk(chunk.getX(), chunk.getZ()); + } + + @Override + public void storePlayerData(Player p, Location loc) + { + plugin.getArenaMaster().addPlayer(p, this); + + PlayerData mp = playerData.get(p); + + // If there's no player stored, create a new one! + if (mp == null) { + mp = new PlayerData(p); + playerData.put(p, mp); + } + + // At any rate, update the data. + mp.update(); + + // And update the inventory as well. + inventoryManager.storeInventory(p); + } + + @Override + public void storeContainerContents() + { + plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, + new Runnable() { + public void run() { + for (Location loc : region.getContainers()) { + BlockState state = world.getBlockAt(loc).getState(); + if (state instanceof ContainerBlock) { + containables.add(new RepairableContainer(state, false)); + } + } + } + }); + } + + @Override + public void restoreContainerContents() + { + plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, + new Runnable() { + public void run() { + for (Repairable r : containables) { + r.repair(); + } + } + }); + } + + @Override + public void movePlayerToLobby(Player p) + { + updateChunk(region.getLobbyWarp()); + specPlayers.remove(p); // If joining from spec area + lobbyPlayers.add(p); + p.teleport(region.getLobbyWarp()); + timeStrategy.setPlayerTime(p); + //movePlayerToLocation(p, region.getLobbyWarp()); + } + + @Override + public void movePlayerToSpec(Player p) + { + updateChunk(region.getSpecWarp()); + specPlayers.add(p); + p.teleport(region.getSpecWarp()); + timeStrategy.setPlayerTime(p); + //movePlayerToLocation(p, region.getSpecWarp()); + } + + @Override + public void movePlayerToEntry(Player p) + { + Location entry = playerData.get(p).entry(); + if (entry == null || p.isDead()) return; + + updateChunk(entry); + p.teleport(entry); + timeStrategy.resetPlayerTime(p); + //movePlayerToLocation(p, entry); + + p.setGameMode(playerData.get(p).getMode()); + p.addPotionEffects(playerData.get(p).getPotionEffects()); + } + + /*private void movePlayerToLocation(Player p, Location l) { + WorldServer fromWorld = ((CraftWorld) p.getWorld()).getHandle(); + WorldServer toWorld = ((CraftWorld) l.getWorld()).getHandle(); + EntityPlayer player = ((CraftPlayer) p).getHandle(); + + if (fromWorld == toWorld) { + player.netServerHandler.teleport(l); + } + else { + if (player.activeContainer != player.defaultContainer) { + player.closeInventory(); + } + CraftServer cs = ((CraftServer) plugin.getServer()); + cs.getHandle().moveToWorld(player, toWorld.dimension, true, l); + } + }*/ + + private void restoreInvAndExp(Player p) { + inventoryManager.clearInventory(p); + inventoryManager.restoreInventory(p); + rewardManager.grantRewards(p); + + if (!settings.getBoolean("keep-exp", false)) { + playerData.get(p).restoreData(); + } + } + + @Override + public void discardPlayer(Player p) + { + plugin.getArenaMaster().removePlayer(p); + clearPlayer(p); + } + + private void clearPlayer(Player p) + { + // Remove the player data completely. + PlayerData mp = playerData.remove(p); + + // Health must be handled in a certain way because of Heroes + setHealth(p, mp.health()); + + // Put out fire. + Delays.douse(plugin, p, 3); + + // Remove pets. + monsterManager.removePets(p); + + // readyPlayers before lobbyPlayers because of startArena sanity-checks + readyPlayers.remove(p); + specPlayers.remove(p); + arenaPlayers.remove(p); + lobbyPlayers.remove(p); + arenaPlayerMap.remove(p); + } + + private void setHealth(Player p, int health) { + plugin.getHealthStrategy().setHealth(p, health); + } + + @Override + public void repairBlocks() + { + while (!repairQueue.isEmpty()) + repairQueue.poll().repair(); + } + + @Override + public void queueRepairable(Repairable r) + { + repairQueue.add(r); + } + + + + /*//////////////////////////////////////////////////////////////////// + // + // Items & Cleanup + // + ////////////////////////////////////////////////////////////////////*/ + + @Override + public void assignClass(Player p, String className) { + ArenaPlayer arenaPlayer = arenaPlayerMap.get(p); + ArenaClass arenaClass = classes.get(className); + + if (arenaPlayer == null || arenaClass == null) { + return; + } + + inventoryManager.clearInventory(p); + + arenaPlayer.setArenaClass(arenaClass); + arenaClass.grantItems(p); + } + + @Override + public void assignRandomClass(Player p) + { + Random r = new Random(); + List classes = new LinkedList(this.classes.keySet()); + + String className = classes.remove(r.nextInt(classes.size())); + while (!plugin.has(p, "mobarena.classes." + className)) + { + if (classes.isEmpty()) + { + plugin.info("Player '" + p.getName() + "' has no class permissions!"); + playerLeave(p); + return; + } + className = classes.remove(r.nextInt(classes.size())); + } + + assignClass(p, className); + Messenger.tellPlayer(p, Msg.LOBBY_CLASS_PICKED, className); + } + + @Override + public void assignClassPermissions(Player p) + { + PermissionAttachment pa = arenaPlayerMap.get(p).getArenaClass().grantPermissions(plugin, p); + if (pa == null) return; + + attachments.put(p, pa); + p.recalculatePermissions(); + } + + @Override + public void removeClassPermissions(Player p) + { + PermissionAttachment pa = attachments.remove(p); + if (pa == null) return; + + try { + p.removeAttachment(pa); + } + catch (Exception e) { + for (Entry entry : pa.getPermissions().entrySet()) { + String perm = entry.getKey() + ":" + entry.getValue(); + String name = p.getName(); + + plugin.warning("[PERM01] Failed to remove permission attachment '" + perm + "' from player '" + name + + "'.\nThis should not be a big issue, but please verify that the player doesn't have any permissions they shouldn't have."); + } + } + p.recalculatePermissions(); + } + + private void cleanup() { + removeMonsters(); + removeBlocks(); + removeEntities(); + clearPlayers(); + } + + private void removeMonsters() { + monsterManager.clear(); + } + + private void removeBlocks() { + for (Block b : blocks) { + b.setTypeId(0); + } + blocks.clear(); + } + + private void removeEntities() { + List chunks = region.getChunks(); + + for (Chunk c : chunks) { + for (Entity e : c.getEntities()) { + if (!(e instanceof Item || e instanceof Vehicle || e instanceof Slime || e instanceof ExperienceOrb)) { + continue; + } + + if (e != null) { + e.remove(); + } + } + } + } + + private void clearPlayers() { + arenaPlayers.clear(); + arenaPlayerMap.clear(); + lobbyPlayers.clear(); + readyPlayers.clear(); + } + + + + /*//////////////////////////////////////////////////////////////////// + // + // Initialization & Checks + // + ////////////////////////////////////////////////////////////////////*/ + + @Override + public void restoreRegion() + { + Collections.sort(repairables, new RepairableComparator()); + + for (Repairable r : repairables) + r.repair(); + } + + + + /*//////////////////////////////////////////////////////////////////// + // + // Getters & Misc + // + ////////////////////////////////////////////////////////////////////*/ + + @Override + public boolean inArena(Player p) { + return arenaPlayers.contains(p); + } + + @Override + public boolean inLobby(Player p) { + return lobbyPlayers.contains(p); + } + + @Override + public boolean inSpec(Player p) { + return specPlayers.contains(p); + } + + @Override + public boolean isDead(Player p) { + return deadPlayers.contains(p); + } + + @Override + public String configName() + { + return name; + } + + @Override + public String arenaName() + { + return MAUtils.nameConfigToArena(name); + } + + @Override + public MobArena getPlugin() + { + return plugin; + } + + @Override + public Wave getWave() + { + return currentWave; + } + + @Override + public Map getClasses() + { + return classes; + } + + @Override + public int getPlayerCount() + { + return spawnThread.getPlayerCount(); + } + + @Override + public List getAllPlayers() + { + List result = new LinkedList(); + result.addAll(arenaPlayers); + result.addAll(lobbyPlayers); + result.addAll(specPlayers); + + return result; + } + + @Override + public Collection getArenaPlayerSet() + { + return arenaPlayerMap.values(); + } + + /*@Override + public List getArenaPlayerStatistics(Comparator comparator) + { + List list = new ArrayList(); + + for (ArenaPlayer ap : arenaPlayerMap.values()) + list.add(ap.getStats()); + + Collections.sort(list, comparator); + return list; + }*/ + + @Override + public List getNonreadyPlayers() + { + List result = new LinkedList(); + result.addAll(lobbyPlayers); + result.removeAll(readyPlayers); + return result; + } + + @Override + public boolean canAfford(Player p) { + if (entryFee.isEmpty()) return true; + + PlayerInventory inv = p.getInventory(); + for (ItemStack stack : entryFee) { + // Economy money + if (stack.getTypeId() == MobArena.ECONOMY_MONEY_ID) { + if (!plugin.hasEnough(p, stack.getAmount())) { + return false; + } + } + // Normal stack + else { + if (!inv.contains(stack.getTypeId(), stack.getAmount())) { + return false; + } + } + } + return true; + } + + @Override + public boolean takeFee(Player p) { + if (entryFee.isEmpty()) return true; + + PlayerInventory inv = p.getInventory(); + + // Take some economy money + for (ItemStack stack : InventoryUtils.extractAll(MobArena.ECONOMY_MONEY_ID, entryFee)) { + plugin.takeMoney(p, stack.getAmount()); + } + + // Take any other items + for (ItemStack stack : entryFee) { + inv.removeItem(stack); + } + + Messenger.tellPlayer(p, Msg.JOIN_FEE_PAID.toString(MAUtils.listToString(entryFee, plugin))); + return true; + } + + @Override + public boolean refund(Player p) { + if (entryFee.isEmpty()) return true; + if (!inLobby(p)) return false; + + // Refund economy money + for (ItemStack stack : InventoryUtils.extractAll(MobArena.ECONOMY_MONEY_ID, entryFee)) { + plugin.giveMoney(p, stack.getAmount()); + } + + // Refund other items. + for (ItemStack stack : entryFee) { + if (stack.getTypeId() > 0) { + p.getInventory().addItem(stack); + } + } + return true; + } + + @Override + public boolean canJoin(Player p) { + if (!enabled) + Messenger.tellPlayer(p, Msg.JOIN_ARENA_NOT_ENABLED); + else if (!region.isSetup() || waveManager.getRecurrentWaves().isEmpty()) + Messenger.tellPlayer(p, Msg.JOIN_ARENA_NOT_SETUP); + else if (edit) + Messenger.tellPlayer(p, Msg.JOIN_ARENA_EDIT_MODE); + else if (arenaPlayers.contains(p) || lobbyPlayers.contains(p)) + Messenger.tellPlayer(p, Msg.JOIN_ALREADY_PLAYING); + else if (running) + Messenger.tellPlayer(p, Msg.JOIN_ARENA_IS_RUNNING); + else if (!plugin.has(p, "mobarena.arenas." + configName())) + Messenger.tellPlayer(p, Msg.JOIN_ARENA_PERMISSION); + else if (getMaxPlayers() > 0 && lobbyPlayers.size() >= getMaxPlayers()) + Messenger.tellPlayer(p, Msg.JOIN_PLAYER_LIMIT_REACHED); + else if (getJoinDistance() > 0 && !region.contains(p.getLocation(), getJoinDistance())) + Messenger.tellPlayer(p, Msg.JOIN_TOO_FAR); + else if (settings.getBoolean("require-empty-inv-join", true) && !InventoryManager.hasEmptyInventory(p)) + Messenger.tellPlayer(p, Msg.JOIN_EMPTY_INV); + else if (!canAfford(p)) + Messenger.tellPlayer(p, Msg.JOIN_FEE_REQUIRED, MAUtils.listToString(entryFee, plugin)); + else return true; + + return false; + } + + @Override + public boolean canSpec(Player p) { + if (!enabled) + Messenger.tellPlayer(p, Msg.JOIN_ARENA_NOT_ENABLED); + else if (!region.isSetup()) + Messenger.tellPlayer(p, Msg.JOIN_ARENA_NOT_SETUP); + else if (edit) + Messenger.tellPlayer(p, Msg.JOIN_ARENA_EDIT_MODE); + else if (arenaPlayers.contains(p) || lobbyPlayers.contains(p)) + Messenger.tellPlayer(p, Msg.SPEC_ALREADY_PLAYING); + else if (settings.getBoolean("require-empty-inv-spec", true) && !InventoryManager.hasEmptyInventory(p)) + Messenger.tellPlayer(p, Msg.SPEC_EMPTY_INV); + else if (getJoinDistance() > 0 && !region.contains(p.getLocation(), getJoinDistance())) + Messenger.tellPlayer(p, Msg.JOIN_TOO_FAR); + else return true; + + return false; + } + + /** + * The "perfect equals method" cf. "Object-Oriented Design and Patterns" + * by Cay S. Horstmann. + */ + @Override + public boolean equals(Object other) { + if (this == other) return true; + if (other == null) return false; + if (getClass() != other.getClass()) return false; + + // Arenas must have different names. + if (other instanceof ArenaImpl && ((ArenaImpl)other).name.equals(name)) + return true; + + return false; + } + + @Override + public String toString() { + return ((enabled && region.isSetup()) ? ChatColor.GREEN : ChatColor.GRAY) + configName(); + } +} diff --git a/src/com/garbagemule/MobArena/ArenaListenerImpl.java b/src/com/garbagemule/MobArena/ArenaListenerImpl.java new file mode 100644 index 0000000..e716a5e --- /dev/null +++ b/src/com/garbagemule/MobArena/ArenaListenerImpl.java @@ -0,0 +1,789 @@ +package com.garbagemule.MobArena; + +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +import java.util.Set; + +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; +import org.bukkit.block.ContainerBlock; +import org.bukkit.block.Sign; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.entity.Slime; +import org.bukkit.entity.Wolf; +import org.bukkit.event.Event.Result; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockEvent; +import org.bukkit.event.block.BlockFormEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.block.SignChangeEvent; +import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; +import org.bukkit.event.entity.EntityChangeBlockEvent; +import org.bukkit.event.entity.EntityCombustEvent; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.entity.EntityDeathEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.entity.EntityRegainHealthEvent; +import org.bukkit.event.entity.EntityTargetEvent; +import org.bukkit.event.entity.FoodLevelChangeEvent; +import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; +import org.bukkit.event.entity.EntityTargetEvent.TargetReason; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.player.PlayerAnimationEvent; +import org.bukkit.event.player.PlayerBucketEmptyEvent; +import org.bukkit.event.player.PlayerCommandPreprocessEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerKickEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.player.PlayerRespawnEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.material.Attachable; +import org.bukkit.material.Bed; +import org.bukkit.material.Door; +import org.bukkit.material.Redstone; + +import com.garbagemule.MobArena.MAUtils; +import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.Msg; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaListener; +import com.garbagemule.MobArena.leaderboards.Leaderboard; +import com.garbagemule.MobArena.region.ArenaRegion; +import com.garbagemule.MobArena.region.RegionPoint; +import com.garbagemule.MobArena.repairable.*; +import com.garbagemule.MobArena.util.TextUtils; +import com.garbagemule.MobArena.util.config.ConfigSection; +import com.garbagemule.MobArena.waves.MABoss; + +public class ArenaListenerImpl implements ArenaListener +{ + private MobArena plugin; + private Arena arena; + private ArenaRegion region; + private MonsterManager monsters; + + private boolean softRestore, + softRestoreDrops, + protect; + private boolean monsterExp, + monsterInfight, + pvpEnabled, + foodRegen, + lockFoodLevel; + private boolean allowTeleport, + canShare, + allowMonsters; + + private Set banned; + + public ArenaListenerImpl(Arena arena, MobArena plugin) { + this.plugin = plugin; + this.arena = arena; + this.region = arena.getRegion(); + this.monsters = arena.getMonsterManager(); + + /* + * TODO: Figure out if this is really a good idea + It saves needing all + * those methods in Arena.java + It is relatively simple + It would be + * fairly easy to implement an observer pattern - More private fields - + * Uglier code + */ + ConfigSection s = arena.getSettings(); + this.softRestore = s.getBoolean("soft-restore", false); + this.softRestoreDrops = s.getBoolean("soft-restore-drops", false); + this.protect = s.getBoolean("protect", true); + this.monsterExp = s.getBoolean("monster-exp", false); + this.monsterInfight = s.getBoolean("monster-infight", false); + this.pvpEnabled = s.getBoolean("pvp-enabled", false); + this.foodRegen = s.getBoolean("food-regen", false); + this.lockFoodLevel = s.getBoolean("lock-food-level", true); + this.allowTeleport = s.getBoolean("allow-teleporting", false); + this.canShare = s.getBoolean("share-items-in-arena", true); + + this.allowMonsters = arena.getWorld().getAllowMonsters(); + + this.banned = new HashSet(); + } + + public void onBlockBreak(BlockBreakEvent event) { + if (onBlockDestroy(event)) + return; + + event.setCancelled(true); + } + + public void onBlockBurn(BlockBurnEvent event) { + if (onBlockDestroy(event)) + return; + + event.setCancelled(true); + } + + private boolean onBlockDestroy(BlockEvent event) { + if (!arena.getRegion().contains(event.getBlock().getLocation()) || arena.inEditMode() || (!arena.isProtected() && arena.isRunning())) + return true; + + Block b = event.getBlock(); + if (arena.removeBlock(b) || b.getType() == Material.TNT) + return true; + + if (softRestore && arena.isRunning()) { + BlockState state = b.getState(); + + Repairable r = null; + if (state instanceof ContainerBlock) + r = new RepairableContainer(state); + else if (state instanceof Sign) + r = new RepairableSign(state); + else if (state.getData() instanceof Attachable) + r = new RepairableAttachable(state); + else + r = new RepairableBlock(state); + + arena.addRepairable(r); + + if (!softRestoreDrops) + b.setTypeId(0); + + return true; + } + + return false; + } + + public void onBlockPlace(BlockPlaceEvent event) { + Block b = event.getBlock(); + + // If the event didn't happen in the region, or if in edit mode, ignore + if (!arena.getRegion().contains(b.getLocation()) || arena.inEditMode()) { + return; + } + + // If the arena isn't running, or if the player isn't in the arena, + // cancel. + if (!arena.isRunning() || !arena.inArena(event.getPlayer())) { + event.setCancelled(true); + return; + } + + // Otherwise, block was placed during a session. + arena.addBlock(b); + + switch (b.getType()){ + // For doors, add the block just above (so we get both halves) + case WOODEN_DOOR: + case IRON_DOOR_BLOCK: + arena.addBlock(b.getRelative(0, 1, 0)); + break; + } + } + + public void onBlockForm(BlockFormEvent event) { + if (!arena.getRegion().contains(event.getBlock().getLocation())) + return; + + // If a snowman forms some snow on its path, add the block + if (event.getNewState().getType() == Material.SNOW) + arena.addBlock(event.getBlock()); + } + + public void onBlockIgnite(BlockIgniteEvent event) { + if (!arena.getRegion().contains(event.getBlock().getLocation())) + return; + + switch (event.getCause()){ + case LIGHTNING: + case SPREAD: + event.setCancelled(true); + break; + case FLINT_AND_STEEL: + if (arena.isRunning()) + arena.addBlock(event.getBlock().getRelative(BlockFace.UP)); + else + event.setCancelled(true); + break; + default: + break; + } + } + + public void onSignChange(SignChangeEvent event) { + arena.setLeaderboard(new Leaderboard(plugin, arena, event.getBlock().getLocation())); + arena.getRegion().set(RegionPoint.LEADERBOARD, event.getBlock().getLocation()); + + Messenger.tellPlayer(event.getPlayer(), "Leaderboard made. Now set up the stat signs!"); + } + + public void onCreatureSpawn(CreatureSpawnEvent event) { + if (!arena.getRegion().contains(event.getLocation())) { + if (!event.isCancelled()) { + event.setCancelled(!allowMonsters); + } + return; + } + + if (event.getSpawnReason() != SpawnReason.CUSTOM) { + event.setCancelled(true); + return; + } + + LivingEntity entity = (LivingEntity) event.getEntity(); + if (arena.isRunning() && entity instanceof Slime) + monsters.addMonster(entity); + + // If running == true, setCancelled(false), and vice versa. + event.setCancelled(!arena.isRunning()); + } + + public void onEntityExplode(EntityExplodeEvent event) { + if (!monsters.getMonsters().contains(event.getEntity()) && !arena.getRegion().contains(event.getLocation(), 10)) + return; + + monsters.removeMonster(event.getEntity()); + + // Cancel if the arena isn't running + if (!arena.isRunning()) { + event.setCancelled(true); + return; + } + + // Uncancel, just in case. + event.setCancelled(false); + + // If the arena isn't destructible, just clear the blocklist. + if (!softRestore && protect) { + List blocks = new LinkedList(arena.getBlocks()); + event.blockList().retainAll(blocks); + return; + } + + if (!softRestoreDrops) + event.setYield(0); + + // Handle all the blocks in the block list. + for (Block b : event.blockList()) { + BlockState state = b.getState(); + + if (state.getData() instanceof Door && ((Door) state.getData()).isTopHalf()) { + state = b.getRelative(BlockFace.DOWN).getState(); + } + else if (state.getData() instanceof Bed && ((Bed) state.getData()).isHeadOfBed()) { + state = b.getRelative(((Bed) state.getData()).getFacing().getOppositeFace()).getState(); + } + + // Create a Repairable from the block. + Repairable r = null; + if (state instanceof ContainerBlock) + r = new RepairableContainer(state); + else if (state instanceof Sign) + r = new RepairableSign(state); + else if (state.getData() instanceof Bed) + r = new RepairableBed(state); + else if (state.getData() instanceof Door) + r = new RepairableDoor(state); + else if (state.getData() instanceof Attachable || state.getData() instanceof Redstone) + r = new RepairableAttachable(state); + else + r = new RepairableBlock(state); + + // Cakes and liquids should just get removed. If player-placed block, drop as item. + Material mat = state.getType(); + if (mat == Material.CAKE_BLOCK || mat == Material.WATER || mat == Material.LAVA) + arena.removeBlock(b); + else if (arena.removeBlock(b)) + arena.getWorld().dropItemNaturally(b.getLocation(), new ItemStack(state.getTypeId(), 1)); + else if (softRestore) + arena.addRepairable(r); + else + arena.queueRepairable(r); + } + } + + /****************************************************** + * + * DEATH LISTENERS + * + ******************************************************/ + + public void onEntityDeath(EntityDeathEvent event) { + if (event instanceof PlayerDeathEvent) { + onPlayerDeath((PlayerDeathEvent) event, (Player) event.getEntity()); + } + else if (monsters.removeMonster(event.getEntity())) { + onMonsterDeath(event); + } + } + + private void onPlayerDeath(PlayerDeathEvent event, Player player) { + if (arena.inArena(player) || arena.inLobby(player)) { + event.getDrops().clear(); + event.setDroppedExp(0); + event.setKeepLevel(true); + arena.playerDeath(player); + } + } + + public boolean onPlayerRespawn(PlayerRespawnEvent event) { + Player p = event.getPlayer(); + if (!arena.isDead(p)) { + return false; + } + + Location loc = arena.getRespawnLocation(p); + event.setRespawnLocation(loc); + + arena.playerRespawn(p); + return true; + } + + private void onMonsterDeath(EntityDeathEvent event) { + EntityDamageEvent e1 = event.getEntity().getLastDamageCause(); + EntityDamageByEntityEvent e2 = (e1 instanceof EntityDamageByEntityEvent) ? (EntityDamageByEntityEvent) e1 : null; + Entity damager = (e2 != null) ? e2.getDamager() : null; + + // Make sure to grab the owner of a projectile/pet + if (damager instanceof Projectile) { + damager = ((Projectile) damager).getShooter(); + } + else if (damager instanceof Wolf && arena.hasPet(damager)) { + damager = (Player) ((Wolf) damager).getOwner(); + } + + // If the damager was a player, add to kills. + if (damager instanceof Player) { + ArenaPlayer ap = arena.getArenaPlayer((Player) damager); + if (ap != null) { + ArenaPlayerStatistics stats = ap.getStats(); + if (stats != null) { + ap.getStats().inc("kills"); + } + } + } + + if (!monsterExp) + event.setDroppedExp(0); + + event.getDrops().clear(); + + List loot = monsters.getLoot(event.getEntity()); + if (loot != null && !loot.isEmpty()) { + event.getDrops().add(getRandomItem(loot)); + } + + return; + } + + private ItemStack getRandomItem(List stacks) { + return stacks.get((new Random()).nextInt(stacks.size())); + } + + /****************************************************** + * + * DAMAGE LISTENERS + * + ******************************************************/ + + public void onEntityDamage(EntityDamageEvent event) { + Entity damagee = event.getEntity(); + if (!arena.isRunning() || !arena.getRegion().contains(damagee.getLocation())) { + return; + } + + EntityDamageByEntityEvent edbe = (event instanceof EntityDamageByEntityEvent) ? (EntityDamageByEntityEvent) event : null; + Entity damager = null; + + if (edbe != null) { + damager = edbe.getDamager(); + + if (damager instanceof Projectile) { + damager = ((Projectile) damager).getShooter(); + } + else if (damager instanceof Wolf && arena.hasPet(damager)) { + damager = (Player) ((Wolf) damager).getOwner(); + } + } + + // Pet wolf + if (damagee instanceof Wolf && arena.hasPet(damagee)) { + onPetDamage(event, (Wolf) damagee, damager); + } + // Player + else if (damagee instanceof Player) { + onPlayerDamage(event, (Player) damagee, damager); + } + // Boss + else if (monsters.getBossMonsters().contains(damagee)) { + onBossDamage(event, (LivingEntity) damagee, damager); + } + // Regular monster + else if (monsters.getMonsters().contains(damagee)) { + onMonsterDamage(event, damagee, damager); + } + } + + private void onPlayerDamage(EntityDamageEvent event, Player player, Entity damager) { + // Cancel all damage in the lobby and spec area + if (arena.inLobby(player) || arena.inSpec(player)) { + event.setCancelled(true); + return; + } + // If PvP is disabled and damager is a player, cancel damage + else if (arena.inArena(player)) { + if (!pvpEnabled && damager instanceof Player) { + event.setCancelled(true); + return; + } + event.setCancelled(false); + arena.getArenaPlayer(player).getStats().add("dmgTaken", event.getDamage()); + } + } + + private void onPetDamage(EntityDamageEvent event, Wolf pet, Entity damager) { + event.setCancelled(true); + } + + private void onMonsterDamage(EntityDamageEvent event, Entity monster, Entity damager) { + if (damager instanceof Player) { + Player p = (Player) damager; + if (!arena.inArena(p)) { + event.setCancelled(true); + return; + } + + ArenaPlayerStatistics aps = arena.getArenaPlayer(p).getStats(); + aps.add("dmgDone", event.getDamage()); + aps.inc("hits"); + } + else if (damager instanceof Wolf && arena.hasPet(damager)) { + event.setDamage(1); + Player p = (Player) ((Wolf) damager).getOwner(); + ArenaPlayerStatistics aps = arena.getArenaPlayer(p).getStats(); + aps.add("dmgDone", event.getDamage()); + // arena.getArenaPlayer(p).getStats().dmgDone += event.getDamage(); + } + else if (damager instanceof LivingEntity) { + if (!monsterInfight) + event.setCancelled(true); + } + } + + private void onBossDamage(EntityDamageEvent event, LivingEntity monster, Entity damager) { + // Health the boss back up. + monster.setHealth(monster.getMaxHealth()); + + // Damage the underlying MABoss. + MABoss boss = monsters.getBoss(monster); + boss.damage(event.getDamage()); + + // If it died, remove it from the arena. + if (boss.isDead()) { + monsters.removeBoss(monster); + monster.damage(10000); + } + + // And "cancel out" the damage. + event.setDamage(1); + } + + public void onEntityCombust(EntityCombustEvent event) { + if (monsters.getMonsters().contains(event.getEntity())) + event.setCancelled(true); + } + + public void onEntityTarget(EntityTargetEvent event) { + if (!arena.isRunning() || event.isCancelled()) + return; + + if (arena.hasPet(event.getEntity())) { + if (event.getReason() != TargetReason.TARGET_ATTACKED_OWNER && event.getReason() != TargetReason.OWNER_ATTACKED_TARGET) + return; + + if (!(event.getTarget() instanceof Player)) + return; + + // If the target is a player, cancel. + event.setCancelled(true); + } + + else if (monsters.getMonsters().contains(event.getEntity())) { + if (event.getReason() == TargetReason.FORGOT_TARGET) + event.setTarget(MAUtils.getClosestPlayer(plugin, event.getEntity(), arena)); + + else if (event.getReason() == TargetReason.TARGET_DIED) + event.setTarget(MAUtils.getClosestPlayer(plugin, event.getEntity(), arena)); + + else if (event.getReason() == TargetReason.TARGET_ATTACKED_ENTITY) + if (arena.hasPet(event.getTarget())) + event.setCancelled(true); + + else if (event.getReason() == TargetReason.CLOSEST_PLAYER) + if (!arena.inArena((Player) event.getTarget())) + event.setCancelled(true); + } + } + + public void onEntityChangeBlock(EntityChangeBlockEvent event) { + if (arena.getRegion().contains(event.getBlock().getLocation())) + event.setCancelled(true); + } + + public void onEntityRegainHealth(EntityRegainHealthEvent event) { + if (!arena.isRunning()) + return; + + if (!(event.getEntity() instanceof Player) || !arena.inArena((Player) event.getEntity())) + return; + + if (!foodRegen && event.getRegainReason() == RegainReason.SATIATED) { + event.setCancelled(true); + } + } + + public void onFoodLevelChange(FoodLevelChangeEvent event) { + if (!arena.isRunning()) + return; + + if (!(event.getEntity() instanceof Player) || !arena.inArena((Player) event.getEntity())) + return; + + // If the food level is locked, cancel all changes. + if (lockFoodLevel) + event.setCancelled(true); + } + + public void onPlayerAnimation(PlayerAnimationEvent event) { + if (!arena.isRunning() || !arena.inArena(event.getPlayer())) + return; + + arena.getArenaPlayer(event.getPlayer()).getStats().inc("swings"); + } + + public void onPlayerDropItem(PlayerDropItemEvent event) { + Player p = event.getPlayer(); + + // If the player is active in the arena, only cancel if sharing is not + // allowed + if (arena.inArena(p)) { + if (!canShare) { + Messenger.tellPlayer(p, Msg.LOBBY_DROP_ITEM); + event.setCancelled(true); + } + } + + // Else, if the player is in the lobby or a spectator, just cancel + else if (arena.inLobby(p) || arena.inSpec(p)) { + Messenger.tellPlayer(p, Msg.LOBBY_DROP_ITEM); + event.setCancelled(true); + } + + /* + * If the player is not in the arena in any way (as arena player, lobby + * player or a spectator), but they -are- in the region, it must mean + * they are trying to drop items when not allowed + */ + else if (region.contains(p.getLocation())) { + Messenger.tellPlayer(p, Msg.LOBBY_DROP_ITEM); + event.setCancelled(true); + } + + /* + * If the player is in the banned set, it means they got kicked or + * disconnected during a session, meaning they are more than likely + * trying to steal items, if a PlayerDropItemEvent is fired. + */ + else if (banned.contains(p)) { + plugin.warning("Player " + p.getName() + " tried to steal class items!"); + event.setCancelled(true); + } + } + + public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event) { + if (!arena.getReadyPlayersInLobby().contains(event.getPlayer()) && !arena.inArena(event.getPlayer())) + return; + + if (!arena.isRunning()) { + event.getBlockClicked().getRelative(event.getBlockFace()).setTypeId(0); + event.setCancelled(true); + return; + } + + Block liquid = event.getBlockClicked().getRelative(event.getBlockFace()); + arena.addBlock(liquid); + } + + public void onPlayerInteract(PlayerInteractEvent event) { + Player p = event.getPlayer(); + if (arena.inArena(p) || !arena.inLobby(p)) + return; + + // Player is in the lobby, so disallow using items. + Action a = event.getAction(); + if (a == Action.RIGHT_CLICK_AIR || a == Action.RIGHT_CLICK_BLOCK) { + event.setUseItemInHand(Result.DENY); + event.setCancelled(true); + } + + // If there's no block involved, just return. + if (!event.hasBlock()) + return; + + // Iron block + if (event.getClickedBlock().getTypeId() == 42) { + handleReadyBlock(p); + } + // Sign + else if (event.getClickedBlock().getState() instanceof Sign) { + Sign sign = (Sign) event.getClickedBlock().getState(); + handleSign(sign, p); + } + } + + private void handleReadyBlock(Player p) { + if (arena.getArenaPlayer(p).getArenaClass() != null) { + Messenger.tellPlayer(p, Msg.LOBBY_PLAYER_READY); + arena.playerReady(p); + } + else { + Messenger.tellPlayer(p, Msg.LOBBY_PICK_CLASS); + } + } + + private void handleSign(Sign sign, Player p) { + // Check if the first line is a class name. + String className = ChatColor.stripColor(sign.getLine(0)).toLowerCase(); + + if (!arena.getClasses().containsKey(className) && !className.equals("random")) + return; + + // Check for permission. + if (!plugin.has(p, "mobarena.classes." + className) && !className.equals("random")) { + Messenger.tellPlayer(p, Msg.LOBBY_CLASS_PERMISSION); + return; + } + + // Delay the inventory stuff to ensure that right-clicking works. + delayAssignClass(p, className); + } + + private void delayAssignClass(final Player p, final String className) { + plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin,new Runnable() { + public void run() { + arena.assignClass(p, className); + + if (!className.equalsIgnoreCase("random")) + Messenger.tellPlayer(p, Msg.LOBBY_CLASS_PICKED, TextUtils.camelCase(className), arena.getClassLogo(className)); + else + Messenger.tellPlayer(p, Msg.LOBBY_CLASS_RANDOM); + } + }); + } + + public void onPlayerQuit(PlayerQuitEvent event) { + Player p = event.getPlayer(); + if (!arena.isEnabled() || (!arena.inArena(p) && !arena.inLobby(p))) + return; + + arena.playerLeave(p); + banned.add(p); + scheduleUnban(p, 20); + } + + public void onPlayerKick(PlayerKickEvent event) { + Player p = event.getPlayer(); + if (!arena.isEnabled() || (!arena.inArena(p) && !arena.inLobby(p))) { + return; + } + + arena.playerLeave(p); + banned.add(p); + scheduleUnban(p, 20); + } + + private void scheduleUnban(final Player p, int ticks) { + plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { + public void run() { + banned.remove(p); + } + }, ticks); + } + + public TeleportResponse onPlayerTeleport(PlayerTeleportEvent event) { + if (!arena.isEnabled() || !region.isSetup() || arena.inEditMode() || allowTeleport) { + return TeleportResponse.IDGAF; + } + + Location to = event.getTo(); + Location from = event.getFrom(); + Player p = event.getPlayer(); + + if (region.contains(from)) { + // Players not in the arena are free to warp out. + if (!arena.inArena(p) && !arena.inLobby(p) && !arena.inSpec(p)) { + return TeleportResponse.ALLOW; + } + + // Covers the case in which both locations are in the arena. + if (region.contains(to) || region.isWarp(to) || to.equals(arena.getPlayerEntry(p))) { + return TeleportResponse.ALLOW; + } + + Messenger.tellPlayer(p, Msg.WARP_FROM_ARENA); + return TeleportResponse.REJECT; + } + else if (region.contains(to)) { + if (region.isWarp(from) || region.isWarp(to) || to.equals(arena.getPlayerEntry(p))) { + return TeleportResponse.ALLOW; + } + + Messenger.tellPlayer(p, Msg.WARP_TO_ARENA); + return TeleportResponse.REJECT; + } + + return TeleportResponse.IDGAF; + } + + public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) { + Player p = event.getPlayer(); + + if (event.isCancelled() || (!arena.inArena(p) && !arena.inLobby(p))) { + return; + } + + // This is safe, because commands will always have at least one element. + String base = event.getMessage().split(" ")[0]; + + // Check if the entire base command is allowed. + if (plugin.getArenaMaster().isAllowed(base)) { + return; + } + + // If not, check if the specific command is allowed. + String noslash = event.getMessage().substring(1); + if (plugin.getArenaMaster().isAllowed(noslash)) { + return; + } + + // This is dirty, but it ensures that commands are indeed blocked. + event.setMessage("/"); + + // Cancel the event regardless. + event.setCancelled(true); + Messenger.tellPlayer(p, Msg.MISC_COMMAND_NOT_ALLOWED); + } +} diff --git a/src/com/garbagemule/MobArena/ArenaLog.java b/src/com/garbagemule/MobArena/ArenaLog.java deleted file mode 100644 index 0c78f57..0000000 --- a/src/com/garbagemule/MobArena/ArenaLog.java +++ /dev/null @@ -1,141 +0,0 @@ -package com.garbagemule.MobArena; - -import java.sql.Timestamp; -import java.util.Date; -import java.util.HashMap; -import java.util.Map; - -import org.bukkit.entity.Player; - -import com.garbagemule.MobArena.util.data.PlainText; -import com.garbagemule.MobArena.util.data.Totals; -import com.garbagemule.MobArena.util.data.XML; -import com.garbagemule.MobArena.util.data.YAML; - -public class ArenaLog -{ - public MobArena plugin; - public Arena arena; - public Timestamp startTime, endTime; - public int lastWave; - - public Map players; - public Map distribution; - - /** - * Create a new ArenaLog. - * @param plugin MobArena instance - * @param arena The arena - */ - public ArenaLog(MobArena plugin, Arena arena) - { - this.plugin = plugin; - this.arena = arena; - this.players = new HashMap(arena.arenaPlayers.size()); - this.distribution = new HashMap(arena.classes.size()); - } - - /** - * Start logging by creating ArenaPlayer objects and recording - * the class distributions and the start time. - */ - public void start() - { - // Populate the data maps - populatePlayerMap(); - populateDistributionMap(); - - // Grab the current timestamp - startTime = new Timestamp((new Date()).getTime()); - } - - /** - * End logging by recording the last wave and the end time. - */ - public void end() - { - lastWave = arena.spawnThread.getWave() - 1; - endTime = new Timestamp((new Date()).getTime()); - } - - /** - * Map players to ArenaPlayer objects. - */ - private void populatePlayerMap() - { - for (Player p : arena.arenaPlayers) - players.put(p, new ArenaPlayer(p, arena, plugin)); - } - - /** - * Map classes to amounts of players playing as the classes. - */ - private void populateDistributionMap() - { - // Initialize the map - for (String c : arena.classes) - distribution.put(c,0); - - // Count occurrences - for (String c : arena.classMap.values()) - distribution.put(c,distribution.get(c) + 1); - } - - /** - * Save the data of the current session according to the logging type. - */ - public void saveSessionData() - { - if (arena.logging.equals("xml")) - XML.saveSessionData(this); - else if (arena.logging.equals("yml") || arena.logging.equals("yaml")) - YAML.saveSessionData(this); - else - PlainText.saveSessionData(this); - //CSV.saveSessionData(this, plugin); - //YAML.saveSessionData(this); - } - - /** - * Update the totals-file - */ - public void updateArenaTotals() - { - Totals.updateArenaTotals(this); - - if (arena.logging.equals("xml")) - XML.updateArenaTotals(this); - //PlainText.updateArenaTotals(this); - } - - /** - * Clear maps. - */ - public void clearSessionData() - { - players.clear(); - distribution.clear(); - } - - public Arena getArena() { return arena; } - public Timestamp getStartTime() { return startTime; } - public Timestamp getEndTime() { return endTime; } - public String getDuration() { return MAUtils.getDuration(endTime.getTime() - startTime.getTime()); } - public long getDurationLong() { return endTime.getTime() - startTime.getTime(); } - public int getLastWave() { return lastWave; } - - public void playerKill(Player p) - { - players.get(p).getStats().kills++; - } - - public void playerDamager(Player p, int damage) - { - players.get(p).getStats().dmgDone += damage; - } - - public void playerDamagee(Player p, int damage) - { - players.get(p).getStats().dmgTaken += damage; - } -} diff --git a/src/com/garbagemule/MobArena/ArenaMaster.java b/src/com/garbagemule/MobArena/ArenaMaster.java deleted file mode 100644 index 537fa4b..0000000 --- a/src/com/garbagemule/MobArena/ArenaMaster.java +++ /dev/null @@ -1,147 +0,0 @@ -package com.garbagemule.MobArena; - -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -//import org.bukkit.util.config.Configuration; - -//import com.garbagemule.ArenaPlugin.Master; - -public abstract class ArenaMaster //implements Master -{ - protected Arena selectedArena; - - // Settings - protected boolean enabled, updateNotify; - - // Classes - protected Set classes; - protected Map> classItems, classArmor; - protected Map> classPerms; - //protected Map>> classBonuses; - protected Map arenaMap; - - // Location map - protected Map locations = new HashMap(); - - // Arena list - protected List arenas; - - // Listeners - protected Set listeners = new HashSet(); - - - - /*///////////////////////////////////////////////////////////////////////// - // - // Arena getters - // - /////////////////////////////////////////////////////////////////////////*/ - - - public abstract List getEnabledArenas(); - - public abstract List getPermittedArenas(Player p); - - public abstract List getEnabledAndPermittedArenas(Player p); - - public abstract Arena getArenaAtLocation(Location loc); - - public abstract List getArenasInWorld(World world); - - public abstract List getAllPlayers(); - - public abstract List getAllPlayersInArena(String arenaName); - - public abstract List getAllLivingPlayers(); - - public abstract List getLivingPlayersInArena(String arenaName); - - public abstract Arena getArenaWithPlayer(Player p); - - public abstract Arena getArenaWithPlayer(String playerName); - - public abstract Arena getArenaWithSpectator(Player p); - - public abstract Arena getArenaWithMonster(Entity e); - - public abstract Arena getArenaWithPet(Entity e); - - public abstract Arena getArenaWithName(String configName); - - public abstract Arena getArenaWithName(Collection arenas, String configName); - - - - /*///////////////////////////////////////////////////////////////////////// - // - // Initialization - // - /////////////////////////////////////////////////////////////////////////*/ - - public abstract void initialize(); - - /** - * Load the global settings. - */ - public abstract void loadSettings(); - - /** - * Load all class-related stuff. - */ - public abstract void loadClasses(); - - /** - * Load all arena-related stuff. - */ - public abstract void loadArenas(); - - public abstract Arena createArenaNode(String configName, World world); - - public abstract void removeArenaNode(String configName); - - - - /*///////////////////////////////////////////////////////////////////////// - // - // Update and serialization methods - // - /////////////////////////////////////////////////////////////////////////*/ - - /** - * Update one, two or all three of global settings, classes - * and arenas (arenas with deserialization). - */ - public abstract void update(boolean settings, boolean classes, boolean arenalist); - - /** - * Serialize the global settings. - */ - public abstract void serializeSettings(); - - /** - * Serialize all arena configs. - */ - public abstract void serializeArenas(); - - /** - * Deserialize all arena configs. Updates the arena list to - * include only the current arenas (not ones added in the - * actual file) that are also in the config-file. - */ - public abstract void deserializeArenas(); - - public abstract void updateSettings(); - public abstract void updateClasses(); - public abstract void updateArenas(); - public abstract void updateAll(); -} diff --git a/src/com/garbagemule/MobArena/ArenaMasterImpl.java b/src/com/garbagemule/MobArena/ArenaMasterImpl.java new file mode 100644 index 0000000..7a61223 --- /dev/null +++ b/src/com/garbagemule/MobArena/ArenaMasterImpl.java @@ -0,0 +1,591 @@ +package com.garbagemule.MobArena; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; +import org.bukkit.permissions.Permission; +import org.bukkit.permissions.PermissionDefault; +import org.bukkit.plugin.PluginManager; + +import com.garbagemule.MobArena.ArenaImpl; +import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.ArenaClass.ArmorType; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; +import com.garbagemule.MobArena.util.ItemParser; +import com.garbagemule.MobArena.util.TextUtils; +import com.garbagemule.MobArena.util.config.Config; +import com.garbagemule.MobArena.util.config.ConfigSection; +import com.garbagemule.MobArena.util.config.ConfigUtils; + +public class ArenaMasterImpl implements ArenaMaster +{ + private MobArena plugin; + private Config config; + + private List arenas; + private Map arenaMap; + private Arena selectedArena; + + private Map classes; + + private Set allowedCommands; + + /** + * Default constructor. + */ + public ArenaMasterImpl(MobArena plugin) { + this.plugin = plugin; + this.config = plugin.getMAConfig(); + + this.arenas = new LinkedList(); + this.arenaMap = new HashMap(); + + this.classes = new HashMap(); + + this.allowedCommands = new HashSet(); + } + + /* + * ///////////////////////////////////////////////////////////////////////// + * // // NEW METHODS IN REFACTORING // + * ///////////////////////////////////////////////////////////////////////// + */ + + public MobArena getPlugin() { + return plugin; + } + + public boolean isEnabled() { + return config.getBoolean("global-settings.enabled", true); + } + + public void setEnabled(boolean value) { + config.set("global-settings.enabled", value); + } + + public boolean notifyOnUpdates() { + return config.getBoolean("global-settings.update-notification", false); + } + + public Arena getSelectedArena() { + return selectedArena; + } + + public void setSelectedArena(Arena arena) { + selectedArena = arena; + } + + public List getArenas() { + return arenas; + } + + public Map getClasses() { + return classes; + } + + public void addPlayer(Player p, Arena arena) { + arenaMap.put(p, arena); + } + + public Arena removePlayer(Player p) { + return arenaMap.remove(p); + } + + public void resetArenaMap() { + arenaMap.clear(); + } + + public boolean isAllowed(String command) { + return allowedCommands.contains(command); + } + + /* + * ///////////////////////////////////////////////////////////////////////// + * // // Arena getters // + * ///////////////////////////////////////////////////////////////////////// + */ + + public List getEnabledArenas() { + List result = new LinkedList(); + for (Arena arena : arenas) + if (arena.isEnabled()) + result.add(arena); + return result; + } + + public List getPermittedArenas(Player p) { + List result = new LinkedList(); + for (Arena arena : arenas) + if (plugin.has(p, "mobarena.arenas." + arena.configName())) + result.add(arena); + return result; + } + + public List getEnabledAndPermittedArenas(Player p) { + List result = new LinkedList(); + for (Arena arena : arenas) + if (arena.isEnabled() && plugin.has(p, "mobarena.arenas." + arena.configName())) + result.add(arena); + return result; + } + + public Arena getArenaAtLocation(Location loc) { + for (Arena arena : arenas) + if (arena.getRegion().contains(loc)) + return arena; + return null; + } + + public List getArenasInWorld(World world) { + List result = new LinkedList(); + for (Arena arena : arenas) + if (arena.getWorld().equals(world)) + result.add(arena); + return result; + } + + public List getAllPlayers() { + List result = new LinkedList(); + for (Arena arena : arenas) + result.addAll(arena.getAllPlayers()); + return result; + } + + public List getAllPlayersInArena(String arenaName) { + Arena arena = getArenaWithName(arenaName); + return (arena != null) ? new LinkedList(arena.getPlayersInArena()) : new LinkedList(); + } + + public List getAllLivingPlayers() { + List result = new LinkedList(); + for (Arena arena : arenas) + result.addAll(arena.getPlayersInArena()); + return result; + } + + public List getLivingPlayersInArena(String arenaName) { + Arena arena = getArenaWithName(arenaName); + return (arena != null) ? new LinkedList(arena.getPlayersInArena()) : new LinkedList(); + } + + public Arena getArenaWithPlayer(Player p) { + return arenaMap.get(p); + } + + public Arena getArenaWithPlayer(String playerName) { + return arenaMap.get(plugin.getServer().getPlayer(playerName)); + } + + public Arena getArenaWithSpectator(Player p) { + for (Arena arena : arenas) { + if (arena.getSpectators().contains(p)) + return arena; + } + return null; + } + + public Arena getArenaWithMonster(Entity e) { + for (Arena arena : arenas) + if (arena.getMonsterManager().getMonsters().contains(e)) + return arena; + return null; + } + + public Arena getArenaWithPet(Entity e) { + for (Arena arena : arenas) + if (arena.hasPet(e)) + return arena; + return null; + } + + public Arena getArenaWithName(String configName) { + return getArenaWithName(this.arenas, configName); + } + + public Arena getArenaWithName(Collection arenas, String configName) { + for (Arena arena : arenas) + if (arena.configName().equals(configName)) + return arena; + return null; + } + + /* + * ///////////////////////////////////////////////////////////////////////// + * // // Initialization // + * ///////////////////////////////////////////////////////////////////////// + */ + + public void initialize() { + config.load(); + loadSettings(); + loadClasses(); + loadArenas(); + config.save(); + } + + /** + * Load the global settings. + */ + public void loadSettings() { + ConfigUtils.replaceAllNodes(plugin, config, "global-settings", "global-settings.yml"); + ConfigSection section = config.getConfigSection("global-settings"); + + // Grab the commands string + String cmds = section.getString("allowed-commands", ""); + + // Split by commas + String[] parts = cmds.split(","); + + // Add in the /ma command. + allowedCommands.add("/ma"); + + // Add in each command + for (String part : parts) { + allowedCommands.add(part.trim().toLowerCase()); + } + } + + /** + * Load all class-related stuff. + */ + public void loadClasses() { + Set classNames = config.getKeys("classes"); + + // If no classes were found, load the defaults. + if (classNames == null || classNames.isEmpty()) { + loadDefaultClasses(); + classNames = config.getKeys("classes"); + } + + // Establish the map. + classes = new HashMap(); + + // Load each individual class. + for (String className : classNames) { + loadClass(className.toLowerCase()); + } + } + + /** + * Loads the classes in res/classes.yml into the config-file. + */ + public void loadDefaultClasses() { + ConfigUtils.addMissingNodes(plugin, config, "classes", "classes.yml"); + } + + /** + * Helper method for loading a single class. + */ + private ArenaClass loadClass(String className) { + // Grab the class section. + ConfigSection section = config.getConfigSection("classes." + TextUtils.camelCase(className)); + + // If the section doesn't exist, the class doesn't either. + if (section == null) { + plugin.error("Failed to load class '" + TextUtils.camelCase(className) + "'."); + return null; + } + + ArenaClass arenaClass = new ArenaClass(className); + + // Parse the items-node + String items = section.getString("items", ""); + if (!items.equals("")) { + List stacks = ItemParser.parseItems(items); + arenaClass.setItems(stacks); + } + + // And the legacy armor-node + String armor = section.getString("armor", ""); + if (!armor.equals("")) { + List stacks = ItemParser.parseItems(armor); + arenaClass.setArmor(stacks); + } + + // Get armor strings + String head = section.getString("helmet", null); + String chest = section.getString("chestplate", null); + String legs = section.getString("leggings", null); + String feet = section.getString("boots", null); + + // Parse to ItemStacks + ItemStack helmet = ItemParser.parseItem(head); + ItemStack chestplate = ItemParser.parseItem(chest); + ItemStack leggings = ItemParser.parseItem(legs); + ItemStack boots = ItemParser.parseItem(feet); + + // Set in ArenaClass + arenaClass.setHelmet(helmet); + arenaClass.setChestplate(chestplate); + arenaClass.setLeggings(leggings); + arenaClass.setBoots(boots); + + // Per-class permissions + loadClassPermissions(arenaClass, section); + + // Register the permission. + registerPermission("mobarena.classes." + className, PermissionDefault.TRUE).addParent("mobarena.classes", true); + + // Finally add the class to the classes map. + classes.put(className, arenaClass); + return arenaClass; + } + + private void loadClassPermissions(ArenaClass arenaClass, ConfigSection section) { + List perms = section.getStringList("permissions", null); + if (perms.isEmpty()) + return; + + for (String perm : perms) { + // If the permission starts with - or ^, it must be revoked. + boolean value = true; + if (perm.startsWith("-") || perm.startsWith("^")) { + perm = perm.substring(1).trim(); + value = false; + } + arenaClass.addPermission(perm, value); + } + } + + public ArenaClass createClassNode(String className, PlayerInventory inv, boolean safe) { + String path = "classes." + TextUtils.camelCase(className); + if (safe && config.getConfigSection(path) != null) { + return null; + } + + // Create the node. + config.set(path, ""); + + // Grab the section. + ConfigSection section = config.getConfigSection(path); + + // Take the current items and armor. + section.set("items", ItemParser.parseString(inv.getContents())); + section.set("armor", ItemParser.parseString(inv.getArmorContents())); + + // If the helmet isn't a real helmet, set it explicitly. + ItemStack helmet = inv.getHelmet(); + if (helmet.getTypeId() != 0 && ArmorType.getType(helmet) != ArmorType.HELMET) { + section.set("helmet", ItemParser.parseString(helmet)); + } + + // Save changes. + config.save(); + + // Load the class + return loadClass(className.toLowerCase()); + } + + public void removeClassNode(String className) { + if (!classes.containsKey(className.toLowerCase())) + throw new IllegalArgumentException("Class does not exist!"); + + // Remove the class from the config-file and save it. + config.remove("classes." + className); + config.save(); + + // Remove the class from the map. + classes.remove(className.toLowerCase()); + + unregisterPermission("mobarena.arenas." + className.toLowerCase()); + } + + public boolean addClassPermission(String className, String perm) { + return addRemoveClassPermission(className, perm, true); + } + + public boolean removeClassPermission(String className, String perm) { + return addRemoveClassPermission(className, perm, false); + } + + private boolean addRemoveClassPermission(String className, String perm, boolean add) { + String path = "classes." + TextUtils.camelCase(className); + if (config.getConfigSection(path) == null) + return false; + + // Grab the class section + ConfigSection section = config.getConfigSection(path); + + // Get any previous nodes + List nodes = section.getStringList("permissions", null); + if (nodes.contains(perm)) + return false; + + // Add or remove. + if (add) { + removeContradictions(nodes, perm); + nodes.add(perm); + } + else { + nodes.remove(perm); + } + + // Replace the set. + section.set("permissions", nodes); + config.save(); + + // Reload the class. + loadClass(className); + return true; + } + + /** + * Removes any nodes that would contradict the permission, e.g. if the node + * 'mobarena.use' is in the set, and the perm node is '-mobarena.use', the + * '-mobarena.use' node is removed as to not contradict the new + * 'mobarena.use' node. + */ + private void removeContradictions(List nodes, String perm) { + if (perm.startsWith("^") || perm.startsWith("-")) { + nodes.remove(perm.substring(1).trim()); + } + else { + nodes.remove("^" + perm); + nodes.remove("-" + perm); + } + } + + /** + * Load all arena-related stuff. + */ + public void loadArenas() { + Set arenaNames = config.getKeys("arenas"); + + // If no arenas were found, create a default node. + if (arenaNames == null || arenaNames.isEmpty()) { + createArenaNode("default", plugin.getServer().getWorlds().get(0)); + arenaNames = config.getKeys("arenas"); + } + + // Establish the list. + arenas = new LinkedList(); + + for (String arenaName : arenaNames) { + loadArena(arenaName); + } + + selectedArena = arenas.get(0); + } + + private Arena loadArena(String arenaName) { + String path = "arenas." + arenaName; + String worldName = config.getString(path + ".settings.world", ""); + World world = null; + + // If a string was found, try to fetch the world from the server. + if (!worldName.equals("")) { + world = plugin.getServer().getWorld(worldName); + + if (world == null) { + plugin.error("The world '" + worldName + "' for arena '" + arenaName + "' does not exist!"); + return null; + } + } + // Otherwise, use the default world. + else { + world = plugin.getServer().getWorlds().get(0); + plugin.warning("Could not find the world for arena '" + arenaName + "'. Using default world ('" + world.getName() + "')! Check the config-file!"); + } + + // Assert all settings nodes. + ConfigUtils.replaceAllNodes(plugin, config, path + ".settings", "settings.yml"); + + // Create an Arena with the name and world. + Arena arena = new ArenaImpl(plugin, config, arenaName, world); + + // Register the permission + registerPermission("mobarena.arenas." + arenaName, PermissionDefault.TRUE); + + // Finally, add it to the arena list. + arenas.add(arena); + return arena; + } + + public Arena createArenaNode(String arenaName, World world) { + String path = "arenas." + arenaName; + if (config.getConfigSection(path) != null) + throw new IllegalArgumentException("Arena already exists!"); + + // Extract the default settings and update the world-node. + ConfigUtils.replaceAllNodes(plugin, config, path + ".settings", "settings.yml"); + config.set(path + ".settings.world", world.getName()); + + // Extract the default waves. + ConfigUtils.replaceAllNodes(plugin, config, path + ".waves", "waves.yml"); + + // Extract the default rewards. + ConfigUtils.replaceAllNodes(plugin, config, path + ".rewards", "rewards.yml"); + + // Save the changes. + config.save(); + + // Load the arena + return loadArena(arenaName); + } + + public void removeArenaNode(Arena arena) { + // Remove the arena from the config-file and save it. + config.remove("arenas." + arena.configName()); + config.save(); + + // Remove the arena from the list. + arenas.remove(arena); + + unregisterPermission("mobarena.arenas." + arena.configName()); + } + + public void reloadConfig() { + boolean wasEnabled = isEnabled(); + + // If MobArena was enabled, disable it before updating. + if (wasEnabled) { + setEnabled(false); + } + + for (Arena a : arenas) { + a.forceEnd(); + } + + config.load(); + loadSettings(); + loadClasses(); + loadArenas(); + + // If MobArena was enabled, re-enable it after updating. + if (wasEnabled) { + setEnabled(true); + } + } + + public void saveConfig() { + config.save(); + } + + private Permission registerPermission(String permString, PermissionDefault value) { + PluginManager pm = plugin.getServer().getPluginManager(); + + Permission perm = pm.getPermission(permString); + if (perm == null) { + perm = new Permission(permString); + perm.setDefault(value); + pm.addPermission(perm); + } + return perm; + } + + private void unregisterPermission(String s) { + plugin.getServer().getPluginManager().removePermission(s); + } +} diff --git a/src/com/garbagemule/MobArena/ArenaMasterStandard.java b/src/com/garbagemule/MobArena/ArenaMasterStandard.java deleted file mode 100644 index e89fff6..0000000 --- a/src/com/garbagemule/MobArena/ArenaMasterStandard.java +++ /dev/null @@ -1,388 +0,0 @@ -package com.garbagemule.MobArena; - -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; - -import com.garbagemule.MobArena.util.Config; - -public class ArenaMasterStandard extends ArenaMaster -{ - private MobArena plugin; - private Config config; - - - - /** - * Default constructor. - */ - public ArenaMasterStandard(MobArenaPlugin instance) - { - plugin = (MobArena) instance; - config = plugin.getMAConfig(); - arenas = new LinkedList(); - arenaMap = new HashMap(); - } - - - - /*///////////////////////////////////////////////////////////////////////// - // - // Arena getters - // - /////////////////////////////////////////////////////////////////////////*/ - - public List getEnabledArenas() - { - List result = new LinkedList(); - for (Arena arena : arenas) - if (arena.enabled) - result.add(arena); - return result; - } - - public List getPermittedArenas(Player p) - { - List result = new LinkedList(); - for (Arena arena : arenas) - if (plugin.has(p, "mobarena.arenas." + arena.configName())) - result.add(arena); - return result; - } - - public List getEnabledAndPermittedArenas(Player p) - { - List result = new LinkedList(); - for (Arena arena : arenas) - if (arena.enabled && plugin.has(p, "mobarena.arenas." + arena.configName())) - result.add(arena); - return result; - } - - public Arena getArenaAtLocation(Location loc) - { - for (Arena arena : arenas) - if (arena.inRegion(loc)) - return arena; - return null; - } - - public List getArenasInWorld(World world) - { - List result = new LinkedList(); - for (Arena arena : arenas) - if (arena.world.equals(world)) - result.add(arena); - return result; - } - - public List getAllPlayers() - { - List result = new LinkedList(); - for (Arena arena : arenas) - result.addAll(arena.getAllPlayers()); - return result; - } - - public List getAllPlayersInArena(String arenaName) - { - Arena arena = getArenaWithName(arenaName); - return (arena != null) ? arena.getLivingPlayers() : new LinkedList(); - } - - public List getAllLivingPlayers() - { - List result = new LinkedList(); - for (Arena arena : arenas) - result.addAll(arena.getLivingPlayers()); - return result; - } - - public List getLivingPlayersInArena(String arenaName) - { - Arena arena = getArenaWithName(arenaName); - return (arena != null) ? arena.getLivingPlayers() : new LinkedList(); - } - - public Arena getArenaWithPlayer(Player p) - { - return arenaMap.get(p); - } - - public Arena getArenaWithPlayer(String playerName) - { - return arenaMap.get(Bukkit.getServer().getPlayer(playerName)); - } - - public Arena getArenaWithSpectator(Player p) - { - for (Arena arena : arenas) - { - if (arena.specPlayers.contains(p)) - return arena; - } - return null; - } - - public Arena getArenaWithMonster(Entity e) - { - for (Arena arena : arenas) - if (arena.monsters.contains(e)) - return arena; - return null; - } - - public Arena getArenaWithPet(Entity e) - { - for (Arena arena : arenas) - if (arena.pets.contains(e)) - return arena; - return null; - } - - public Arena getArenaWithName(String configName) - { - return getArenaWithName(this.arenas, configName); - } - - public Arena getArenaWithName(Collection arenas, String configName) - { - for (Arena arena : arenas) - if (arena.configName().equals(configName)) - return arena; - return null; - } - - - - /*///////////////////////////////////////////////////////////////////////// - // - // Initialization - // - /////////////////////////////////////////////////////////////////////////*/ - - public void initialize() - { - config.load(); - loadSettings(); - loadClasses(); - loadArenas(); - config.save(); - } - - /** - * Load the global settings. - */ - public void loadSettings() - { - if (config.getKeys("global-settings") == null) - { - config.setProperty("global-settings.enabled", true); - config.setProperty("global-settings.update-notification", true); - } - - enabled = config.getBoolean("global-settings.enabled", true); - updateNotify = config.getBoolean("global-settings.update-notification", true); - } - - /** - * Load all class-related stuff. - */ - public void loadClasses() - { - classes = config.getKeys("classes"); - if (classes == null) - { - config.setProperty("classes.Archer.items", "wood_sword, bow, arrow:128, grilled_pork"); - config.setProperty("classes.Archer.armor", "298,299,300,301"); - config.setProperty("classes.Knight.items", "diamond_sword, grilled_pork:2"); - config.setProperty("classes.Knight.armor", "306,307,308,309"); - config.setProperty("classes.Tank.items", "iron_sword, grilled_pork:3, apple"); - config.setProperty("classes.Tank.armor", "310,311,312,313"); - config.setProperty("classes.Oddjob.items", "stone_sword, flint_and_steel, netherrack:2, wood_pickaxe, tnt:4, fishing_rod, apple, grilled_pork:3"); - config.setProperty("classes.Oddjob.armor", "298,299,300,301"); - config.setProperty("classes.Chef.items", "stone_sword, bread:6, grilled_pork:4, mushroom_soup, cake:3, cookie:12"); - config.setProperty("classes.Chef.armor", "314,315,316,317"); - classes = config.getKeys("classes"); - } - classItems = MAUtils.getClassItems(config, "items"); - classArmor = MAUtils.getClassItems(config, "armor"); - classPerms = MAUtils.getClassPerms(config); - } - - /** - * Load all arena-related stuff. - */ - public void loadArenas() - { - arenas = new LinkedList(); - - if (config.getKeys("arenas") == null) - createArenaNode("default", Bukkit.getServer().getWorlds().get(0)); - - for (String configName : config.getKeys("arenas")) - { - String arenaPath = "arenas." + configName + "."; - String worldName = config.getString(arenaPath + "settings.world", null); - World world; - if (worldName == null || worldName.equals("")) - { - MobArena.warning("Could not find the world for arena '" + configName + "'. Using default world! Check the config-file!"); - world = Bukkit.getServer().getWorlds().get(0); - } - else world = Bukkit.getServer().getWorld(worldName); - - Arena arena = new ArenaStandard(MAUtils.nameConfigToArena(configName), world); - arena.load(config); - arenas.add(arena); - } - - selectedArena = arenas.get(0); - } - - public Arena createArenaNode(String configName, World world) - { - config.setProperty("arenas." + configName + ".settings.world", world.getName()); - config.save(); - config.load(); - config.setProperty("arenas." + configName + ".settings.enabled", true); - config.save(); - config.load(); - config.setProperty("arenas." + configName + ".settings.protect", true); - config.save(); - config.load(); - config.setProperty("arenas." + configName + ".settings.entry-fee", ""); - config.save(); - config.load(); - config.setProperty("arenas." + configName + ".settings.logging", false); - config.setProperty("arenas." + configName + ".settings.clear-wave-before-next", false); - config.setProperty("arenas." + configName + ".settings.detonate-creepers", false); - config.setProperty("arenas." + configName + ".settings.detonate-damage", false); - config.setProperty("arenas." + configName + ".settings.lightning", true); - config.setProperty("arenas." + configName + ".settings.auto-equip-armor", true); - config.setProperty("arenas." + configName + ".settings.force-restore", false); - config.setProperty("arenas." + configName + ".settings.soft-restore", false); - config.setProperty("arenas." + configName + ".settings.soft-restore-drops", false); - config.setProperty("arenas." + configName + ".settings.require-empty-inv-join", true); - config.setProperty("arenas." + configName + ".settings.require-empty-inv-spec", true); - config.setProperty("arenas." + configName + ".settings.hellhounds", false); - config.setProperty("arenas." + configName + ".settings.pvp-enabled", false); - config.setProperty("arenas." + configName + ".settings.monster-infight", false); - config.setProperty("arenas." + configName + ".settings.allow-teleporting", false); - config.setProperty("arenas." + configName + ".settings.spectate-on-death", true); - config.setProperty("arenas." + configName + ".settings.share-items-in-arena", true); - config.save(); - config.load(); - config.setProperty("arenas." + configName + ".settings.player-limit", 0); - config.setProperty("arenas." + configName + ".settings.max-join-distance", 0); - config.save(); - config.load(); - config.setProperty("arenas." + configName + ".settings.repair-delay", 5); - config.setProperty("arenas." + configName + ".settings.first-wave-delay", 5); - config.setProperty("arenas." + configName + ".settings.wave-interval", 20); - config.setProperty("arenas." + configName + ".settings.special-modulo", 4); - config.setProperty("arenas." + configName + ".settings.max-idle-time", 0); - config.save(); - config.load(); - - Arena arena = new ArenaStandard(MAUtils.nameConfigToArena(configName), world); - arena.load(config); - return arena; - } - - public void removeArenaNode(String configName) - { - config.removeProperty("arenas." + configName); - config.save(); - } - - - - /*///////////////////////////////////////////////////////////////////////// - // - // Update and serialization methods - // - /////////////////////////////////////////////////////////////////////////*/ - - /** - * Update one, two or all three of global settings, classes - * and arenas (arenas with deserialization). - */ - public void update(boolean settings, boolean classes, boolean arenalist) - { - boolean tmp = enabled; - enabled = false; - - for (Arena arena : arenas) - arena.forceEnd(); - - config.load(); - if (settings) loadSettings(); - if (classes) loadClasses(); - if (arenalist) deserializeArenas(); - config.save(); - - enabled = tmp; - } - - /** - * Serialize the global settings. - */ - public void serializeSettings() - { - String settings = "global-settings."; - config.setProperty(settings + "enabled", enabled); - config.save(); - } - - /** - * Serialize all arena configs. - */ - public void serializeArenas() - { - for (Arena arena : arenas) - arena.serializeConfig(); - } - - /** - * Deserialize all arena configs. Updates the arena list to - * include only the current arenas (not ones added in the - * actual file) that are also in the config-file. - */ - public void deserializeArenas() - { - // Get only the arenas in the config. - Set strings = config.getKeys("arenas"); - if (strings == null) - return; - - // Get their Arena objects. - List configArenas = new LinkedList(); - for (String s : strings) - if (getArenaWithName(s) != null) - configArenas.add(getArenaWithName(s)); - - // Remove all Arenas no longer in the config. - arenas.retainAll(configArenas); - - for (Arena arena : arenas) - arena.deserializeConfig(); - - // Make sure to update the selected arena to a valid one. - if (!arenas.contains(selectedArena) && arenas.size() >= 1) - selectedArena = arenas.get(0); - } - - public void updateSettings() { update(true, false, false); } - public void updateClasses() { update(false, true, false); } - public void updateArenas() { update(false, false, true); } - public void updateAll() { update(true, true, true); } -} diff --git a/src/com/garbagemule/MobArena/ArenaPlayer.java b/src/com/garbagemule/MobArena/ArenaPlayer.java index 359eae8..9d84cb2 100644 --- a/src/com/garbagemule/MobArena/ArenaPlayer.java +++ b/src/com/garbagemule/MobArena/ArenaPlayer.java @@ -1,59 +1,63 @@ package com.garbagemule.MobArena; -import java.util.LinkedList; -import java.util.List; - -import org.bukkit.block.Block; import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; + +import com.garbagemule.MobArena.ArenaPlayerStatistics; +import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.framework.Arena; public class ArenaPlayer { - public MobArena plugin; - public Player player; - public String className; - public Arena arena; - public List rewards; - public List blocks; - + private Player player; + + private ArenaClass arenaClass; private ArenaPlayerStatistics stats; - - protected boolean isDead, inArena, inLobby, inSpec, isReady; - - public ArenaPlayer(Player player, Arena arena, MobArena plugin) - { + private boolean isDead; + + //private List rewards; + //private List blocks; + + public ArenaPlayer(Player player, Arena arena, MobArena plugin) { this.player = player; - this.arena = arena; - this.plugin = plugin; - - className = arena.classMap.get(player); - rewards = new LinkedList(); - blocks = new LinkedList(); - - stats = new ArenaPlayerStatistics(this); } - - public Player getPlayer() { return player; } - public Arena getArena() { return arena; } - public String getClassName() { return className; } - + + public Player getPlayer() { + return player; + } + + public ArenaClass getArenaClass() { + return arenaClass; + } + + public void setArenaClass(ArenaClass arenaClass) { + this.arenaClass = arenaClass; + } + /** * Check if the player is "dead", i.e. died or not. * @return true, if the player is either a spectator or played and died, false otherwise */ - public boolean isDead() - { + public boolean isDead() { return isDead; } - + /** * Set the player's death status. * @param value true, if the player is dead, false otherwise */ - public void setDead(boolean value) - { + public void setDead(boolean value) { isDead = value; } - - public ArenaPlayerStatistics getStats() { return stats; } + + public void resetStats() { + if (stats != null) { + stats.reset(); + return; + } + stats = new ArenaPlayerStatistics(this); + } + + public ArenaPlayerStatistics getStats() { + return stats; + } } diff --git a/src/com/garbagemule/MobArena/ArenaPlayerStatistics.java b/src/com/garbagemule/MobArena/ArenaPlayerStatistics.java index 8b0289e..30792cf 100644 --- a/src/com/garbagemule/MobArena/ArenaPlayerStatistics.java +++ b/src/com/garbagemule/MobArena/ArenaPlayerStatistics.java @@ -1,91 +1,130 @@ package com.garbagemule.MobArena; import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; import org.bukkit.entity.Player; +import com.garbagemule.MobArena.ArenaPlayer; +import com.garbagemule.MobArena.ArenaPlayerStatistics; +import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.util.MutableInt; + public class ArenaPlayerStatistics { - private String playerName, className; private ArenaPlayer player; - public int kills, dmgDone, dmgTaken, swings, hits, lastWave; - - public ArenaPlayerStatistics(ArenaPlayer player) - { - this.player = player; + private String playerName, className; + private Map ints; + + public ArenaPlayerStatistics(ArenaPlayer player) { + this.player = player; this.playerName = player.getPlayer().getName(); - this.className = player.getClassName(); + this.className = player.getArenaClass().getName(); + reset(); } - - public ArenaPlayerStatistics(Player p, Arena arena, MobArena plugin) - { + + public void reset() { + if (ints == null) { + ints = new HashMap(); + } + + ints.clear(); + + ints.put("kills", new MutableInt()); + ints.put("dmgDone", new MutableInt()); + ints.put("dmgTaken", new MutableInt()); + ints.put("swings", new MutableInt()); + ints.put("hits", new MutableInt()); + ints.put("lastWave", new MutableInt()); + } + + public ArenaPlayerStatistics(Player p, Arena arena, MobArena plugin) { this(new ArenaPlayer(p, arena, plugin)); } - - public ArenaPlayer getArenaPlayer() - { + + public ArenaPlayer getArenaPlayer() { return player; } - - public static Comparator killComparator() - { - return new Comparator() - { - public int compare(ArenaPlayerStatistics s1, ArenaPlayerStatistics s2) - { - if (s1.kills > s2.kills) - return -1; - else if (s1.kills < s2.kills) - return 1; + + public String getPlayerName() { + return playerName; + } + + public String getClassName() { + return className; + } + + public int getInt(String s) { + return ints.get(s).value(); + } + + public void inc(String s) { + ints.get(s).inc(); + } + + public void add(String s, int amount) { + ints.get(s).add(amount); + } + + public static Comparator killComparator() { + return new Comparator() { + public int compare(ArenaPlayerStatistics s1, ArenaPlayerStatistics s2) { + int s1kills = s1.getInt("kills"); + int s2kills = s2.getInt("kills"); + + if (s1kills == s2kills) return 0; - } - }; + + return (s1kills > s2kills ? -1 : 1); + } + }; } - - private static int compareKills(ArenaPlayerStatistics s1, ArenaPlayerStatistics s2) - { - if (s1.kills > s2.kills) - return -1; - else if (s1.kills < s2.kills) - return 1; - return 0; + + public static Comparator waveComparator() { + return new Comparator() { + public int compare(ArenaPlayerStatistics s1, ArenaPlayerStatistics s2) { + int result = compareWaves(s1, s2); + if (result != 0) + return result; + + return compareKills(s1, s2); + } + }; } - - public static Comparator waveComparator() - { - return new Comparator() - { - public int compare(ArenaPlayerStatistics s1, ArenaPlayerStatistics s2) - { - int result = compareWaves(s1, s2); - if (result != 0) return result; - - return compareKills(s1, s2); - } - }; - } - - private static int compareWaves(ArenaPlayerStatistics s1, ArenaPlayerStatistics s2) - { - if (s1.lastWave > s2.lastWave) - return -1; - else if (s1.lastWave < s2.lastWave) - return 1; - return 0; - } - - public static Comparator dmgDoneComparator() - { - return new Comparator() - { - public int compare(ArenaPlayerStatistics s1, ArenaPlayerStatistics s2) - { - if (s1.dmgDone > s2.dmgDone) - return -1; - else if (s1.dmgDone < s2.dmgDone) - return 1; + + public static Comparator dmgDoneComparator() { + return new Comparator() { + public int compare(ArenaPlayerStatistics s1, ArenaPlayerStatistics s2) { + int s1dmgDone = s1.getInt("dmgDone"); + int s2dmgDone = s2.getInt("dmgDone"); + + if (s1dmgDone == s2dmgDone) return 0; - } - }; + + return (s1dmgDone > s2dmgDone ? -1 : 1); + } + }; + } + + private static int compareKills(ArenaPlayerStatistics s1, ArenaPlayerStatistics s2) { + int s1kills = s1.getInt("kills"); + int s2kills = s2.getInt("kills"); + + if (s1kills == s2kills) + return 0; + + return (s1kills > s2kills ? -1 : 1); + } + + private static int compareWaves(ArenaPlayerStatistics s1, ArenaPlayerStatistics s2) { + int s1wave = s1.getInt("lastWave"); + int s2wave = s2.getInt("lastWave"); + + if (s1wave == s2wave) + return 0; + + return (s1wave > s2wave ? -1 : 1); } } diff --git a/src/com/garbagemule/MobArena/ArenaStandard.java b/src/com/garbagemule/MobArena/ArenaStandard.java deleted file mode 100644 index f40e854..0000000 --- a/src/com/garbagemule/MobArena/ArenaStandard.java +++ /dev/null @@ -1,1413 +0,0 @@ -package com.garbagemule.MobArena; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.Set; -import java.util.TreeSet; -import java.util.concurrent.PriorityBlockingQueue; - -import net.minecraft.server.WorldServer; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Chunk; -import org.bukkit.GameMode; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.block.BlockState; -import org.bukkit.block.ContainerBlock; -import org.bukkit.craftbukkit.CraftWorld; -import org.bukkit.craftbukkit.entity.CraftEntity; -import org.bukkit.entity.Creature; -import org.bukkit.entity.CreatureType; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Item; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.entity.Slime; -import org.bukkit.entity.Wolf; -import org.bukkit.event.entity.EntityRegainHealthEvent; -import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; -import org.bukkit.permissions.PermissionAttachment; -//import org.bukkit.util.config.Configuration; - -import com.garbagemule.MobArena.leaderboards.Leaderboard; -import com.garbagemule.MobArena.repairable.Repairable; -import com.garbagemule.MobArena.repairable.RepairableComparator; -import com.garbagemule.MobArena.repairable.RepairableContainer; -import com.garbagemule.MobArena.spout.Spouty; -import com.garbagemule.MobArena.util.Config; -import com.garbagemule.MobArena.util.Delays; -import com.garbagemule.MobArena.util.InventoryItem; -import com.garbagemule.MobArena.util.WaveUtils; -import com.garbagemule.MobArena.waves.BossWave; -import com.garbagemule.MobArena.waves.Wave; -import com.garbagemule.MobArena.waves.Wave.WaveBranch; - -public class ArenaStandard extends Arena -{ - private MobArena plugin; - - /** - * Primary constructor. Requires a name and a world. - */ - public ArenaStandard(String name, World world) - { - if (world == null) - throw new NullPointerException("[MobArena] ERROR! World for arena '" + name + "' does not exist!"); - - this.name = name; - this.world = world; - plugin = (MobArena) Bukkit.getServer().getPluginManager().getPlugin("MobArena"); - - arenaPlayers = new HashSet(); - lobbyPlayers = new HashSet(); - notifyPlayers = new HashSet(); - readyPlayers = new HashSet(); - specPlayers = new HashSet(); - rewardedPlayers = new HashSet(); - hasPaid = new HashSet(); - monsters = new HashSet(); - explodingSheep = new HashSet(); - plaguedPigs = new HashSet(); - madCows = new HashSet(); - blocks = new HashSet(); - pets = new HashSet(); - petMap = new HashMap(); - classMap = new HashMap(); - randoms = new HashSet(); - repairables = new LinkedList(); - containables = new LinkedList(); - attachments = new HashMap(); - arenaPlayerMap = new HashMap(); - - running = false; - edit = false; - - allowMonsters = world.getAllowMonsters(); - allowAnimals = world.getAllowAnimals(); - spawnMonsters = MAUtils.getSpawnMonsters(world); - - eventListener = new MAListener(this, plugin); - repairQueue = new PriorityBlockingQueue(100, new RepairableComparator()); - } - - public boolean startArena() - { - // Sanity-checks - if (running || lobbyPlayers.isEmpty() || !readyPlayers.containsAll(lobbyPlayers)) - return false; - if (!softRestore && forceRestore && !serializeRegion()) - return false; - - // Store all chest contents. - storeContainerContents(); - - // Populate arenaPlayers and clear the lobby. - arenaPlayers.addAll(lobbyPlayers); - lobbyPlayers.clear(); - readyPlayers.clear(); - - // Assign random classes. - for (Player p : randoms) - assignRandomClass(p); - if (arenaPlayers.isEmpty()) - return false; - - // Teleport players, give full health, initialize maps - for (Player p : arenaPlayers) - { - p.teleport(arenaLoc); - setHealth(p, 20); - p.setFoodLevel(10); - assignClassPermissions(p); - arenaPlayerMap.put(p, new ArenaPlayer(p, this, plugin)); - } - - // Copy the singleWaves Set for polling. - singleWavesInstance = new TreeSet(singleWaves); - - // Start spawning monsters (must happen before 'running = true;') - startSpawning(); - startBouncingSheep(); - - // Set the boolean. - running = true; - - // Spawn pets (must happen after 'running = true;') - spawnPets(); - - // Start logging - log = new ArenaLog(plugin, this); - log.start(); - - // Initialize leaderboards and start displaying info. - leaderboard.initialize(); - leaderboard.startTracking(); - - // Announce and notify. - MAUtils.tellAll(this, Msg.ARENA_START); - - for (MobArenaListener listener : plugin.getAM().listeners) - listener.onArenaStart(this); - - return true; - } - - public boolean endArena() - { - // Sanity-checks. - if (!running || !arenaPlayers.isEmpty()) - { - //System.out.println("Arena was not ended, playercount: " + arenaPlayers.size()); - return false; - } - //else System.out.println("Arena ending..."); - - // Set the boolean. - running = false; - - // Stop tracking leaderboards - leaderboard.stopTracking(); - leaderboard.update(); - - // Finish logging - log.end(); - if (logging != null) - { - log.saveSessionData(); - log.updateArenaTotals(); - } - log.clearSessionData(); - - // Stop spawning. - stopSpawning(); - - // Clean arena floor. - cleanup(); - - // Restore region. - if (softRestore) - restoreRegion(); - else if (forceRestore) - deserializeRegion(); - - // Restore chests - restoreContainerContents(); - - // Announce and clear sets. - MAUtils.tellAll(this, Msg.ARENA_END, true); - arenaPlayers.clear(); - arenaPlayerMap.clear(); - lobbyPlayers.clear(); - readyPlayers.clear(); - notifyPlayers.clear(); - rewardedPlayers.clear(); - classMap.clear(); - - // Notify listeners. - for (MobArenaListener listener : plugin.getAM().listeners) - listener.onArenaEnd(this); - - return true; - } - - public void forceStart() - { - if (running) - return; - - // Set operations. - Set tmp = new HashSet(); - tmp.addAll(lobbyPlayers); - tmp.removeAll(readyPlayers); - - // Force leave. - for (Player p : tmp) - { - plugin.getAM().arenaMap.remove(p); - playerLeave(p); - } - } - - public void forceEnd() - { - Bukkit.getServer().getScheduler().cancelTask(spawnTaskId); - Bukkit.getServer().getScheduler().cancelTask(sheepTaskId); - - for (Player p : getAllPlayers()) - playerLeave(p); - - for (Entity e : monsters) - if (e != null) e.remove(); - - if (bossWave != null) - bossWave.clear(); - - arenaPlayers.clear(); - lobbyPlayers.clear(); - readyPlayers.clear(); - - cleanup(); - - spawnTaskId = -1; - sheepTaskId = -1; - } - - public void playerJoin(Player p, Location loc) - { - storePlayerData(p, loc); - MAUtils.sitPets(p); - setHealth(p, 20); - p.setFoodLevel(10); - p.setGameMode(GameMode.SURVIVAL); - movePlayerToLobby(p); - - // Notify listeners. - for (MobArenaListener listener : plugin.getAM().listeners) - listener.onPlayerJoin(this, p); - - if (MobArena.hasSpout && spoutSelect) - Spouty.classSelectionScreen(plugin, this, p); - } - - public void playerReady(Player p) - { - readyPlayers.add(p); - - if (minPlayers > 0 && lobbyPlayers.size() < minPlayers) - { - MAUtils.tellPlayer(p, Msg.LOBBY_NOT_ENOUGH_PLAYERS, "" + minPlayers); - return; - } - - startArena(); - } - - public void playerLeave(Player p) - { - finishArenaPlayer(p, false); - movePlayerToEntry(p); - discardPlayer(p); - - // Notify listeners. - for (MobArenaListener listener : plugin.getAM().listeners) - listener.onPlayerLeave(this, p); - - // End arena if possible. - endArena(); - } - - public void playerDeath(Player p) - { - finishArenaPlayer(p, true); - - if (specOnDeath) - { - clearPlayer(p); - movePlayerToSpec(p); - } - else - { - movePlayerToEntry(p); - discardPlayer(p); - } - - if (running && spawnThread != null) - spawnThread.updateTargets(); - - MAUtils.tellAll(this, Msg.PLAYER_DIED, p.getName()); - Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, - new Runnable() - { - public void run() - { - endArena(); - } - }); - - // Notify listeners. - for (MobArenaListener listener : plugin.getAM().listeners) - listener.onPlayerDeath(this, p); - } - - public void playerSpec(Player p, Location loc) - { - storePlayerData(p, loc); - MAUtils.sitPets(p); - movePlayerToSpec(p); - } - - private void spawnPets() - { - for (Map.Entry entry : petMap.entrySet()) - { - // Remove the bones from the inventory. - Player p = entry.getKey(); - p.getInventory().removeItem(new ItemStack(Material.BONE, entry.getValue())); - - // Spawn wolves, set owner and health, and add to pet set. - for (int i = 0; i < entry.getValue(); i++) - { - Wolf wolf = (Wolf) world.spawnCreature(p.getLocation(), CreatureType.WOLF); - wolf.setTamed(true); - wolf.setOwner(p); - wolf.setHealth(20); - if (hellhounds) - wolf.setFireTicks(32768); - pets.add(wolf); - } - } - } - - private void startSpawning() - { - // Set the spawn flags to enable monster spawning. - MAUtils.setSpawnFlags(plugin, world, 1, allowMonsters, allowAnimals); - - // Start the spawnThread. - spawnThread = new MASpawnThread(plugin, this); - spawnTaskId = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, spawnThread, waveDelay, (!waveClear) ? waveInterval : 60); - } - - private void stopSpawning() - { - // Stop the spawn thread. - if (spawnThread != null) - { - Bukkit.getServer().getScheduler().cancelTask(spawnThread.getTaskId()); - Bukkit.getServer().getScheduler().cancelTask(spawnTaskId); - Bukkit.getServer().getScheduler().cancelTask(sheepTaskId); - spawnTaskId = -1; - sheepTaskId = -1; - spawnThread = null; - currentWave = null; - } - else System.out.println("--------- THE SPAWNTHREAD IS NULL! ----------"); - - // Restore spawn flags. - MAUtils.setSpawnFlags(plugin, world, spawnMonsters, allowMonsters, allowAnimals); - } - - private void startBouncingSheep() - { - sheepTaskId = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, - new Runnable() - { - public void run() - { - if (explodingSheep.isEmpty()) return; - - for (LivingEntity e : new LinkedList(explodingSheep)) - { - if (e == null) continue; - - Creature c = (Creature) e; - LivingEntity target = c.getTarget(); - if (target != null && target instanceof Player && MAUtils.distanceSquared((Player) target, e.getLocation()) < 8D) - { - CraftEntity ce = (CraftEntity) e; - CraftWorld cw = (CraftWorld) e.getWorld(); - WorldServer ws = cw.getHandle(); - ws.createExplosion(ce.getHandle(), e.getLocation().getX(), e.getLocation().getY() + 1, e.getLocation().getZ(), 2f, false); - e.remove(); - } - - if (e.isDead()) - { - explodingSheep.remove(e); - continue; - } - - if (Math.abs(e.getVelocity().getY()) < 1) - e.setVelocity(e.getVelocity().setY(0.5)); - } - } - }, waveDelay, 20); - } - - private void updateChunk(Location loc) - { - if (!arenaPlayers.isEmpty() || !world.getName().equals(loc.getWorld().getName())) - return; - - Chunk chunk = world.getChunkAt(loc); - if (!world.isChunkLoaded(chunk)) - world.loadChunk(chunk); - else - world.refreshChunk(chunk.getX(), chunk.getZ()); - } - - public void playerKill(Player p) - { - if (p == null || log.players.get(p) == null) - return; - - arenaPlayerMap.get(p).getStats().kills++; - } - - public void restoreInvAndGiveRewardsDelayed(final Player p) - { - final List rewards = log != null && log.players.get(p) != null ? log.players.get(p).rewards : new LinkedList(); - final boolean hadRewards = rewardedPlayers.contains(p); - - Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, - new Runnable() - { - public void run() - { - if (!emptyInvJoin) - MAUtils.restoreInventory(p); - - if (hadRewards) - return; - - MAUtils.giveRewards(p, rewards, plugin); - if (running) - rewardedPlayers.add(p); - } - }); - } - - public void restoreInvAndGiveRewards(final Player p) - { - if (!emptyInvJoin) - MAUtils.restoreInventory(p); - - if (rewardedPlayers.contains(p)) - return; - - final List rewards = (log != null && log.players.get(p) != null) ? - log.players.get(p).rewards : - new LinkedList(); - - MAUtils.giveRewards(p, rewards, plugin); - if (running) - rewardedPlayers.add(p); - } - - public void storePlayerData(Player p, Location loc) - { - plugin.getAM().arenaMap.put(p, this); - - if (!locations.containsKey(p)) - locations.put(p, loc); - - if (!healthMap.containsKey(p)) - healthMap.put(p, p.getHealth()); - - if (!hungerMap.containsKey(p)) - hungerMap.put(p, p.getFoodLevel()); - - if (!modeMap.containsKey(p)) - modeMap.put(p, p.getGameMode()); - } - - public void storeContainerContents() - { - Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, - new Runnable() - { - public void run() - { - for (Location loc : containers.values()) - { - BlockState state = world.getBlockAt(loc).getState(); - if (state instanceof ContainerBlock) - containables.add(new RepairableContainer(state, false)); - } - } - }); - } - - public void restoreContainerContents() - { - Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, - new Runnable() - { - public void run() - { - for (Repairable r : containables) - r.repair(); - } - }); - } - - public void movePlayerToLobby(Player p) - { - updateChunk(lobbyLoc); - lobbyPlayers.add(p); - p.teleport(lobbyLoc); - } - - public void movePlayerToSpec(Player p) - { - updateChunk(spectatorLoc); - specPlayers.add(p); - p.teleport(spectatorLoc); - } - - public void movePlayerToEntry(Player p) - { - Location entry = locations.get(p); - if (entry == null || p.isDead()) return; - - updateChunk(entry); - p.teleport(entry); - } - - private void clearPlayer(Player p) - { - if (healthMap.containsKey(p)) - { - int health = healthMap.remove(p); - setHealth(p, health); - } - - if (hungerMap.containsKey(p)) - p.setFoodLevel(hungerMap.remove(p)); - - if (modeMap.containsKey(p)) - p.setGameMode(modeMap.remove(p)); - - // Put out fire. - Delays.douse(plugin, p, 3); - - // Remove pets. - removePets(p); - - // readyPlayers before lobbyPlayers because of startArena sanity-checks - readyPlayers.remove(p); - specPlayers.remove(p); - arenaPlayers.remove(p); - lobbyPlayers.remove(p); - classMap.remove(p); - arenaPlayerMap.remove(p); - } - - /** - * Completely remove a player from the arena collections. - * @param p A player - */ - private void discardPlayer(Player p) - { - locations.remove(p); - plugin.getAM().arenaMap.remove(p); - clearPlayer(p); - } - - /** - * Give the player back his inventory and record his last wave. - * Called when a player dies or leaves prematurely. - * @param p A player - * @param dead If the player died or not - */ - private void finishArenaPlayer(Player p, boolean dead) - { - if (!arenaPlayers.contains(p) && !lobbyPlayers.contains(p)) - return; - - removeClassPermissions(p); - MAUtils.clearInventory(p); - - if (dead) restoreInvAndGiveRewardsDelayed(p); - else restoreInvAndGiveRewards(p); - - ArenaPlayer ap = arenaPlayerMap.get(p); - if (ap != null) - ap.setDead(true); - } - - private void setHealth(Player p, int health) - { - // Grab the current health - int current = p.getHealth(); - - // If the health is 20, just leave it at that no matter what. - int regain = health == 20 ? 20 : health - current; - - // Set the health, and fire off the event. - p.setHealth(health); - EntityRegainHealthEvent event = new EntityRegainHealthEvent(p, regain, RegainReason.CUSTOM); - Bukkit.getPluginManager().callEvent(event); - } - - public void repairBlocks() - { - while (!repairQueue.isEmpty()) - repairQueue.poll().repair(); - } - - public void queueRepairable(Repairable r) - { - repairQueue.add(r); - } - - - - /*//////////////////////////////////////////////////////////////////// - // - // Items & Cleanup - // - ////////////////////////////////////////////////////////////////////*/ - - public void assignClass(Player p, String className) - { - petMap.remove(p); - randoms.remove(p); - classMap.put(p, className); - - MAUtils.clearInventory(p); - - // If random, don't give any items yet. - if (className.equalsIgnoreCase("random")) - { - randoms.add(p); - return; - } - - MAUtils.giveItems(p, classItems.get(className), autoEquip, plugin); - MAUtils.giveItems(p, classArmor.get(className), autoEquip, plugin); - - int pets = MAUtils.getPetAmount(p); - if (pets > 0) petMap.put(p, pets); - } - - public void assignRandomClass(Player p) - { - Random r = new Random(); - List classes = new LinkedList(plugin.getAM().classes); - - String className = classes.remove(r.nextInt(classes.size())); - while (!plugin.has(p, "mobarena.classes." + className)) - { - if (classes.isEmpty()) - { - MobArena.info("Player '" + p.getName() + "' has no class permissions!"); - playerLeave(p); - return; - } - className = classes.remove(r.nextInt(classes.size())); - } - - assignClass(p, className); - MAUtils.tellPlayer(p, Msg.LOBBY_CLASS_PICKED, className); - } - - public void assignClassPermissions(Player p) - { - Map perms = classPerms.get(classMap.get(p)); - if (perms == null || perms.isEmpty()) return; - - PermissionAttachment pa = p.addAttachment(plugin); - attachments.put(p,pa); - for (Map.Entry entry : perms.entrySet()) - pa.setPermission(entry.getKey(), entry.getValue()); - - p.recalculatePermissions(); - } - - public void removeClassPermissions(Player p) - { - if (attachments.get(p) == null) return; - - for (PermissionAttachment pa : attachments.values()) - if (pa != null) pa.remove(); - - p.recalculatePermissions(); - } - - private void cleanup() - { - removeMonsters(); - removeBlocks(); - removePets(); - removeEntities(); - monsters.clear(); - explodingSheep.clear(); - plaguedPigs.clear(); - madCows.clear(); - blocks.clear(); - pets.clear(); - } - - private void removeMonsters() - { - if (bossWave != null) - bossWave.clear(); - for (LivingEntity e : monsters) - if (e != null) e.remove(); - for (LivingEntity e : explodingSheep) - if (e != null) e.remove(); - for (LivingEntity e : plaguedPigs) - if (e != null) e.remove(); - for (LivingEntity e : madCows) - if (e != null) e.remove(); - } - - private void removeBlocks() - { - for (Block b : blocks) - b.setTypeId(0); - } - - private void removePets() - { - for (Wolf w : pets) - { - if (w == null) continue; - - w.setOwner(null); - w.remove(); - } - } - - private void removePets(Player p) - { - for (Wolf w : pets) - { - if (w == null || !(w.getOwner() instanceof Player) || !((Player) w.getOwner()).getName().equals(p.getName())) - continue; - - w.setOwner(null); - w.remove(); - } - petMap.remove(p); - } - - private void removeEntities() - { - if (p1 == null || p2 == null) return; - Chunk c1 = world.getChunkAt(p1); - Chunk c2 = world.getChunkAt(p2); - - for (int i = c1.getX(); i <= c2.getX(); i++) - for (int j = c1.getZ(); j <= c2.getZ(); j++) - for (Entity e : world.getChunkAt(i,j).getEntities()) - if ((e instanceof Item || e instanceof Slime) && inRegion(e.getLocation())) - if (e != null) e.remove(); - } - - - - /*//////////////////////////////////////////////////////////////////// - // - // Initialization & Checks - // - ////////////////////////////////////////////////////////////////////*/ - - public void load(Config config) - { - config.load(); - - String arenaPath = "arenas." + MAUtils.nameArenaToConfig(name) + ".settings."; - String configName = MAUtils.nameArenaToConfig(name); - - enabled = config.getBoolean(arenaPath + "enabled", true); - protect = config.getBoolean(arenaPath + "protect", true); - logging = config.getString(arenaPath + "logging", null); - autoEquip = config.getBoolean(arenaPath + "auto-equip-armor", true); - waveClear = config.getBoolean(arenaPath + "clear-wave-before-next", false); - detCreepers = config.getBoolean(arenaPath + "detonate-creepers", false); - detDamage = config.getBoolean(arenaPath + "detonate-damage", false); - lightning = config.getBoolean(arenaPath + "lightning", true); - forceRestore = config.getBoolean(arenaPath + "force-restore", false); - softRestore = config.getBoolean(arenaPath + "soft-restore", false); - softRestoreDrops = config.getBoolean(arenaPath + "soft-restore-drops", false); - emptyInvJoin = config.getBoolean(arenaPath + "require-empty-inv-join", true); - emptyInvSpec = config.getBoolean(arenaPath + "require-empty-inv-spec", true); - hellhounds = config.getBoolean(arenaPath + "hellhounds", false); - pvp = config.getBoolean(arenaPath + "pvp-enabled", false); - monsterInfight = config.getBoolean(arenaPath + "monster-infight", false); - allowWarp = config.getBoolean(arenaPath + "allow-teleporting", false); - specOnDeath = config.getBoolean(arenaPath + "spectate-on-death", true); - shareInArena = config.getBoolean(arenaPath + "share-items-in-arena", true); - spoutSelect = config.getBoolean(arenaPath + "spout-class-select", true); - joinDistance = config.getInt(arenaPath + "max-join-distance", 0); - minPlayers = config.getInt(arenaPath + "min-players", 0); - maxPlayers = config.getInt(arenaPath + "max-players", 0); - waveDelay = config.getInt(arenaPath + "first-wave-delay", 5) * 20; - waveInterval = config.getInt(arenaPath + "wave-interval", 20) * 20; - specialModulo = config.getInt(arenaPath + "special-modulo", 4); - maxIdleTime = config.getInt(arenaPath + "max-idle-time", 0) * 20; - finalWave = config.getInt(arenaPath + "final-wave", 0); - - everyWaveMap = MAUtils.getArenaRewardMap(config, configName, "every"); - afterWaveMap = MAUtils.getArenaRewardMap(config, configName, "after"); - entryFee = MAUtils.getEntryFee(config, configName); - - p1 = MAUtils.getArenaCoord(config, world, configName, "p1"); - p2 = MAUtils.getArenaCoord(config, world, configName, "p2"); - l1 = MAUtils.getArenaCoord(config, world, configName, "l1"); - l2 = MAUtils.getArenaCoord(config, world, configName, "l2"); - arenaLoc = MAUtils.getArenaCoord(config, world, configName, "arena"); - lobbyLoc = MAUtils.getArenaCoord(config, world, configName, "lobby"); - spectatorLoc = MAUtils.getArenaCoord(config, world, configName, "spectator"); - spawnpoints = MAUtils.getArenaSpawnpoints(config, world, configName); - spawnpointsBoss = MAUtils.getArenaBossSpawnpoints(config, world, configName); - containers = MAUtils.getArenaContainers(config, world, configName); - leaderboard = new Leaderboard(plugin, this, config); - - // NEW WAVES - singleWaves = WaveUtils.getWaves(this, config, WaveBranch.SINGLE); - recurrentWaves = WaveUtils.getWaves(this, config, WaveBranch.RECURRENT); - - classes = plugin.getAM().classes; - classItems = plugin.getAM().classItems; - classArmor = plugin.getAM().classArmor; - classPerms = plugin.getAM().classPerms; - - // Determine if the arena is properly set up. Then add the to arena list. - setup = MAUtils.verifyData(this); - lobbySetup = MAUtils.verifyLobby(this); - } - - public void restoreRegion() - { - Collections.sort(repairables, new RepairableComparator()); - - for (Repairable r : repairables) - r.repair(); - } - - public void serializeConfig() - { - String coords = "arenas." + configName() + ".coords."; - Config config = plugin.getMAConfig(); - - config.setProperty("arenas." + configName() + ".settings.enabled", enabled); - config.setProperty("arenas." + configName() + ".settings.protect", protect); - if (p1 != null) config.setProperty(coords + "p1", MAUtils.makeCoord(p1)); - if (p2 != null) config.setProperty(coords + "p2", MAUtils.makeCoord(p2)); - if (l1 != null) config.setProperty(coords + "l1", MAUtils.makeCoord(l1)); - if (l2 != null) config.setProperty(coords + "l2", MAUtils.makeCoord(l2)); - if (arenaLoc != null) config.setProperty(coords + "arena", MAUtils.makeCoord(arenaLoc)); - if (lobbyLoc != null) config.setProperty(coords + "lobby", MAUtils.makeCoord(lobbyLoc)); - if (spectatorLoc != null) config.setProperty(coords + "spectator", MAUtils.makeCoord(spectatorLoc)); - for (Map.Entry entry : spawnpoints.entrySet()) - config.setProperty(coords + "spawnpoints." + entry.getKey(), MAUtils.makeCoord(entry.getValue())); - for (Map.Entry entry : spawnpointsBoss.entrySet()) - config.setProperty(coords + "spawnpoints." + entry.getKey(), MAUtils.makeCoord(entry.getValue())); - - config.save(); - } - - public void deserializeConfig() - { - Config config = plugin.getMAConfig(); - config.load(); - load(config); - } - - public boolean serializeRegion() - { - int x1 = (int) p1.getX(); - int y1 = (int) p1.getY(); - int z1 = (int) p1.getZ(); - int x2 = (int) p2.getX(); - int y2 = (int) p2.getY(); - int z2 = (int) p2.getZ(); - - HashSet set = new HashSet(); - int[] buffer; - for (int i = x1; i <= x2; i++) - { - for (int j = y1; j <= y2; j++) - { - for (int k = z1; k <= z2; k++) - { - buffer = new int[4]; - buffer[0] = i; - buffer[1] = j; - buffer[2] = k; - buffer[3] = world.getBlockAt(i,j,k).getTypeId(); - set.add(buffer); - } - } - } - - try - { - new File(plugin.getDataFolder() + File.separator + "regions").mkdir(); - File regionFile = new File(plugin.getDataFolder() + File.separator + "regions" + File.separator + configName() + ".tmp"); - if (regionFile.exists()) - regionFile.createNewFile(); - - FileOutputStream fos = new FileOutputStream(regionFile); - ObjectOutputStream oos = new ObjectOutputStream(fos); - oos.writeObject(set); - oos.close(); - } - catch (Exception e) - { - MobArena.warning("Could not create region file. The arena will not be started!"); - e.printStackTrace(); - return false; - } - return true; - } - - @SuppressWarnings("unchecked") - public boolean deserializeRegion() - { - HashSet set = new HashSet(); - try - { - File regionFile = new File(plugin.getDataFolder() + File.separator + "regions" + File.separator + configName() + ".tmp"); - if (!regionFile.exists()) - return false; - - FileInputStream fis = new FileInputStream(regionFile); - ObjectInputStream ois = new ObjectInputStream(fis); - set = (HashSet) ois.readObject(); - ois.close(); - } - catch (Exception e) - { - MobArena.warning("Could not find region file. The arena cannot be restored!"); - e.printStackTrace(); - return false; - } - - for (int[] buffer : set) - world.getBlockAt(buffer[0], buffer[1], buffer[2]).setTypeId(buffer[3]); - - return true; - } - - /** - * Check if a location is inside of the cuboid region - * that p1 and p2 span. - */ - public boolean inRegion(Location loc) - { - if (!loc.getWorld().getName().equals(world.getName()) || !setup) - return false; - - int x = loc.getBlockX(); - int y = loc.getBlockY(); - int z = loc.getBlockZ(); - - // Check the lobby first. - if (lobbySetup) - { - if ((x >= l1.getBlockX() && x <= l2.getBlockX()) && - (z >= l1.getBlockZ() && z <= l2.getBlockZ()) && - (y >= l1.getBlockY() && y <= l2.getBlockY())) - return true; - } - - // Returns false if the location is outside of the region. - return ((x >= p1.getBlockX() && x <= p2.getBlockX()) && - (z >= p1.getBlockZ() && z <= p2.getBlockZ()) && - (y >= p1.getBlockY() && y <= p2.getBlockY())); - } - - /** - * Check if a location is inside of the arena region, expanded - * by 'radius' blocks. Used with explosions. - */ - public boolean inRegionRadius(Location loc, int radius) - { - if (!loc.getWorld().getName().equals(world.getName()) || !setup) - return false; - - int x = loc.getBlockX(); - int y = loc.getBlockY(); - int z = loc.getBlockZ(); - - // Check the lobby first. - if (lobbySetup) - { - if ((x + radius >= l1.getBlockX() && x - radius <= l2.getBlockX()) && - (z + radius >= l1.getBlockZ() && z - radius <= l2.getBlockZ()) && - (y + radius >= l1.getBlockY() && y - radius <= l2.getBlockY())) - return true; - } - - return ((x + radius >= p1.getBlockX() && x - radius <= p2.getBlockX()) && - (z + radius >= p1.getBlockZ() && z - radius <= p2.getBlockZ()) && - (y + radius >= p1.getBlockY() && y - radius <= p2.getBlockY())); - } - - - - /*//////////////////////////////////////////////////////////////////// - // - // Getters & Misc - // - ////////////////////////////////////////////////////////////////////*/ - - public boolean inArena(Player p) - { - return arenaPlayers.contains(p); - } - - public boolean inLobby(Player p) - { - return lobbyPlayers.contains(p); - } - - public boolean isEnabled() { - return enabled; - } - - public boolean isRunning() - { - return running; - } - - public boolean isPvpEnabled() - { - return pvp; - } - - public boolean isLightningEnabled() - { - return lightning; - } - - public boolean isBossWave() - { - return bossWave != null; - } - - public String configName() - { - return MAUtils.nameArenaToConfig(name); - } - - public String arenaName() - { - return name; - } - - public MobArena getPlugin() - { - return plugin; - } - - public World getWorld() - { - return world; - } - - public Wave getWave() - { - return currentWave; - } - - public void setWave(Wave wave) - { - currentWave = wave; - } - - public void setBossWave(BossWave bossWave) - { - this.bossWave = bossWave; - } - - public Set getClasses() - { - return classes; - } - - public List getAllSpawnpoints() - { - ArrayList result = new ArrayList(spawnpoints.size() + spawnpointsBoss.size()); - result.addAll(spawnpoints.values()); - result.addAll(spawnpointsBoss.values()); - return result; - } - - public List getSpawnpoints() - { - return new ArrayList(spawnpoints.values()); - } - - public Location getBossSpawnpoint() - { - if (spawnpointsBoss.isEmpty()) - { - List points = WaveUtils.getValidSpawnpoints(this, getLivingPlayers()); - return points.get(MobArena.random.nextInt(points.size())); - } - - return new ArrayList(spawnpointsBoss.values()).get(MobArena.random.nextInt(spawnpointsBoss.size())); - } - - public int getPlayerCount() - { - return spawnThread.getPlayerCount(); - } - - public void addBlock(Block b) - { - blocks.add(b); - } - - public void addMonster(LivingEntity e) - { - monsters.add(e); - } - - public void addExplodingSheep(LivingEntity e) - { - explodingSheep.add(e); - } - - public List getAllPlayers() - { - List result = new LinkedList(); - result.addAll(arenaPlayers); - result.addAll(lobbyPlayers); - result.addAll(specPlayers); - return result; - } - - public List getLivingPlayers() - { - List result = new LinkedList(); - result.addAll(arenaPlayers); - return result; - } - - public Set getArenaPlayers() - { - return arenaPlayers; - } - - public Collection getArenaPlayerSet() - { - return arenaPlayerMap.values(); - } - - public List getArenaPlayerStatistics(Comparator comparator) - { - List list = new ArrayList(); - - for (ArenaPlayer ap : arenaPlayerMap.values()) - list.add(ap.getStats()); - - Collections.sort(list, comparator); - return list; - } - - public List getNonreadyPlayers() - { - List result = new LinkedList(); - result.addAll(lobbyPlayers); - result.removeAll(readyPlayers); - return result; - } - - public Set getMonsters() - { - Set tmp = new HashSet(monsters); - tmp.addAll(explodingSheep); - return tmp; - } - - public Set getPets() - { - return pets; - } - - public void resetIdleTimer() - { - if (maxIdleTime <= 0 || !running) - return; - - // Reset the previousSize, cancel the previous timer, and start the new timer. - spawnThread.setPreviousSize(getMonsters().size()); - Bukkit.getServer().getScheduler().cancelTask(spawnThread.getTaskId()); - int id = Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, - new Runnable() - { - public void run() - { - // Make sure to remove any dead/removed entities first. - List ms = new LinkedList(monsters); - for (Entity e : ms) - if (e.isDead()) - monsters.remove(e); - - // Compare the current size with the previous size. - if (monsters.size() < spawnThread.getPreviousSize() || spawnThread.getPreviousSize() == 0 || bossWave != null) - { - resetIdleTimer(); - return; - } - - // Clear all player inventories, and "kill" all players. - List ps = new LinkedList(arenaPlayers); - for (Player p : ps) - { - MAUtils.clearInventory(p); - MAUtils.tellPlayer(p, Msg.FORCE_END_IDLE); - playerDeath(p); - } - } - }, maxIdleTime); - spawnThread.setTaskId(id); - } - - public void addTrunkAndLeaves(Block b) - { - final int x = b.getX(); - final int y = b.getY(); - final int z = b.getZ(); - - Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, - new Runnable() - { - public void run() - { - List result = new LinkedList(); - for (int i = x-2; i <= x+2; i++) - for (int j = y; j <= y+10; j++) - for (int k = z-2; k <= z+2; k++) - if (world.getBlockAt(i,j,k).getType() == Material.LOG || world.getBlockAt(i,j,k).getType() == Material.LEAVES) - result.add(world.getBlockAt(i,j,k)); - - if (running) blocks.addAll(result); - } - }, 10); - } - - public boolean canAfford(Player p) - { - if (entryFee.isEmpty()) - return true; - - PlayerInventory inv = p.getInventory(); - for (ItemStack stack : entryFee) - { - // Economy money - if (stack.getTypeId() == MobArena.ECONOMY_MONEY_ID) - { - //if (plugin.Methods.hasMethod() && !plugin.Method.getAccount(p.getName()).hasEnough(stack.getAmount())) - if (plugin.Method != null && !(plugin.Method.getAccount(p.getName()).balance() >= stack.getAmount())) - return false; - } - // Normal stack - else - { - if (!inv.contains(stack.getTypeId(), stack.getAmount())) - return false; - } - } - - return true; - } - - public boolean takeFee(Player p) - { - if (entryFee.isEmpty()) - return true; - - PlayerInventory inv = p.getInventory(); - InventoryItem[] items = InventoryItem.parseItemStacks(inv.getContents()); - InventoryItem[] fee = InventoryItem.parseItemStacks(entryFee); - - // Take some economy money - for (InventoryItem item : InventoryItem.extractAllFromArray(MobArena.ECONOMY_MONEY_ID, fee)) - if (plugin.Method != null) - plugin.Method.getAccount(p.getName()).subtract(item.getAmount()); - - // Take any other items - for (InventoryItem item : fee) - InventoryItem.removeItemFromArray(item, items); - - // Turn everything back into ItemStacks - for (int i = 0; i < items.length; i++) - inv.setItem(i, items[i].toItemStack()); - - return true; - } - - public boolean canJoin(Player p) - { - if (!enabled) - MAUtils.tellPlayer(p, Msg.JOIN_ARENA_NOT_ENABLED); - else if (!setup || recurrentWaves.isEmpty()) - MAUtils.tellPlayer(p, Msg.JOIN_ARENA_NOT_SETUP); - else if (edit) - MAUtils.tellPlayer(p, Msg.JOIN_ARENA_EDIT_MODE); - else if (running && (notifyPlayers.contains(p) || notifyPlayers.add(p))) - MAUtils.tellPlayer(p, Msg.JOIN_ARENA_IS_RUNNING); - else if (arenaPlayers.contains(p) || lobbyPlayers.contains(p)) - MAUtils.tellPlayer(p, Msg.JOIN_ALREADY_PLAYING); - else if (!plugin.has(p, "mobarena.arenas." + configName())) - MAUtils.tellPlayer(p, Msg.JOIN_ARENA_PERMISSION); - else if (maxPlayers > 0 && lobbyPlayers.size() >= maxPlayers) - MAUtils.tellPlayer(p, Msg.JOIN_PLAYER_LIMIT_REACHED); - else if (joinDistance > 0 && !inRegionRadius(p.getLocation(), joinDistance)) - MAUtils.tellPlayer(p, Msg.JOIN_TOO_FAR); - else if (emptyInvJoin && !MAUtils.hasEmptyInventory(p)) - MAUtils.tellPlayer(p, Msg.JOIN_EMPTY_INV); - else if (!canAfford(p))// || !takeFee(p)) - MAUtils.tellPlayer(p, Msg.JOIN_FEE_REQUIRED, MAUtils.listToString(entryFee, plugin)); - else return true; - - return false; - } - - public boolean canSpec(Player p) - { - if (!enabled) - MAUtils.tellPlayer(p, Msg.JOIN_ARENA_NOT_ENABLED); - else if (!setup) - MAUtils.tellPlayer(p, Msg.JOIN_ARENA_NOT_SETUP); - else if (edit) - MAUtils.tellPlayer(p, Msg.JOIN_ARENA_EDIT_MODE); - else if (arenaPlayers.contains(p) || lobbyPlayers.contains(p)) - MAUtils.tellPlayer(p, Msg.SPEC_ALREADY_PLAYING); - else if (emptyInvSpec && !MAUtils.hasEmptyInventory(p)) - MAUtils.tellPlayer(p, Msg.SPEC_EMPTY_INV); - else if (joinDistance > 0 && !inRegionRadius(p.getLocation(), joinDistance)) - MAUtils.tellPlayer(p, Msg.JOIN_TOO_FAR); - else return true; - - return false; - } - - /** - * The "perfect equals method" cf. "Object-Oriented Design and Patterns" - * by Cay S. Horstmann. - */ - public boolean equals(Object other) - { - if (this == other) return true; - if (other == null) return false; - if (getClass() != other.getClass()) return false; - - // Arenas must have different names. - if (other instanceof ArenaStandard && ((ArenaStandard)other).name.equals(name)) - return true; - - return false; - } - - public String toString() - { - return ((enabled && setup) ? ChatColor.GREEN : ChatColor.GRAY) + configName(); - } -} diff --git a/src/com/garbagemule/MobArena/MABlockListener.java b/src/com/garbagemule/MobArena/MABlockListener.java deleted file mode 100644 index 47c9c8c..0000000 --- a/src/com/garbagemule/MobArena/MABlockListener.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.garbagemule.MobArena; - -import org.bukkit.ChatColor; -import org.bukkit.event.block.BlockBurnEvent; -import org.bukkit.event.block.BlockIgniteEvent; -import org.bukkit.event.block.BlockListener; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.block.SignChangeEvent; - -import com.garbagemule.MobArena.leaderboards.Stats; - -public class MABlockListener extends BlockListener -{ - private ArenaMaster am; - - public MABlockListener(ArenaMaster am) - { - this.am = am; - } - - public void onBlockBreak(BlockBreakEvent event) - { - for (Arena arena : am.arenas) - arena.eventListener.onBlockBreak(event); - } - - public void onBlockBurn(BlockBurnEvent event) - { - for (Arena arena : am.arenas) - arena.eventListener.onBlockBurn(event); - } - - public void onBlockPlace(BlockPlaceEvent event) - { - for (Arena arena : am.arenas) - arena.eventListener.onBlockPlace(event); - } - - public void onBlockIgnite(BlockIgniteEvent event) - { - for (Arena arena : am.arenas) - arena.eventListener.onBlockIgnite(event); - } - - public void onSignChange(SignChangeEvent event) - { - if (!event.getPlayer().hasPermission("mobarena.setup.leaderboards")) - return; - - if (event.getLine(0).startsWith("[MA]")) - { - String text = event.getLine(0).substring((4)); - Arena arena; - Stats stat; - if ((arena = am.getArenaWithName(text)) != null) - { - arena.eventListener.onSignChange(event); - setSignLines(event, ChatColor.GREEN + "MobArena", ChatColor.YELLOW + arena.arenaName(), ChatColor.AQUA + "Players", "---------------"); - } - else if ((stat = Stats.fromString(text)) != null) - { - setSignLines(event, ChatColor.GREEN + "", "", ChatColor.AQUA + stat.getFullName(), "---------------"); - MAUtils.tellPlayer(event.getPlayer(), "Stat sign created."); - } - } - } - - private void setSignLines(SignChangeEvent event, String s1, String s2, String s3, String s4) - { - event.setLine(0, s1); - event.setLine(1, s2); - event.setLine(2, s3); - event.setLine(3, s4); - } - - /* - public void onBlockPhysics(BlockPhysicsEvent event) - { - for (Arena arena : am.arenas) - arena.eventListener.onBlockPhysics(event); - } - */ -} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/MAClass.java b/src/com/garbagemule/MobArena/MAClass.java deleted file mode 100644 index 3eb6e55..0000000 --- a/src/com/garbagemule/MobArena/MAClass.java +++ /dev/null @@ -1,149 +0,0 @@ -package com.garbagemule.MobArena; - -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; - -public class MAClass -{ - private String name; - private List items, armor; - private Map perms; - - public MAClass(String name) - { - this.name = name; - this.items = new LinkedList(); - this.armor = new LinkedList(); - this.perms = new HashMap(); - } - - public MAClass(String name, List items, List armor) - { - this.name = name; - this.items = items; - this.armor = armor; - this.perms = new HashMap(); - sortArmor(); - immunizeWeapons(); - } - - public String getName() - { - return name; - } - - public List getItems() - { - return items; - } - - public void setItems(List items) - { - this.items = items; - immunizeWeapons(); - } - - public void setArmor(List armor) - { - this.armor = armor; - sortArmor(); - } - - public void setPerms(Map perms) - { - this.perms = perms; - } - - public void giveItems(Player p) - { - PlayerInventory inv = p.getInventory(); - - for (ItemStack stack : items) - { - - inv.addItem(stack.clone()); - } - } - - public void giveArmor(Player p) - { - PlayerInventory inv = p.getInventory(); - - inv.setHelmet (armor.get(0)); - inv.setChestplate(armor.get(1)); - inv.setLeggings (armor.get(2)); - inv.setBoots (armor.get(3)); - } - - private void sortArmor() - { - ItemStack s0 = null, s1 = null, s2 = null, s3 = null; - for (ItemStack stack : armor) - { - if (isHelmet(stack)) - s0 = stack; - else if (isChestplate(stack)) - s1 = stack; - else if (isLeggings(stack)) - s2 = stack; - else if (isBoots(stack)) - s3 = stack; - } - - armor.set(0, s0); - armor.set(1, s1); - armor.set(2, s2); - armor.set(3, s3); - } - - private void immunizeWeapons() - { - for (ItemStack stack : items) - { - } - } - - private boolean isHelmet(ItemStack stack) - { - return (!isChestplate(stack) && !isLeggings(stack) && !isBoots(stack)); - } - - private boolean isChestplate(ItemStack stack) - { - return matches(stack, 299, 303, 307, 311, 315); - } - - private boolean isLeggings(ItemStack stack) - { - return matches(stack, 300, 304, 308, 312, 316); - } - - private boolean isBoots(ItemStack stack) - { - return matches(stack, 301, 305, 309, 313, 317); - } - - private boolean isWeapon(ItemStack stack) - { - return matches(stack, 256, 257, 258, 267, 268, 269, 270, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 283, 284, 285, 286, - 290, 291, 292, 293, 294, 346); - } - - private boolean matches(ItemStack stack, int... ids) - { - int id = stack.getTypeId(); - - for (int i : ids) - if (id == i) - return true; - - return false; - } -} diff --git a/src/com/garbagemule/MobArena/MACommands.java b/src/com/garbagemule/MobArena/MACommands.java deleted file mode 100644 index f5d2992..0000000 --- a/src/com/garbagemule/MobArena/MACommands.java +++ /dev/null @@ -1,1309 +0,0 @@ -package com.garbagemule.MobArena; - -import java.util.List; -import java.util.LinkedList; -import java.util.Set; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.DyeColor; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.Server; -import org.bukkit.World; -import org.bukkit.entity.Player; -import org.bukkit.block.ContainerBlock; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.ConsoleCommandSender; - -public class MACommands implements CommandExecutor -{ - public static List ALLOWED_COMMANDS = new LinkedList(); - public static final List COMMANDS = new LinkedList(); - static - { - COMMANDS.add("j"); // Join - COMMANDS.add("join"); // Join - COMMANDS.add("l"); // Leave - COMMANDS.add("leave"); // Leave - COMMANDS.add("notready"); // List of players who aren't ready - COMMANDS.add("spec"); // Watch arena - COMMANDS.add("spectate"); // Watch arena - COMMANDS.add("arenas"); // List of arenas - COMMANDS.add("list"); // List of players - COMMANDS.add("players"); // List of players - COMMANDS.add("info"); // Info/help - COMMANDS.add("help"); // Info/help - COMMANDS.add("restore"); // Restore inventory - COMMANDS.add("enable"); // Enabling - COMMANDS.add("disable"); // Disabling - COMMANDS.add("protect"); // Protection on/off - COMMANDS.add("force"); // Force start/end - COMMANDS.add("config"); // Reload config - COMMANDS.add("arena"); // Current arena - COMMANDS.add("setarena"); // Set current arena - COMMANDS.add("addarena"); // Add a new arena - COMMANDS.add("delarena"); // Delete current aren - COMMANDS.add("editarena"); // Editing - COMMANDS.add("setregion"); // Set a region point - COMMANDS.add("expandregion"); // Expand the region - COMMANDS.add("showregion"); // Show the region - COMMANDS.add("setlobbyregion"); // Set a region point - COMMANDS.add("expandlobbyregion"); // Expand the region - COMMANDS.add("setwarp"); // Set arena/lobby/spec - COMMANDS.add("spawnpoints"); // List spawnpoints - COMMANDS.add("addspawn"); // Add a spawnpoint - COMMANDS.add("delspawn"); // Delete a spawnpoint - COMMANDS.add("containers"); // List containers - COMMANDS.add("addcontainer"); // Add a container block - COMMANDS.add("delcontainer"); // Delete a container block - COMMANDS.add("reset"); // Reset arena coordinates - COMMANDS.add("addclass"); // Add a new class - COMMANDS.add("delclass"); // Delete a class - COMMANDS.add("checkdata"); // Check arena well formedness - COMMANDS.add("auto-generate"); // Auto-generate arena - COMMANDS.add("auto-degenerate"); // Restore cuboid - } - private boolean meanAdmins, showingRegion; - private Server server; - private MobArena plugin; - private ArenaMaster am; - - public MACommands() - { - - } - - public MACommands(MobArena plugin, ArenaMaster am) - { - this.plugin = plugin; - this.am = am; - server = Bukkit.getServer(); - meanAdmins = (server.getPluginManager().getPlugin("Mean Admins") != null); - ALLOWED_COMMANDS = MAUtils.getAllowedCommands(plugin.getMAConfig()); - } - - /** - * Handles all command parsing. - * Unrecognized commands return false, giving the sender a list of - * valid commands (from plugin.yml). - */ - public boolean onCommand(CommandSender sender, Command command, String label, String[] args) - { - // Play nice with Mean Admins. - if (meanAdmins && !COMMANDS.contains(args[0].toLowerCase())) - { - server.getPluginManager().getPlugin("Mean Admins").onCommand(sender, command, label, args); - return true; - } - - // Determine if the sender is a player (and an op), or the console. - boolean player = (sender instanceof Player); - boolean op = player && ((Player) sender).isOp(); - boolean console = (sender instanceof ConsoleCommandSender); - - // Cast the sender to Player if possible. - Player p = (player) ? (Player) sender : null; - - if (args.length == 0) - { - List arenas = am.getEnabledArenas(); - if (arenas == null || arenas.isEmpty()) - MAUtils.tellPlayer(p, "There are no enabled arenas to join!"); - else - MAUtils.tellPlayer(p, "Use /ma join to join an arena."); - return true; - } - - // Grab the command base and any arguments. - String base = args[0].toLowerCase(); - String arg1 = (args.length > 1) ? args[1].toLowerCase() : ""; - String arg2 = (args.length > 2) ? args[2].toLowerCase() : ""; - String arg3 = (args.length > 3) ? args[3].toLowerCase() : ""; - - - - /*//////////////////////////////////////////////////////////////// - // - // Basics - // - ////////////////////////////////////////////////////////////////*/ - - if (base.equals("spawn")) - { - p.getWorld().setSpawnLocation(p.getLocation().getBlockX(), p.getLocation().getBlockY() + 1, p.getLocation().getBlockZ()); - } - - /* - * Player join - */ - if (base.equals("join") || base.equals("j")) - { - if (!player || !plugin.has(p, "mobarena.use.join")) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - List arenas = am.getEnabledArenas(); - if (!am.enabled || arenas.size() < 1) - { - MAUtils.tellPlayer(p, Msg.JOIN_NOT_ENABLED); - return true; - } - - // Grab the arena to join - Arena arena = arenas.size() == 1 ? arenas.get(0) : am.getArenaWithName(arg1); - - // Run a couple of basic sanity checks - if (!sanityChecks(p, arena, arg1, arenas)) - return true; - - // Run a bunch of per-arena sanity checks - if (!arena.canJoin(p)) - return true; - - // If player is in a boat/minecart, eject! - if (p.isInsideVehicle()) - p.leaveVehicle(); - - // Take entry fee and store inventory - arena.takeFee(p); - if (!arena.emptyInvJoin) MAUtils.storeInventory(p); - - // If player is in a bed, unbed! - if (p.isSleeping()) - { - p.kickPlayer("Banned for life... Nah, just don't join from a bed ;)"); - return true; - } - - // Join the arena! - arena.playerJoin(p, p.getLocation()); - - MAUtils.tellPlayer(p, Msg.JOIN_PLAYER_JOINED); - if (!arena.entryFee.isEmpty()) - MAUtils.tellPlayer(p, Msg.JOIN_FEE_PAID.toString(MAUtils.listToString(arena.entryFee, plugin))); - if (arena.hasPaid.contains(p)) - arena.hasPaid.remove(p); - - return true; - } - - /* - * Player leave - */ - if (base.equals("leave") || base.equals("l")) - { - if (!player || !plugin.has(p, "mobarena.use.leave")) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - if (!am.arenaMap.containsKey(p)) - { - Arena arena = am.getArenaWithSpectator(p); - if (arena != null) - { - arena.playerLeave(p); - MAUtils.tellPlayer(p, Msg.LEAVE_PLAYER_LEFT); - return true; - } - - MAUtils.tellPlayer(p, Msg.LEAVE_NOT_PLAYING); - return true; - } - - Arena arena = am.arenaMap.get(p); - arena.playerLeave(p); - MAUtils.tellPlayer(p, Msg.LEAVE_PLAYER_LEFT); - return true; - } - - /* - * Player spectate - */ - if (base.equals("spectate") || base.equals("spec")) - { - if (!player || !plugin.has(p, "mobarena.use.spectate")) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - List arenas = am.getEnabledArenas(); - if (!am.enabled || arenas.size() < 1) - { - MAUtils.tellPlayer(p, Msg.JOIN_NOT_ENABLED); - return true; - } - - // Grab the arena to join - Arena arena = arenas.size() == 1 ? arenas.get(0) : am.getArenaWithName(arg1); - - // Run a couple of basic sanity checks - if (!sanityChecks(p, arena, arg1, arenas)) - return true; - - // Run a bunch of arena-specific sanity-checks - if (!arena.canSpec(p)) - return true; - - // If player is in a boat/minecart, eject! - if (p.isInsideVehicle()) - p.leaveVehicle(); - - // If player is in a bed, unbed! - if (p.isSleeping()) - { - p.kickPlayer("Banned for life... Nah, just don't join from a bed ;)"); - return true; - } - - // Spectate the arena! - arena.playerSpec(p, p.getLocation()); - - MAUtils.tellPlayer(p, Msg.SPEC_PLAYER_SPECTATE); - return true; - } - - /* - * Prints a list of all arenas. - */ - if (base.equals("arenas")) - { - String list = MAUtils.listToString(player ? am.getPermittedArenas(p) : am.arenas, plugin); - MAUtils.tellPlayer(sender, Msg.MISC_LIST_ARENAS.toString(list)); - return true; - } - - /* - * Prints a list of all live players in all arenas, or live players in a specific arena. - */ - if (base.equals("players") || base.equals("list")) - { - if (!arg1.isEmpty()) - { - Arena arena = am.getArenaWithName(arg1); - if (arena == null) - { - MAUtils.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); - return true; - } - - String list = MAUtils.listToString(arena.getLivingPlayers(), plugin); - MAUtils.tellPlayer(sender, Msg.MISC_LIST_PLAYERS.toString(list)); - } - else - { - StringBuffer buffy = new StringBuffer(); - List players = new LinkedList(); - for (Arena arena : am.arenas) - players.addAll(arena.getLivingPlayers()); - buffy.append(MAUtils.listToString(players, plugin)); - MAUtils.tellPlayer(sender, Msg.MISC_LIST_PLAYERS.toString(buffy.toString())); - } - return true; - } - - /* - * Prints a list of all non-ready players in current arena, or non-ready players in a specific arena. - */ - if (base.equals("notready")) - { - Arena arena; - if (!arg1.isEmpty()) - { - arena = am.getArenaWithName(arg1); - if (arena == null) - { - MAUtils.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); - return true; - } - } - else if (player) - { - arena = am.getArenaWithPlayer(p); - if (arena == null) - { - MAUtils.tellPlayer(sender, Msg.LEAVE_NOT_PLAYING); - return true; - } - } - else - { - MAUtils.tellPlayer(sender, "Usage: /ma notready "); - return true; - } - - String list = MAUtils.listToString(arena.getNonreadyPlayers(), plugin); - MAUtils.tellPlayer(sender, Msg.MISC_LIST_PLAYERS.toString(list)); - return true; - } - - - - /*//////////////////////////////////////////////////////////////// - // - // Setup & Reload - // - ////////////////////////////////////////////////////////////////*/ - - /* - * Enable or disable arena(s) - */ - if ((base.equals("enable") || base.equals("disable"))) - { - if (!console && !(player && plugin.has(p, "mobarena.admin.enable")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - if (!arg1.isEmpty()) - { - Arena arena = am.getArenaWithName(arg1); - if (arena != null) - { - arena.enabled = base.equals("enable"); - arena.serializeConfig(); - MAUtils.tellPlayer(sender, "Arena '" + arena.configName() + "' " + ((arena.enabled) ? ChatColor.GREEN : ChatColor.RED) + base + "d"); - } - else - { - MAUtils.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); - } - } - else - { - am.enabled = base.equals("enable"); - am.serializeSettings(); - MAUtils.tellPlayer(sender, "All arenas " + ((am.enabled) ? ChatColor.GREEN : ChatColor.RED) + base + "d"); - } - return true; - } - - /* - * Kick player from whichever arena they are in. - */ - if (base.equals("kick")) - { - if (!console && !(player && plugin.has(p, "mobarena.admin.kick")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - if (arg1.isEmpty()) - { - MAUtils.tellPlayer(sender, "Usage: /ma kick "); - return true; - } - - Arena arena = am.getArenaWithPlayer(arg1); - if (arena == null) - { - MAUtils.tellPlayer(sender, "That player is not in an arena."); - return true; - } - else - { - Player pl = server.getPlayer(arg1); - am.arenaMap.remove(pl); - arena.playerLeave(pl); - MAUtils.tellPlayer(sender, "Player '" + arg1 + "' was kicked from arena '" + arena.configName() + "'."); - MAUtils.tellPlayer(pl, "You were kicked by " + ((player) ? p.getName() : "the server.")); - return true; - } - } - - /* - * Restore a player's inventory. - */ - if (base.equals("restore")) - { - if (!console && !(player && plugin.has(p, "mobarena.admin.restore")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - if (!arg1.isEmpty()) - { - if (am.getArenaWithPlayer(arg1) != null) - { - MAUtils.tellPlayer(sender, "Player is currently in an arena."); - return true; - } - - if (MAUtils.restoreInventory(Bukkit.getServer().getPlayer(arg1))); - MAUtils.tellPlayer(sender, "Restored " + arg1 + "'s inventory!"); - return true; - } - } - - /* - * Force start/end arenas. - */ - if (base.equals("force")) - { - if (arg1.equals("end")) - { - if (!console && !(player && plugin.has(p, "mobarena.admin.force.end")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - if (arg2.isEmpty()) - { - for (Arena arena : am.arenas) - arena.forceEnd(); - - am.arenaMap.clear(); - return true; - } - - Arena arena = am.getArenaWithName(arg2); - if (arena == null) - { - MAUtils.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); - return true; - } - - if (arena.getAllPlayers().isEmpty()) - { - MAUtils.tellPlayer(sender, Msg.FORCE_END_EMPTY); - return true; - } - - arena.forceEnd(); - MAUtils.tellPlayer(sender, Msg.FORCE_END_ENDED); - return true; - } - else if (arg1.equals("start")) - { - if (!console && !(player && plugin.has(p, "mobarena.admin.force.start")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - if (arg2.isEmpty()) - { - MAUtils.tellPlayer(sender, "Usage: /ma force start "); - return true; - } - - Arena arena = am.getArenaWithName(arg2); - if (arena == null) - { - MAUtils.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); - return true; - } - - if (arena.running) - { - MAUtils.tellPlayer(sender, Msg.FORCE_START_RUNNING); - return true; - } - if (arena.readyPlayers.isEmpty()) - { - MAUtils.tellPlayer(sender, Msg.FORCE_START_NOT_READY); - return true; - } - - arena.forceStart(); - MAUtils.tellPlayer(sender, Msg.FORCE_START_STARTED); - return true; - } - else - { - MAUtils.tellPlayer(sender, "Usage: /ma force [start|end] ()"); - return true; - } - } - - /* - * Reload the config-file. - */ - if (base.equals("config")) - { - if (!console && !(player && plugin.has(p, "mobarena.admin.config.reload")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - if (!arg1.equals("reload")) - { - MAUtils.tellPlayer(sender, "Usage: /ma config reload"); - return true; - } - - am.updateAll(); - MAUtils.tellPlayer(sender, "Config reloaded."); - return true; - } - - /* - * Get the current arena, and list all other arenas. - */ - if (base.equals("arena")) - { - if (!console && !(player && plugin.has(p, "mobarena.setup.arena")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - MAUtils.tellPlayer(sender, "Currently selected arena: " + ChatColor.GREEN + am.selectedArena.configName()); - - StringBuffer buffy = new StringBuffer(); - if (am.arenas.size() > 1) - { - for (Arena arena : am.arenas) - if (!arena.equals(am.selectedArena)) - buffy.append(arena.configName() + " "); - } - else buffy.append(Msg.MISC_NONE); - - MAUtils.tellPlayer(sender, "Other arenas: " + buffy.toString()); - return true; - } - - /* - * Set the current arena - */ - if (base.equals("setarena")) - { - if (!console && !(player && plugin.has(p, "mobarena.setup.setarena")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - if (arg1.isEmpty()) - { - MAUtils.tellPlayer(sender, "Usage: /ma setarena "); - return true; - } - - Arena arena = am.getArenaWithName(arg1); - if (arena != null) - { - am.selectedArena = arena; - MAUtils.tellPlayer(sender, "Currently selected arena: " + arena.configName()); - } - else - { - MAUtils.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); - } - return true; - } - - /* - * Create a new arena, and set the current arena to this new arena. - */ - if (base.equals("addarena")) - { - if (!(player && plugin.has(p, "mobarena.setup.addarena")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - if (arg1.isEmpty()) - { - MAUtils.tellPlayer(sender, "Usage: /ma addarena "); - return true; - } - - Arena arena = am.getArenaWithName(arg1); - if (arena != null) - { - MAUtils.tellPlayer(sender, "An arena with that name already exists."); - return true; - } - - arena = am.createArenaNode(arg1, p.getWorld()); - am.arenas.add(arena); - am.selectedArena = arena; - - MAUtils.tellPlayer(sender, "New arena with name '" + arg1 + "' created!"); - return true; - } - - if (base.equals("delarena")) - { - if (!console && !(player && plugin.has(p, "mobarena.setup.delarena")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - if (arg1.isEmpty()) - { - MAUtils.tellPlayer(sender, "Usage: /ma delarena "); - return true; - } - if (am.arenas.size() < 2) - { - MAUtils.tellPlayer(sender, "At least one arena must exist."); - return true; - } - - Arena arena = am.getArenaWithName(arg1); - if (arena == null) - { - MAUtils.tellPlayer(sender, "There is no arena with that name."); - return true; - } - - am.removeArenaNode(arg1); - am.arenas.remove(arena); - am.selectedArena = (am.selectedArena.equals(arena)) ? am.arenas.get(0) : am.selectedArena; - - MAUtils.tellPlayer(sender, "Arena '" + arena.configName() + "' deleted."); - return true; - } - - /* - * Enable or disable protection - */ - if (base.equals("protect")) - { - if (!console && !(player && plugin.has(p, "mobarena.setup.protect")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - Arena arena; - - // No arguments - if (arg1.isEmpty()) - { - arena = am.selectedArena; - arena.protect = !arena.protect; - } - - // One argument - else if (arg2.isEmpty()) - { - // true/false - if (arg1.equals("true") || arg1.equals("false")) - { - arena = am.selectedArena; - arena.protect = arg1.equals("true"); - } - // Arena name - else - { - arena = am.getArenaWithName(arg1); - if (arena == null) - { - MAUtils.tellPlayer(sender, "There is no arena with that name."); - MAUtils.tellPlayer(sender, "Usage: /ma protect ([true|false])"); - MAUtils.tellPlayer(sender, " or /ma protect ([true|false])"); - return true; - } - arena.protect = !arena.protect; - } - } - - // Two arguments - else - { - if (!(arg2.equals("true") || arg2.equals("false"))) - { - MAUtils.tellPlayer(sender, "Usage: /ma protect ([true|false])"); - MAUtils.tellPlayer(sender, " or /ma protect ([true|false])"); - return true; - } - arena = am.getArenaWithName(arg1); - if (arena == null) - { - MAUtils.tellPlayer(sender, "There is no arena with that name."); - MAUtils.tellPlayer(sender, "Usage: /ma protect ([true|false])"); - MAUtils.tellPlayer(sender, " or /ma protect ([true|false])"); - return true; - } - arena.protect = arg2.equals("true"); - } - - arena.serializeConfig(); - MAUtils.tellPlayer(sender, "Protection for arena '" + arena.configName() + "': " + ((arena.protect) ? ChatColor.GREEN + "on" : ChatColor.RED + "off")); - return true; - } - - if (base.equals("editarena")) - { - if (!console && !(player && plugin.has(p, "mobarena.setup.editarena")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - Arena arena; - - // No arguments. - if (arg1.isEmpty()) - { - arena = am.selectedArena; - arena.edit = !arena.edit; - } - - // One argument. - else if (arg2.isEmpty()) - { - // Argument is [true|false] - if (arg1.equals("true") || arg1.equals("false")) - { - arena = am.selectedArena; - arena.edit = arg1.equals("true"); - } - // Argument is - else - { - arena = am.getArenaWithName(arg1); - if (arena == null) - { - MAUtils.tellPlayer(sender, "There is no arena with that name."); - MAUtils.tellPlayer(sender, "Usage: /ma editarena ([true|false])"); - MAUtils.tellPlayer(sender, " or /ma editarena ([true|false])"); - return true; - } - arena.edit = !arena.edit; - } - } - - // Two arguments - else - { - if (!(arg2.equals("true") || arg2.equals("false"))) - { - MAUtils.tellPlayer(sender, "Usage: /ma editarena ([true|false])"); - MAUtils.tellPlayer(sender, " or /ma editarena ([true|false])"); - return true; - } - arena = am.getArenaWithName(arg1); - if (arena == null) - { - MAUtils.tellPlayer(sender, "There is no arena with that name."); - MAUtils.tellPlayer(sender, "Usage: /ma editarena ([true|false])"); - MAUtils.tellPlayer(sender, " or /ma editarena ([true|false])"); - return true; - } - arena.edit = arg2.equals("true"); - } - - MAUtils.tellPlayer(sender, "Edit mode for arena '" + arena.configName() + "': " + ((arena.edit) ? ChatColor.GREEN + "true" : ChatColor.RED + "false")); - if (arena.edit) MAUtils.tellPlayer(sender, "Remember to turn it back off after editing!"); - return true; - } - - /* - * Set region points [p1|p2] for the current arena. - */ - if (base.equals("setregion")) - { - if (!(player && plugin.has(p, "mobarena.setup.setregion")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - if (!(arg1.equals("p1") || arg1.equals("p2"))) - { - MAUtils.tellPlayer(sender, "Usage: /ma setregion [p1|p2]"); - return true; - } - - MAUtils.setArenaCoord(plugin.getMAConfig(), am.selectedArena, arg1, p.getLocation()); - MAUtils.tellPlayer(sender, "Set region point " + arg1 + " for arena '" + am.selectedArena.configName() + "'"); - return true; - } - - /* - * Expand the region (arg1) [up|down|out] - */ - if (base.equals("expandregion")) - { - if (!console && !(player && plugin.has(p, "mobarena.setup.expandregion")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - if (args.length != 3 || !arg1.matches("(-)?[0-9]+")) - { - MAUtils.tellPlayer(sender, "Usage: /ma expandregion [up|down|out]"); - return true; - } - if (am.selectedArena.p1 == null || am.selectedArena.p2 == null) - { - MAUtils.tellPlayer(sender, "You must first define p1 and p2"); - return true; - } - - if (arg2.equals("up")) - { - am.selectedArena.p2.setY(Math.min(127, am.selectedArena.p2.getY() + Integer.parseInt(arg1))); - } - else if (arg2.equals("down")) - { - am.selectedArena.p1.setY(Math.max(0, am.selectedArena.p1.getY() - Integer.parseInt(arg1))); - } - else if (arg2.equals("out")) - { - am.selectedArena.p1.setX(am.selectedArena.p1.getX() - Integer.parseInt(arg1)); - am.selectedArena.p1.setZ(am.selectedArena.p1.getZ() - Integer.parseInt(arg1)); - am.selectedArena.p2.setX(am.selectedArena.p2.getX() + Integer.parseInt(arg1)); - am.selectedArena.p2.setZ(am.selectedArena.p2.getZ() + Integer.parseInt(arg1)); - } - else - { - MAUtils.tellPlayer(sender, "Usage: /ma expandregion [up|down|out]"); - return true; - } - - // In case of a "negative" region, fix it! - MAUtils.fixRegion(plugin.getMAConfig(), am.selectedArena.world, am.selectedArena); - - MAUtils.tellPlayer(sender, "Region for '" + am.selectedArena.configName() + "' expanded " + arg2 + " by " + arg1 + " blocks."); - am.selectedArena.serializeConfig(); - am.selectedArena.load(plugin.getMAConfig()); - return true; - } - - if (base.equals("showregion")) - { - if (!(player && plugin.has(p, "mobarena.setup.showregion")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - Arena arena = am.getArenaAtLocation(p.getLocation()); - if (arena == null) - arena = am.selectedArena; - - if (arena.p1 == null || arena.p2 == null) - { - MAUtils.tellPlayer(sender, "The region is not defined for the selected arena."); - return true; - } - if (showingRegion) - { - MAUtils.tellPlayer(sender, "Already showing region."); - return true; - } - - Material mat = Material.WOOL; - byte color = (byte)0; - - if (arg1.equals("glowstone")) - mat = Material.GLOWSTONE; - else if (arg1.equals("white") || arg1.equals("red") || arg1.equals("blue")) - color = DyeColor.valueOf(arg1.toUpperCase()).getData(); - else if (arg1.equals("green")) // Dark green sucks - color = 0x5; - else - mat = Material.GLASS; - - // Set the variable so we don't overwrite the region. - showingRegion = true; - - // Show the frame. - final World world = arena.world; - final Set blocks = MAUtils.showRegion(p, world, arena.p1, arena.p2, mat.getId(), color); - final Player fp = p; - - // And hide the frame. - plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, - new Runnable() - { - public void run() - { - for (int[] buffer : blocks) - fp.sendBlockChange(new Location(world, buffer[0], buffer[1], buffer[2]), buffer[3], (byte) 0); - //world.getBlockAt(buffer[0], buffer[1], buffer[2]).setTypeIdAndData(buffer[3], (byte) 0, false); - showingRegion = false; - } - }, 2*20); - - return true; - } - - if (base.equals("setlobbyregion")) - { - if (!(player && plugin.has(p, "mobarena.setup.setlobbyregion")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - if (!(arg1.equals("l1") || arg1.equals("l2"))) - { - MAUtils.tellPlayer(sender, "Usage: /ma setlobbyregion [l1|l2]"); - return true; - } - - MAUtils.setArenaCoord(plugin.getMAConfig(), am.selectedArena, arg1, p.getLocation()); - MAUtils.tellPlayer(sender, "Set lobby point " + arg1 + " for arena '" + am.selectedArena.configName() + "'"); - return true; - } - - if (base.equals("expandlobbyregion")) - { - if (!console && !(player && plugin.has(p, "mobarena.setup.expandlobbyregion")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - if (args.length != 3 || !arg1.matches("[0-9]+")) - { - MAUtils.tellPlayer(sender, "Usage: /ma expandlobbyregion [up|down|out]"); - return true; - } - if (am.selectedArena.l1 == null || am.selectedArena.l2 == null) - { - MAUtils.tellPlayer(sender, "You must first define l1 and l2"); - return true; - } - - if (arg2.equals("up")) - { - am.selectedArena.l2.setY(Math.min(127, am.selectedArena.l2.getY() + Integer.parseInt(arg1))); - } - else if (arg2.equals("down")) - { - am.selectedArena.l1.setY(Math.max(0, am.selectedArena.l1.getY() - Integer.parseInt(arg1))); - } - else if (arg2.equals("out")) - { - am.selectedArena.l1.setX(am.selectedArena.l1.getX() - Integer.parseInt(arg1)); - am.selectedArena.l1.setZ(am.selectedArena.l1.getZ() - Integer.parseInt(arg1)); - am.selectedArena.l2.setX(am.selectedArena.l2.getX() + Integer.parseInt(arg1)); - am.selectedArena.l2.setZ(am.selectedArena.l2.getZ() + Integer.parseInt(arg1)); - } - else - { - MAUtils.tellPlayer(sender, "Usage: /ma expandlobbyregion [up|down|out]"); - return true; - } - - MAUtils.tellPlayer(sender, "Lobby region for '" + am.selectedArena.configName() + "' expanded " + arg2 + " by " + arg1 + " blocks."); - am.selectedArena.serializeConfig(); - am.selectedArena.load(plugin.getMAConfig()); - return true; - } - - /* - * Set warp points [arena|lobby|spectator] for the current arena. - */ - if (base.equals("setwarp")) - { - if (!(player && plugin.has(p, "mobarena.setup.setwarp")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - if (!(arg1.equals("arena") || arg1.equals("lobby") || arg1.equals("spectator"))) - { - MAUtils.tellPlayer(sender, "Usage: /ma setwarp [arena|lobby|spectator]"); - return true; - } - - MAUtils.setArenaCoord(plugin.getMAConfig(), am.selectedArena, arg1, p.getLocation()); - MAUtils.tellPlayer(sender, "Warp point " + arg1 + " was set for arena '" + am.selectedArena.configName() + "'"); - MAUtils.tellPlayer(sender, "Type /ma checkdata to see if you're missing anything..."); - return true; - } - - /* - * List all the current spawnpoints for the current arena. - */ - if (base.equals("spawnpoints")) - { - if (!console && !(player && plugin.has(p, "mobarena.setup.spawnpoints")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - StringBuffer buffy = new StringBuffer(); - Set spawnpoints = plugin.getMAConfig().getKeys("arenas." + am.selectedArena.configName() + ".coords.spawnpoints"); - - if (spawnpoints != null) - { - for (String s : spawnpoints) - { - buffy.append(s); - buffy.append(" "); - } - } - else - { - buffy.append(Msg.MISC_NONE); - } - - MAUtils.tellPlayer(sender, "Spawnpoints for arena '" + am.selectedArena.configName() + "': " + buffy.toString()); - return true; - } - - /* - * Add a spawnpoint for the current arena. - */ - if (base.equals("addspawn")) - { - if (!(player && plugin.has(p, "mobarena.setup.addspawn")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - if (arg1 == null || !arg1.matches("^[a-zA-Z][a-zA-Z0-9]*$")) - { - MAUtils.tellPlayer(sender, "Usage: /ma addspawn "); - return true; - } - - MAUtils.setArenaCoord(plugin.getMAConfig(), am.selectedArena, "spawnpoints." + arg1, p.getLocation()); - MAUtils.tellPlayer(sender, "Spawnpoint " + arg1 + " added for arena \"" + am.selectedArena.configName() + "\""); - return true; - } - - /* - * Delete a spawnpoint for the current arena. - */ - if (base.equals("delspawn")) - { - if (!console && !(player && plugin.has(p, "mobarena.setup.delspawn")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - if (arg1 == null || !arg1.matches("^[a-zA-Z][a-zA-Z0-9]*$")) - { - MAUtils.tellPlayer(sender, "Usage: /ma delspawn "); - return true; - } - - if (MAUtils.delArenaCoord(plugin.getMAConfig(), am.selectedArena, "spawnpoints." + arg1)) - MAUtils.tellPlayer(sender, "Spawnpoint " + arg1 + " deleted for arena '" + am.selectedArena.configName() + "'"); - else - MAUtils.tellPlayer(sender, "Could not find the spawnpoint " + arg1 + "for the arena '" + am.selectedArena.configName() + "'"); - return true; - } - - if (base.equals("containers")) - { - if (!console && !(player && plugin.has(p, "mobarena.setup.containers")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - StringBuffer buffy = new StringBuffer(); - Set containers = plugin.getMAConfig().getKeys("arenas." + am.selectedArena.configName() + ".coords.containers"); - - if (containers != null) - { - for (String s : containers) - { - buffy.append(s); - buffy.append(" "); - } - } - else - { - buffy.append(Msg.MISC_NONE); - } - - MAUtils.tellPlayer(sender, "Containers for arena '" + am.selectedArena.configName() + "': " + buffy.toString()); - return true; - } - - if (base.equals("addcontainer")) - { - if (!(player && plugin.has(p, "mobarena.setup.addcontainer")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - if (arg1 == null || !arg1.matches("^[a-zA-Z][a-zA-Z0-9]*$")) - { - MAUtils.tellPlayer(sender, "Usage: /ma addcontainer "); - return true; - } - if (!(p.getTargetBlock(null, 50).getState() instanceof ContainerBlock)) - { - MAUtils.tellPlayer(sender, "You must look at container."); - return true; - } - - MAUtils.setArenaCoord(plugin.getMAConfig(), am.selectedArena, "containers." + arg1, p.getTargetBlock(null, 50).getLocation()); - MAUtils.tellPlayer(sender, "Container '" + arg1 + "' added for arena \"" + am.selectedArena.configName() + "\""); - return true; - } - - if (base.equals("delcontainer")) - { - if (!console && !(player && plugin.has(p, "mobarena.setup.delcontainer")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - if (arg1 == null || !arg1.matches("^[a-zA-Z][a-zA-Z0-9]*$")) - { - MAUtils.tellPlayer(sender, "Usage: /ma delcontainer "); - return true; - } - - if (MAUtils.delArenaCoord(plugin.getMAConfig(), am.selectedArena, "containers." + arg1)) - MAUtils.tellPlayer(sender, "Container '" + arg1 + "' deleted for arena '" + am.selectedArena.configName() + "'"); - else - MAUtils.tellPlayer(sender, "Could not find the container '" + arg1 + "' for arena '" + am.selectedArena.configName() + "'"); - return true; - } - - if (base.equals("checkdata")) - { - if (!console && !(player && plugin.has(p, "mobarena.setup.checkdata")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - Arena arena = arg1.isEmpty() ? am.selectedArena : am.getArenaWithName(arg1); - if (arena == null) - { - MAUtils.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); - return true; - } - - MAUtils.checkData(arena, sender); - return true; - } - - if (base.equals("auto-generate") || base.equals("autogenerate")) - { - if (!(player && plugin.has(p, "mobarena.setup.autogenerate")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - if (arg1 == null || !arg1.matches("^[a-zA-Z][a-zA-Z0-9]*$")) - { - MAUtils.tellPlayer(sender, "Usage: /ma auto-generate "); - return true; - } - if (am.getArenaWithName(arg1) != null) - { - MAUtils.tellPlayer(sender, "An arena with that name already exists."); - return true; - } - - if (MAUtils.doooooItHippieMonster(p.getLocation(), 13, arg1, plugin)) - MAUtils.tellPlayer(sender, "Arena with name '" + arg1 + "' generated."); - else - MAUtils.tellPlayer(sender, "Could not auto-generate arena."); - return true; - } - - if (base.equals("auto-degenerate") || base.equals("autodegenerate")) - { - if (!console && !(player && plugin.has(p, "mobarena.setup.autodegenerate")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - if (arg1.isEmpty()) - { - MAUtils.tellPlayer(sender, "Usage: /ma auto-degenerate "); - return true; - } - if (am.arenas.size() < 2) - { - MAUtils.tellPlayer(sender, "At least one arena must exist!"); - return true; - } - if (am.getArenaWithName(arg1) == null) - { - MAUtils.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); - return true; - } - - if (MAUtils.undoItHippieMonster(arg1, plugin, true)) - MAUtils.tellPlayer(sender, "Arena with name '" + arg1 + "' degenerated."); - else - MAUtils.tellPlayer(sender, "Could not degenerate arena."); - return true; - } - - if (base.equals("dooooo") && arg1.equals("it") && arg2.equals("hippie") && arg3.equals("monster")) - { - if (!(player && plugin.has(p, "mobarena.setup.autogenerate")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - - String name = "a0"; - do name = name.substring(0,1) + (Integer.parseInt(name.substring(1,2)) + 1); - while (am.getArenaWithName(name) != null); - - if (MAUtils.doooooItHippieMonster(p.getLocation(), 13, name, plugin)) - MAUtils.tellPlayer(sender, "Arena with name '" + name + "' generated."); - else - MAUtils.tellPlayer(sender, "Could not auto-generate arena."); - return true; - } - - if (base.equals("undo") && arg1.equals("it") && arg2.equals("hippie") && arg3.equals("monster")) - { - if (!(player && plugin.has(p, "mobarena.setup.autodegenerate")) && !op) - { - MAUtils.tellPlayer(sender, Msg.MISC_NO_ACCESS); - return true; - } - if (am.arenas.size() < 2) - { - MAUtils.tellPlayer(sender, "At least one arena must exist!"); - return true; - } - if (am.getArenaWithName("a1") == null) - { - MAUtils.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); - return true; - } - - String name = "a1"; - while (am.getArenaWithName(name) != null) - name = name.substring(0,1) + (Integer.parseInt(name.substring(1,2)) + 1); - name = name.substring(0,1) + (Integer.parseInt(name.substring(1,2)) - 1); - - if (MAUtils.undoItHippieMonster(name, plugin, true)) - MAUtils.tellPlayer(sender, "Arena with name '" + name + "' degenerated."); - else - MAUtils.tellPlayer(sender, "Could not degenerate arena."); - return true; - } - - MAUtils.tellPlayer(sender, "Command not found."); - return true; - } - - private boolean sanityChecks(Player p, Arena arena, String arg1, List arenas) - { - if (arenas.size() > 1 && arg1.isEmpty()) - MAUtils.tellPlayer(p, Msg.JOIN_ARG_NEEDED); - else if (arena == null) - MAUtils.tellPlayer(p, Msg.ARENA_DOES_NOT_EXIST); - else if (am.arenaMap.containsKey(p) && (am.arenaMap.get(p).arenaPlayers.contains(p) || am.arenaMap.get(p).lobbyPlayers.contains(p))) - MAUtils.tellPlayer(p, Msg.JOIN_IN_OTHER_ARENA); - else - return true; - - return false; - } -} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/MAEntityListener.java b/src/com/garbagemule/MobArena/MAEntityListener.java deleted file mode 100644 index 7c853d4..0000000 --- a/src/com/garbagemule/MobArena/MAEntityListener.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.garbagemule.MobArena; - -import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.event.entity.EndermanPickupEvent; -import org.bukkit.event.entity.EndermanPlaceEvent; -import org.bukkit.event.entity.EntityCombustEvent; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.entity.EntityDeathEvent; -import org.bukkit.event.entity.EntityExplodeEvent; -import org.bukkit.event.entity.EntityListener; -import org.bukkit.event.entity.EntityRegainHealthEvent; -import org.bukkit.event.entity.EntityTargetEvent; - -import com.garbagemule.MobArena.Arena; -import com.garbagemule.MobArena.ArenaMaster; - -public class MAEntityListener extends EntityListener -{ - private ArenaMaster am; - - public MAEntityListener(ArenaMaster am) - { - this.am = am; - } - - public void onEntityRegainHealth(EntityRegainHealthEvent event) - { - for (Arena arena : am.arenas) - arena.eventListener.onEntityRegainHealth(event); - } - - public void onEntityDeath(EntityDeathEvent event) - { - for (Arena arena : am.arenas) - arena.eventListener.onEntityDeath(event); - } - - public void onEntityDamage(EntityDamageEvent event) - { - for (Arena arena : am.arenas) - arena.eventListener.onEntityDamage(event); - } - - public void onCreatureSpawn(CreatureSpawnEvent event) - { - for (Arena arena : am.arenas) - arena.eventListener.onCreatureSpawn(event); - } - - public void onEntityExplode(EntityExplodeEvent event) - { - for (Arena arena : am.arenas) - arena.eventListener.onEntityExplode(event); - } - - public void onEntityCombust(EntityCombustEvent event) - { - for (Arena arena : am.arenas) - arena.eventListener.onEntityCombust(event); - } - - public void onEntityTarget(EntityTargetEvent event) - { - for (Arena arena : am.arenas) - arena.eventListener.onEntityTarget(event); - } - - public void onEndermanPickup(EndermanPickupEvent event) - { - for (Arena arena : am.arenas) - arena.eventListener.onEndermanPickup(event); - } - - public void onEndermanPickup(EndermanPlaceEvent event) - { - for (Arena arena : am.arenas) - arena.eventListener.onEndermanPlace(event); - } -} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/MAListener.java b/src/com/garbagemule/MobArena/MAListener.java deleted file mode 100644 index 07e90c2..0000000 --- a/src/com/garbagemule/MobArena/MAListener.java +++ /dev/null @@ -1,724 +0,0 @@ -package com.garbagemule.MobArena; - -import java.util.LinkedList; -import java.util.List; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.block.BlockFace; -import org.bukkit.block.BlockState; -import org.bukkit.block.ContainerBlock; -import org.bukkit.block.Sign; -import org.bukkit.entity.Entity; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.entity.Projectile; -import org.bukkit.entity.Slime; -import org.bukkit.entity.Wolf; -import org.bukkit.event.Event.Result; -import org.bukkit.event.block.Action; -import org.bukkit.event.block.BlockBreakEvent; -import org.bukkit.event.block.BlockBurnEvent; -import org.bukkit.event.block.BlockEvent; -import org.bukkit.event.block.BlockIgniteEvent; -import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.block.SignChangeEvent; -import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.event.entity.EndermanPickupEvent; -import org.bukkit.event.entity.EndermanPlaceEvent; -import org.bukkit.event.entity.EntityCombustEvent; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.event.entity.EntityDamageEvent; -import org.bukkit.event.entity.EntityDeathEvent; -import org.bukkit.event.entity.EntityExplodeEvent; -import org.bukkit.event.entity.EntityRegainHealthEvent; -import org.bukkit.event.entity.EntityTargetEvent; -import org.bukkit.event.entity.EntityDamageEvent.DamageCause; -import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; -import org.bukkit.event.entity.EntityTargetEvent.TargetReason; -import org.bukkit.event.player.PlayerAnimationEvent; -import org.bukkit.event.player.PlayerBucketEmptyEvent; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import org.bukkit.event.player.PlayerDropItemEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerKickEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.event.player.PlayerTeleportEvent; -import org.bukkit.inventory.ItemStack; -import org.bukkit.material.Attachable; -import org.bukkit.material.Bed; -import org.bukkit.material.Door; -import org.bukkit.material.Redstone; - -import com.garbagemule.MobArena.leaderboards.Leaderboard; -import com.garbagemule.MobArena.repairable.*; - -public class MAListener implements ArenaListener -{ - private MobArena plugin; - private Arena arena; - - public MAListener(Arena arena, MobArena plugin) - { - this.arena = arena; - this.plugin = plugin; - } - - public void onBlockBreak(BlockBreakEvent event) - { - if (onBlockDestroy(event)) - return; - - event.setCancelled(true); - } - - public void onBlockBurn(BlockBurnEvent event) - { - if (onBlockDestroy(event)) - return; - - event.setCancelled(true); - } - - private boolean onBlockDestroy(BlockEvent event) - { - if (!arena.inRegion(event.getBlock().getLocation()) || arena.edit || (!arena.protect && arena.running)) - return true; - - Block b = event.getBlock(); - if (arena.blocks.remove(b) || b.getType() == Material.TNT) - return true; - - if (arena.softRestore && arena.running) - { - BlockState state = b.getState(); - - Repairable r = null; - if (state instanceof ContainerBlock) - r = new RepairableContainer(state); - else if (state instanceof Sign) - r = new RepairableSign(state); - else if (state.getData() instanceof Attachable) - r = new RepairableAttachable(state); - else - r = new RepairableBlock(state); - - arena.repairables.add(r); - - if (!arena.softRestoreDrops) - b.setTypeId(0); - - return true; - } - - return false; - } - - public void onBlockPlace(BlockPlaceEvent event) - { - Block b = event.getBlock(); - - if (!arena.inRegion(b.getLocation()) || arena.edit) - return; - - if (arena.running && arena.inArena(event.getPlayer())) - { - arena.blocks.add(b); - Material mat = b.getType(); - - if (mat == Material.WOODEN_DOOR || mat == Material.IRON_DOOR_BLOCK) - arena.blocks.add(b.getRelative(0,1,0)); - - return; - } - - // If the arena isn't running, or if the player isn't in the arena, cancel. - event.setCancelled(true); - } - - public void onBlockIgnite(BlockIgniteEvent event) - { - if (!arena.inRegion(event.getBlock().getLocation())) - return; - - switch (event.getCause()) - { - case LIGHTNING: - event.setCancelled(true); - break; - case SPREAD: - case FLINT_AND_STEEL: - if (arena.running) - arena.blocks.add(event.getBlock()); - else - event.setCancelled(true); - break; - default: - break; - } - } - - public void onSignChange(SignChangeEvent event) - { - arena.leaderboard = new Leaderboard(plugin, arena, event.getBlock().getLocation()); - MAUtils.setArenaCoord(plugin.getMAConfig(), arena, "leaderboard", event.getBlock().getLocation()); - MAUtils.tellPlayer(event.getPlayer(), "Leaderboard made. Now set up the stat signs!"); - } - - public void onCreatureSpawn(CreatureSpawnEvent event) - { - if (!arena.inRegion(event.getLocation())) // || event.getSpawnReason() == SpawnReason.CUSTOM) - return; - - LivingEntity entity = (LivingEntity) event.getEntity(); - if (arena.running && entity instanceof Slime) - arena.monsters.add(entity); - - // If running == true, setCancelled(false), and vice versa. - event.setCancelled(!arena.running); - } - - public void onEntityExplode(EntityExplodeEvent event) - { - if (!arena.monsters.contains(event.getEntity()) && !arena.inRegionRadius(event.getLocation(), 10)) - return; - - arena.monsters.remove(event.getEntity()); - - // Cancel if the arena isn't running - if (!arena.running) - { - event.setCancelled(true); - return; - } - - // Uncancel, just in case. - event.setCancelled(false); - - // If the arena isn't destructible, just clear the blocklist. - if (!arena.softRestore && arena.protect) - { - List blocks = new LinkedList(arena.blocks); - event.blockList().retainAll(blocks); - return; - } - - if (!arena.softRestoreDrops) - event.setYield(0); - - // Handle all the blocks in the block list. - for (Block b : event.blockList()) - { - BlockState state = b.getState(); - - if (state.getData() instanceof Door && ((Door) state.getData()).isTopHalf()) - state = b.getRelative(BlockFace.DOWN).getState(); - else if (state.getData() instanceof Bed && ((Bed) state.getData()).isHeadOfBed()) - state = b.getRelative(((Bed) state.getData()).getFacing().getOppositeFace()).getState(); - - // Create a Repairable from the block. - Repairable r = null; - if (state instanceof ContainerBlock) - r = new RepairableContainer(state); - else if (state instanceof Sign) - r = new RepairableSign(state); - else if (state.getData() instanceof Bed) - r = new RepairableBed(state); - else if (state.getData() instanceof Door) - r = new RepairableDoor(state); - else if (state.getData() instanceof Attachable || state.getData() instanceof Redstone) - r = new RepairableAttachable(state); - else - r = new RepairableBlock(state); - - // Cakes and liquids should just get removed. If player-placed block, drop as item. - Material mat = state.getType(); - if (mat == Material.CAKE_BLOCK || mat == Material.WATER || mat == Material.LAVA) - arena.blocks.remove(b); - else if (arena.blocks.remove(b)) - arena.world.dropItemNaturally(b.getLocation(), new ItemStack(state.getTypeId(), 1)); - else if (arena.softRestore) - arena.repairables.add(r); - else - arena.queueRepairable(r); - } - } - - - /****************************************************** - * - * DEATH LISTENERS - * - ******************************************************/ - - public void onEntityDeath(EntityDeathEvent event) - { - if (event.getEntity() instanceof Player) - onPlayerDeath(event, (Player) event.getEntity()); - - else if (arena.monsters.remove(event.getEntity())) - onMonsterDeath(event); - } - - private void onPlayerDeath(EntityDeathEvent event, Player player) - { - if (arena.inArena(player) || arena.lobbyPlayers.contains(player)) - { - event.getDrops().clear(); - arena.playerDeath(player); - } - } - - private void onMonsterDeath(EntityDeathEvent event) - { - EntityDamageEvent e1 = event.getEntity().getLastDamageCause(); - EntityDamageByEntityEvent e2 = (e1 instanceof EntityDamageByEntityEvent) ? (EntityDamageByEntityEvent) e1 : null; - Entity damager = (e2 != null) ? e2.getDamager() : null; - - if (damager instanceof Player) - arena.playerKill((Player) damager); - - event.getDrops().clear(); - arena.resetIdleTimer(); - return; - } - - - /****************************************************** - * - * DAMAGE LISTENERS - * - ******************************************************/ - - public void onEntityDamage(EntityDamageEvent event) - { - if (!arena.running) return; - - EntityDamageByEntityEvent e = (event instanceof EntityDamageByEntityEvent) ? (EntityDamageByEntityEvent) event : null; - Entity damagee = event.getEntity(); - Entity damager = null; - if (e != null) - { - damager = e.getDamager(); - if (damager instanceof Projectile) - damager = ((Projectile) damager).getShooter(); - } - - event.setCancelled(false); - - // Pet wolf - if (damagee instanceof Wolf && arena.pets.contains(damagee)) - onPetDamage(event, (Wolf) damagee, damager); - - // Player - else if (damagee instanceof Player) - onPlayerDamage(event, (Player) damagee, damager); - - // Monster - else if (arena.monsters.contains(damagee)) - onMonsterDamage(event, damagee, damager); - } - - private void onPlayerDamage(EntityDamageEvent event, Player player, Entity damager) - { - // Cancel all damage in the lobby - if (arena.lobbyPlayers.contains(player)) - event.setCancelled(true); - - // If not in the lobby or the arena, return - else if (!arena.inArena(player)) - return; - - // Cancel block explosion damage if detonate-damage: false - else if (!arena.detDamage && event.getCause() == DamageCause.BLOCK_EXPLOSION) - event.setCancelled(true); - - // If PvP is disabled and damager is a player, cancel damage - else if (!arena.pvp && damager instanceof Player) - event.setCancelled(true); - - // Log damage - if (!event.isCancelled()) - arena.arenaPlayerMap.get(player).getStats().dmgTaken += event.getDamage(); - } - - private void onPetDamage(EntityDamageEvent event, Wolf pet, Entity damager) - { - if (arena.hellhounds && (damager == null || damager instanceof Player)) - pet.setFireTicks(32768); - - event.setCancelled(true); - } - - private void onMonsterDamage(EntityDamageEvent event, Entity monster, Entity damager) - { - if (damager instanceof Player) - { - Player p = (Player) damager; - if (!arena.inArena(p)) - { - event.setCancelled(true); - return; - } - - arena.arenaPlayerMap.get(p).getStats().dmgDone += event.getDamage(); - arena.arenaPlayerMap.get(p).getStats().hits++; - } - else if (damager instanceof Wolf && arena.pets.contains(damager)) - { - event.setDamage(1); - arena.arenaPlayerMap.get((Player) ((Wolf) damager).getOwner()).getStats().dmgDone += event.getDamage(); - } - else if (damager instanceof LivingEntity) - { - if (!arena.monsterInfight) - event.setCancelled(true); - } - - // Boss - if (arena.bossWave != null && monster.equals(arena.bossWave.getEntity())) - { - if (event.getCause() == DamageCause.LIGHTNING) - { - event.setCancelled(true); - return; - } - - // Subtract boss health, and reset actual entity health - arena.bossWave.subtractHealth(event.getDamage()); - arena.bossWave.getEntity().setHealth(arena.bossWave.getEntity().getMaxHealth()); - - // Set damage to 1 for knockback and feedback - event.setDamage(1); - - // If the boss is dead, remove the entity and create an explosion! - if (arena.bossWave.getHealth() <= 0) - { - arena.bossWave.clear(); - arena.bossWave = null; - } - else if (arena.bossWave.getHealth() <= 100 && !arena.bossWave.isLowHealthAnnounced()) - { - MAUtils.tellAll(arena, Msg.WAVE_BOSS_LOW_HEALTH); - arena.bossWave.setLowHealthAnnounced(true); - } - } - } - - public void onEntityCombust(EntityCombustEvent event) - { - if (arena.monsters.contains(event.getEntity())) - event.setCancelled(true); - } - - public void onEntityTarget(EntityTargetEvent event) - { - if (!arena.running || event.isCancelled()) - return; - - if (arena.pets.contains(event.getEntity())) - { - if (event.getReason() != TargetReason.TARGET_ATTACKED_OWNER && event.getReason() != TargetReason.OWNER_ATTACKED_TARGET) - return; - - if (!(event.getTarget() instanceof Player)) - return; - - // If the target is a player, cancel. - event.setCancelled(true); - } - - else if (arena.monsters.contains(event.getEntity())) - { - if (event.getReason() == TargetReason.FORGOT_TARGET) - event.setTarget(MAUtils.getClosestPlayer(event.getEntity(), arena)); - - else if (event.getReason() == TargetReason.TARGET_DIED) - event.setTarget(MAUtils.getClosestPlayer(event.getEntity(), arena)); - - else if (event.getReason() == TargetReason.TARGET_ATTACKED_ENTITY) - if (arena.pets.contains(event.getTarget())) - event.setCancelled(true); - - else if (event.getReason() == TargetReason.CLOSEST_PLAYER) - if (!arena.inArena((Player) event.getTarget())) - event.setCancelled(true); - } - } - - public void onEndermanPickup(EndermanPickupEvent event) - { - if (arena.inRegion(event.getBlock().getLocation())) - event.setCancelled(true); - } - - public void onEndermanPlace(EndermanPlaceEvent event) - { - if (arena.inRegion(event.getLocation())) - event.setCancelled(true); - } - - public void onEntityRegainHealth(EntityRegainHealthEvent event) - { - if (!arena.running) return; - - if (!(event.getEntity() instanceof Player) || !arena.inArena((Player)event.getEntity())) - return; - - if (event.getRegainReason() == RegainReason.REGEN) - event.setCancelled(true); - } - - public void onPlayerAnimation(PlayerAnimationEvent event) - { - if (!arena.running || !arena.inArena(event.getPlayer())) - return; - - arena.arenaPlayerMap.get(event.getPlayer()).getStats().swings++; - } - - public void onPlayerDropItem(PlayerDropItemEvent event) - { - Player p = event.getPlayer(); - - // Player is in the lobby - if (arena.inLobby(p)) - { - MAUtils.tellPlayer(p, Msg.LOBBY_DROP_ITEM); - event.setCancelled(true); - } - - // Player is in the arena - else if (arena.inArena(p)) - { - if (!arena.shareInArena) - { - MAUtils.tellPlayer(p, Msg.LOBBY_DROP_ITEM); - event.setCancelled(true); - } - } - - // Player died/left - else if (p.getLocation().equals(arena.spectatorLoc) || p.getLocation().equals(arena.locations.get(p))) - { - MobArena.warning("Player '" + p.getName() + "' tried to steal item " + event.getItemDrop().getItemStack().getType()); - event.getItemDrop().remove(); - } - - // Player is in the spectator area - else if (arena.specPlayers.contains(p)) - { - MAUtils.tellPlayer(p, Msg.LOBBY_DROP_ITEM); - event.setCancelled(true); - } - } - - public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event) - { - if (!arena.readyPlayers.contains(event.getPlayer()) && !arena.inArena(event.getPlayer())) - return; - - if (!arena.running) - { - event.getBlockClicked().getRelative(event.getBlockFace()).setTypeId(0); - event.setCancelled(true); - return; - } - - Block liquid = event.getBlockClicked().getRelative(event.getBlockFace()); - arena.blocks.add(liquid); - } - - public void onPlayerInteract(PlayerInteractEvent event) - { - Player p = event.getPlayer(); - if (arena.inArena(p) || !arena.inLobby(p)) - return; - - // Player is in the lobby, so disallow using items. - Action a = event.getAction(); - if (a == Action.RIGHT_CLICK_AIR || a == Action.RIGHT_CLICK_BLOCK) - { - event.setUseItemInHand(Result.DENY); - event.setCancelled(true); - } - - // If there's no block involved, just return. - if (!event.hasBlock()) - return; - - // Iron block - if (event.getClickedBlock().getTypeId() == 42) - handleReadyBlock(p); - - // Sign - else if (event.getClickedBlock().getState() instanceof Sign) - { - Sign sign = (Sign) event.getClickedBlock().getState(); - handleSign(sign, p); - } - } - - private void handleReadyBlock(Player p) - { - if (arena.classMap.containsKey(p)) - { - MAUtils.tellPlayer(p, Msg.LOBBY_PLAYER_READY); - arena.playerReady(p); - } - else MAUtils.tellPlayer(p, Msg.LOBBY_PICK_CLASS); - } - - private void handleSign(Sign sign, Player p) - { - // Check if the first line is a class name. - String className = ChatColor.stripColor(sign.getLine(0)); - if (!arena.classes.contains(className) && !className.equalsIgnoreCase("random")) - return; - - // Check for permission. - if (!plugin.has(p, "mobarena.classes." + className) && !className.equalsIgnoreCase("random")) - { - MAUtils.tellPlayer(p, Msg.LOBBY_CLASS_PERMISSION); - return; - } - - // Delay the inventory stuff to ensure that right-clicking works. - delayAssignClass(p, className); - } - - private void delayAssignClass(final Player p, final String className) - { - Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, - new Runnable() - { - public void run() - { - arena.assignClass(p, className); - - if (!className.equalsIgnoreCase("random")) - MAUtils.tellPlayer(p, Msg.LOBBY_CLASS_PICKED, className, arena.classItems.get(className).get(0).getType()); - else - MAUtils.tellPlayer(p, Msg.LOBBY_CLASS_RANDOM); - } - }); - } - - public void onPlayerQuit(PlayerQuitEvent event) - { - Player p = event.getPlayer(); - if (!arena.enabled || (!arena.inArena(p) && !arena.inLobby(p))) - return; - - arena.playerLeave(p); - } - - public void onPlayerKick(PlayerKickEvent event) - { - Player p = event.getPlayer(); - if (!arena.enabled || (!arena.inArena(p) && !arena.inLobby(p))) - return; - - arena.playerLeave(p); - } - - public void onPlayerTeleport(PlayerTeleportEvent event) - { - if (!arena.enabled || !arena.setup || arena.allowWarp || arena.edit) - return; - - Location to = event.getTo(); - Location from = event.getFrom(); - Player p = event.getPlayer(); - - if (arena.inRegion(from)) - { - // Covers the case in which both locations are in the arena. - if ((arena.inRegion(to) && arena.running) || isWarp(to) || to.equals(arena.locations.get(p))) - return; - - MAUtils.tellPlayer(p, Msg.WARP_FROM_ARENA); - event.setCancelled(true); - } - else if (arena.inRegion(to)) - { - if (isWarp(from) || isWarp(to) || to.equals(arena.locations.get(p))) - return; - - MAUtils.tellPlayer(p, Msg.WARP_TO_ARENA); - event.setCancelled(true); - } - } - - private boolean isWarp(Location l) - { - return l.equals(arena.arenaLoc) || l.equals(arena.lobbyLoc) || l.equals(arena.spectatorLoc); - } - - /*public void onPlayerTeleport(PlayerTeleportEvent event) - { - if (!arena.running || arena.edit || !arena.enabled || !arena.setup || arena.allowWarp) - return; - - Location to = event.getTo(); - Location from = event.getFrom(); - - if (!arena.inRegion(to) && !arena.inRegion(from)) - return; - - Player p = event.getPlayer(); - Location old = arena.locations.get(p); - - if (arena.inArena(p) || arena.inLobby(p) || arena.specPlayers.contains(p)) - { - if (arena.inRegion(from)) - { - if (arena.inRegion(to) || to.equals(arena.arenaLoc) || to.equals(arena.lobbyLoc) || to.equals(arena.spectatorLoc) || to.equals(old)) - return; - - MAUtils.tellPlayer(p, Msg.WARP_FROM_ARENA); - event.setCancelled(true); - return; - } - - if (arena.inRegion(to)) - { - if (to.equals(arena.arenaLoc) || to.equals(arena.lobbyLoc) || to.equals(arena.spectatorLoc) || to.equals(old)) - return; - - MAUtils.tellPlayer(p, Msg.WARP_TO_ARENA); - event.setCancelled(true); - return; - } - - return; - } - - if (arena.running && arena.inRegion(to)) - { - event.setCancelled(true); - return; - } - }*/ - - public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) - { - Player p = event.getPlayer(); - - if (!arena.inArena(p) && !arena.inLobby(p)) - return; - - String[] args = event.getMessage().split(" "); - - if ((args.length > 1 && MACommands.COMMANDS.contains(args[1].trim())) || - MACommands.ALLOWED_COMMANDS.contains(event.getMessage().substring(1).trim()) || - MACommands.ALLOWED_COMMANDS.contains(args[0])) - return; - - event.setCancelled(true); - MAUtils.tellPlayer(p, Msg.MISC_COMMAND_NOT_ALLOWED); - } -} diff --git a/src/com/garbagemule/MobArena/MAMessages.java b/src/com/garbagemule/MobArena/MAMessages.java index f1883bb..0bbf4ca 100644 --- a/src/com/garbagemule/MobArena/MAMessages.java +++ b/src/com/garbagemule/MobArena/MAMessages.java @@ -7,104 +7,110 @@ import java.io.FileInputStream; import java.io.FileWriter; import java.io.InputStreamReader; +import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.Msg; + public class MAMessages { - public static void init(MobArenaPlugin plugin) { + public static void init(MobArena plugin) { // Grab the file - File msgFile = new File(MobArena.dir, "anouncements.properties"); - + File msgFile = new File(plugin.getDataFolder(), "announcements.properties"); + // If it couldn't be loaded for some reason - if (!load(msgFile)) + if (!load(plugin, msgFile)) return; - + // Otherwise, start parsing! - parseFile(msgFile); + parseFile(plugin, msgFile); } - - private static boolean load(File file) { + + private static boolean load(MobArena plugin, File file) { // If the file exists, continue on! if (file.exists()) { return true; } - + // Otherwise, create it, and populate it with the defaults. try { file.createNewFile(); BufferedWriter bw = new BufferedWriter(new FileWriter(file)); - + for (Msg m : Msg.values()) { if (m.hasSpoutMsg()) { bw.write(m.name() + "=" + m + "|" + m.toSpoutString()); - } else { + } + else { bw.write(m.name() + "=" + m); } bw.newLine(); } bw.close(); - + return true; } catch (Exception e) { - MobArena.warning("Couldn't initialize announcements-file. Using defaults."); + plugin.warning("Couldn't initialize announcements-file. Using defaults."); return false; } } - - private static void parseFile(File file) { + + private static void parseFile(MobArena plugin, File file) { try { - FileInputStream fis = new FileInputStream(file); + FileInputStream fis = new FileInputStream(file); InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); - BufferedReader br = new BufferedReader(isr); - + BufferedReader br = new BufferedReader(isr); + // Check for BOM character. br.mark(1); int bom = br.read(); if (bom != 65279) br.reset(); - + String s; while ((s = br.readLine()) != null) - process(s); - + process(plugin, s); + br.close(); } catch (Exception e) { e.printStackTrace(); - MobArena.warning("Problem with announcements-file. Using defaults."); + plugin.warning("Problem with announcements-file. Using defaults."); return; } } - + /** * Helper-method for parsing the strings from the * announcements-file. */ - private static void process(String s) { + private static void process(MobArena plugin, String s) { // If the line ends with = or |, just add a space - if (s.endsWith("=") || s.endsWith("|")) s += " "; - + if (s.endsWith("=") || s.endsWith("|")) { + s += " "; + } + // Split the string by the equals-sign. String[] split = s.split("="); if (split.length != 2) { - MobArena.warning("Couldn't parse \"" + s + "\". Check announcements-file."); + plugin.warning("Couldn't parse \"" + s + "\". Check announcements-file."); return; } - + // Split the value by the pipe-sign. String[] vals = split[1].split("\\|"); - + // For simplicity... String key = split[0]; String val = vals.length == 2 ? vals[0] : split[1]; String spoutVal = vals.length == 2 ? vals[1] : null; - + try { Msg msg = Msg.valueOf(key); msg.set(val); msg.setSpout(spoutVal); } catch (Exception e) { - MobArena.warning(key + " is not a valid key. Check announcements-file."); + plugin.warning(key + " is not a valid key. Check announcements-file."); return; } } diff --git a/src/com/garbagemule/MobArena/MAPlayerListener.java b/src/com/garbagemule/MobArena/MAPlayerListener.java deleted file mode 100644 index 478c8a1..0000000 --- a/src/com/garbagemule/MobArena/MAPlayerListener.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.garbagemule.MobArena; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.player.PlayerAnimationEvent; -import org.bukkit.event.player.PlayerBucketEmptyEvent; -import org.bukkit.event.player.PlayerCommandPreprocessEvent; -import org.bukkit.event.player.PlayerDropItemEvent; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerKickEvent; -import org.bukkit.event.player.PlayerListener; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.event.player.PlayerTeleportEvent; - - -public class MAPlayerListener extends PlayerListener -{ - private MobArena plugin; - private ArenaMaster am; - - public MAPlayerListener(MobArena plugin, ArenaMaster am) - { - this.plugin = plugin; - this.am = am; - } - - public void onPlayerAnimation(PlayerAnimationEvent event) - { - if (!am.enabled) return; - for (Arena arena : am.arenas) - arena.eventListener.onPlayerAnimation(event); - } - - public void onPlayerInteract(PlayerInteractEvent event) - { - if (!am.enabled) return; - for (Arena arena : am.arenas) - arena.eventListener.onPlayerInteract(event); - } - - public void onPlayerDropItem(PlayerDropItemEvent event) - { - if (!am.enabled) return; - for (Arena arena : am.arenas) - arena.eventListener.onPlayerDropItem(event); - } - - public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event) - { - if (!am.enabled) return; - for (Arena arena : am.arenas) - arena.eventListener.onPlayerBucketEmpty(event); - } - - public void onPlayerTeleport(PlayerTeleportEvent event) - { - if (!am.enabled) return; - for (Arena arena : am.arenas) - arena.eventListener.onPlayerTeleport(event); - } - - public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) - { - if (!am.enabled) return; - for (Arena arena : am.arenas) - arena.eventListener.onPlayerCommandPreprocess(event); - } - - public void onPlayerQuit(PlayerQuitEvent event) - { - for (Arena arena : am.arenas) - arena.eventListener.onPlayerQuit(event); - } - - public void onPlayerKick(PlayerKickEvent event) - { - for (Arena arena : am.arenas) - arena.eventListener.onPlayerKick(event); - } - - public void onPlayerJoin(PlayerJoinEvent event) - { - if (!am.updateNotify || !event.getPlayer().isOp()) return; - - final Player p = event.getPlayer(); - Bukkit.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, - new Runnable() - { - public void run() - { - MAUtils.checkForUpdates(plugin, p, false); - } - }, 60); - } -} diff --git a/src/com/garbagemule/MobArena/MASpawnThread.java b/src/com/garbagemule/MobArena/MASpawnThread.java index 98cb3bb..77bc7d9 100644 --- a/src/com/garbagemule/MobArena/MASpawnThread.java +++ b/src/com/garbagemule/MobArena/MASpawnThread.java @@ -1,283 +1,341 @@ package com.garbagemule.MobArena; -import java.util.HashSet; -import java.util.LinkedList; +import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; import org.bukkit.Location; -import org.bukkit.entity.Creeper; +import org.bukkit.World; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.entity.Creature; import org.bukkit.entity.Entity; import org.bukkit.inventory.ItemStack; -import com.garbagemule.MobArena.util.WaveUtils; -import com.garbagemule.MobArena.waves.Wave; +import com.garbagemule.MobArena.ArenaPlayer; +import com.garbagemule.MobArena.MAUtils; +import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.Msg; +import com.garbagemule.MobArena.events.NewWaveEvent; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.region.ArenaRegion; +import com.garbagemule.MobArena.waves.*; +import com.garbagemule.MobArena.waves.enums.WaveType; +import com.garbagemule.MobArena.waves.types.BossWave; +import com.garbagemule.MobArena.waves.types.SupplyWave; +import com.garbagemule.MobArena.waves.types.UpgradeWave; -/** - * Core class for handling wave spawning. - * Currently, every 4th wave is a special wave, and all other waves - * are default waves. The distribution coefficients are used to spread - * out the distribution of each default monster however the server - * host chooses. It is possible to create default waves that consist of - * only one type of monster, or ones that have no creepers, for example. - */ public class MASpawnThread implements Runnable { private MobArena plugin; private Arena arena; - private int wave, taskId, previousSize, playerCount; - - // NEW WAVES - private Wave defaultWave; - private TreeSet recurrentWaves; - private TreeSet singleWaves; - - public MASpawnThread(MobArena plugin, Arena arena) - { - // WAVES - defaultWave = arena.recurrentWaves.first(); - recurrentWaves = arena.recurrentWaves; - singleWaves = new TreeSet(arena.singleWaves); - - this.plugin = plugin; - this.arena = arena; - wave = 1; - playerCount = arena.arenaPlayers.size(); - } - - public void run() - { - // Clear out all dead monsters in the monster set. - removeDeadMonsters(); - - // If there are no players in the arena, return. - if (arena.arenaPlayers.isEmpty()) - return; + private ArenaRegion region; + private RewardManager rewardManager; + private WaveManager waveManager; + private MonsterManager monsterManager; - // Check if wave needs to be cleared first. If so, return! - if (arena.waveClear && wave > 1 && !arena.monsters.isEmpty()) - return; - - // Check if we're on a boss wave - if (!arena.waveClear && arena.bossWave != null) - return; - - // Grant rewards (if any) for this wave - grantRewards(wave); - - // Detonate creepers if needed - detonateCreepers(arena.detCreepers); - - // Check if this is the final wave, in which case, end instead of spawn - if (wave > 1 && wave == arena.finalWave) - { - for (Player p : arena.arenaPlayers) - arena.playerDeath(p); + private int playerCount, monsterLimit; + private boolean waveClear, bossClear; + + /** + * Create a new monster spawner for the input arena. + * Note that the arena's WaveManager is reset + * @param plugin a MobArena instance + * @param arena an arena + */ + public MASpawnThread(MobArena plugin, Arena arena) { + this.plugin = plugin; + this.arena = arena; + this.region = arena.getRegion(); + this.rewardManager = arena.getRewardManager(); + this.waveManager = arena.getWaveManager(); + this.monsterManager = arena.getMonsterManager(); + + reset(); + } + + /** + * Reset the spawner, so all systems and settings are + * ready for a new session. + */ + public void reset() { + waveManager.reset(); + playerCount = arena.getPlayersInArena().size(); + monsterLimit = arena.getSettings().getInt("monster-limit", 100); + waveClear = arena.getSettings().getBoolean("clear-wave-before-next", false); + bossClear = arena.getSettings().getBoolean("clear-boss-before-next", false); + } + + public void run() { + // If the arena isn't running or if there are no players in it. + if (!arena.isRunning() || arena.getPlayersInArena().isEmpty()) { return; } - - // Find the wave to spawn - spawnWave(wave); - + + // Clear out all dead monsters in the monster set. + removeDeadMonsters(); + removeCheatingPlayers(); + + // In case some players were removed, check again. + if (!arena.isRunning()) { + return; + } + + // Grab the wave number. + int nextWave = waveManager.getWaveNumber() + 1; + + // Check if wave needs to be cleared first. If so, return! + if (!isWaveClear()) { + arena.scheduleTask(this, 60); + return; + } + + // Fire off the event. If cancelled, try again in 3 seconds. + NewWaveEvent event = new NewWaveEvent(arena, waveManager.getNext(), nextWave); + plugin.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) { + arena.scheduleTask(this, 60); + return; + } + + // Grant rewards (if any) for the wave about to spawn + grantRewards(nextWave); + + // Check if this is the final wave, in which case, end instead of spawn + if (nextWave > 1 && (nextWave - 1) == waveManager.getFinalWave()) { + List players = new ArrayList(arena.getPlayersInArena()); + for (Player p : players) { + arena.playerLeave(p); + } + + return; + } + + // Spawn the next wave. + spawnWave(nextWave); + // Update stats - updateStats(wave); - - wave++; - if (arena.monsters.isEmpty()) - arena.resetIdleTimer(); + updateStats(nextWave); + + // Reschedule the spawner for the next wave. + arena.scheduleTask(this, arena.getSettings().getInt("wave-interval", 3) * 20); } - - private void removeDeadMonsters() - { - List tmp = new LinkedList(arena.monsters); - for (Entity e : tmp) - { - if (e == null) continue; - - if (e.isDead() || !arena.inRegion(e.getLocation())) - { - arena.monsters.remove(e); + + private void spawnWave(int wave) { + Wave w = waveManager.next(); + + w.announce(arena, wave); + + if (w.getType() == WaveType.UPGRADE) { + handleUpgradeWave(w); + return; + } + + Map monsters = w.getMonstersToSpawn(wave, playerCount, arena); + List spawnpoints = w.getSpawnpoints(arena); + + World world = arena.getWorld(); + int totalSpawnpoints = spawnpoints.size(); + int index = 0; + double mul = w.getHealthMultiplier(); + + for (Map.Entry entry : monsters.entrySet()) { + for (int i = 0; i < entry.getValue(); i++, index++) { + // Check if monster limit has been reached. + if (monsterManager.getMonsters().size() >= monsterLimit) { + return; + } + + // Grab a spawnpoint + Location spawnpoint = spawnpoints.get(index % totalSpawnpoints); + + // Spawn the monster + LivingEntity e = entry.getKey().spawn(arena, world, spawnpoint); + + // Add it to the arena. + monsterManager.addMonster(e); + + // Set the health. + int health = (int) Math.max(1D, e.getMaxHealth() * mul); + e.setHealth(Math.min(health, e.getMaxHealth())); + + // Switch on the type. + switch (w.getType()){ + case BOSS: + BossWave bw = (BossWave) w; + int maxHealth = bw.getMaxHealth(playerCount); + MABoss boss = monsterManager.addBoss(e, maxHealth); + bw.addMABoss(boss); + bw.activateAbilities(arena); + break; + case SWARM: + health = (int) (mul < 1D ? e.getMaxHealth() * mul : 1); + health = Math.max(1, health); + e.setHealth(Math.min(health, e.getMaxHealth())); + break; + case SUPPLY: + SupplyWave sw = (SupplyWave) w; + monsterManager.addSupplier(e, sw.getDropList()); + break; + default: + break; + } + } + } + } + + private void handleUpgradeWave(Wave w) { + UpgradeWave uw = (UpgradeWave) w; + + for (Player p : arena.getPlayersInArena()) { + String className = arena.getArenaPlayer(p).getArenaClass().getName(); + //String className = arena.getClassOfPlayer(p); + uw.grantItems(p, className); + uw.grantItems(p, "All"); + } + } + + /** + * Check if the wave is clear for new spawns. + * If clear-boss-before-next: true, bosses must be dead. + * If clear-wave-before-next: true, all monsters must be dead. + * @param wave the next wave number + * @return true, if the wave is "clear" for new spawns. + */ + private boolean isWaveClear() { + // Check for monster limit + if (monsterManager.getMonsters().size() >= monsterLimit) { + return false; + } + + // Check for boss clear + if (bossClear && !monsterManager.getBossMonsters().isEmpty()) { + return false; + } + + // Check for wave clear + if (waveClear && !monsterManager.getMonsters().isEmpty()) { + return false; + } + + // Check for final wave + if (!monsterManager.getMonsters().isEmpty() && waveManager.getWaveNumber() == waveManager.getFinalWave()) { + return false; + } + + return true; + } + + private void removeDeadMonsters() { + List tmp = new ArrayList(monsterManager.getMonsters()); + for (Entity e : tmp) { + if (e == null) { + continue; + } + + if (e.isDead() || !region.contains(e.getLocation())) { + monsterManager.removeMonster(e); e.remove(); } } } - - private void grantRewards(int wave) - { - for (Map.Entry> entry : arena.everyWaveMap.entrySet()) - if (wave % entry.getKey() == 0) + + private void removeCheatingPlayers() { + List players = new ArrayList(arena.getPlayersInArena()); + for (Player p : players) { + if (region.contains(p.getLocation())) { + continue; + } + + Messenger.tellPlayer(p, "Leaving so soon?"); + p.getInventory().clear(); + arena.playerLeave(p); + } + } + + private void grantRewards(int wave) { + for (Map.Entry> entry : arena.getEveryWaveEntrySet()) { + if (wave % entry.getKey() == 0) { addReward(entry.getValue()); - - if (arena.afterWaveMap.containsKey(wave)) - addReward(arena.afterWaveMap.get(wave)); - } - - private void spawnWave(int wave) - { - Wave w = null; - - // Check the first element of the single waves. - if (!singleWaves.isEmpty() && singleWaves.first().matches(wave)) - { - w = singleWaves.pollFirst(); + } } - else - { - SortedSet matches = getMatchingRecurrentWaves(wave); - w = matches.isEmpty() ? defaultWave : matches.last(); - } - - // Notify listeners. - for (MobArenaListener listener : plugin.getAM().listeners) - listener.onWave(arena, wave, w.getName(), w.getBranch(), w.getType()); - arena.setWave(w); - w.spawn(wave); - } - - private void updateStats(int wave) - { - for (ArenaPlayer ap: arena.getArenaPlayerSet()) - if (arena.getArenaPlayers().contains(ap.getPlayer())) - ap.getStats().lastWave++; - } - - private SortedSet getMatchingRecurrentWaves(int wave) - { - TreeSet result = new TreeSet(WaveUtils.getRecurrentComparator()); - - for (Wave w : recurrentWaves) - { - if (w.matches(wave)) - result.add(w); + List after = arena.getAfterWaveReward(wave); + if (after != null) { + addReward(after); } - - return result; } - - - /*//////////////////////////////////////////////////////////////////// - // - // Getters/setters - // - ////////////////////////////////////////////////////////////////////*/ - - public int getWave() - { - return wave; + private void updateStats(int wave) { + for (ArenaPlayer ap : arena.getArenaPlayerSet()) { + if (arena.getPlayersInArena().contains(ap.getPlayer())) { + ap.getStats().inc("lastWave"); + } + } } - - public int getTaskId() - { - return taskId; - } - - public int getPreviousSize() - { - return previousSize; - } - - public int getPlayerCount() - { + + /* + * //////////////////////////////////////////////////////////////////// + * // + * // Getters/setters + * // + * //////////////////////////////////////////////////////////////////// + */ + + public int getPlayerCount() { return playerCount; } - - public void setTaskId(int taskId) - { - this.taskId = taskId; - } - - public void setPreviousSize(int previousSize) - { - this.previousSize = previousSize; - } - + /** * Rewards all players with an item from the input String. */ - private void addReward(List rewards) - { - for (Player p : arena.arenaPlayers) - { - if (arena.log.players.get(p) == null) - continue; - + private void addReward(List rewards) { + for (Player p : arena.getPlayersInArena()) { ItemStack reward = MAUtils.getRandomReward(rewards); - arena.log.players.get(p).rewards.add(reward); - - if (reward == null) - { - MAUtils.tellPlayer(p, "ERROR! Problem with economy rewards. Notify server host!"); - MobArena.warning("Could not add null reward. Please check the config-file!"); - } - else if (reward.getTypeId() == MobArena.ECONOMY_MONEY_ID) - { - if (plugin.Method != null) - MAUtils.tellPlayer(p, Msg.WAVE_REWARD, plugin.Method.format(reward.getAmount())); - else MobArena.warning("Tried to add money, but no economy plugin detected!"); - } - else - { - MAUtils.tellPlayer(p, Msg.WAVE_REWARD, MAUtils.toCamelCase(reward.getType().toString()) + ":" + reward.getAmount(), reward.getType()); - } - } - } - - /** - * "Detonates" all the Creepers in the monsterSet. - */ - public void detonateCreepers(boolean really) - { - if (!really) - return; - - Set tmp = new HashSet(); - for (Entity e : arena.monsters) - { - if (!(e instanceof Creeper) || e.isDead()) - continue; - - tmp.add(e); - } + rewardManager.addReward(p, reward); - Location loc; - for (Entity e : tmp) - { - if (e == null) continue; - - arena.monsters.remove(e); - loc = e.getLocation().getBlock().getRelative(0,2,0).getLocation(); - arena.world.createExplosion(loc, 2); - e.remove(); + if (reward == null) { + Messenger.tellPlayer(p, "ERROR! Problem with rewards. Notify server host!"); + plugin.warning("Could not add null reward. Please check the config-file!"); + } + else if (reward.getTypeId() == MobArena.ECONOMY_MONEY_ID) { + if (plugin.giveMoney(p, reward.getAmount())) { + Messenger.tellPlayer(p, Msg.WAVE_REWARD, plugin.economyFormat(reward.getAmount())); + } + else { + plugin.warning("Tried to add money, but no economy plugin detected!"); + } + } + else { + Messenger.tellPlayer(p, Msg.WAVE_REWARD, MAUtils.toCamelCase(reward.getType().toString()) + ":" + reward.getAmount(), reward.getType()); + } } } - + /** * Update the targets of all monsters, if their targets aren't alive. */ - public void updateTargets() - { + public void updateTargets() { Creature c; Entity target; - for (Entity e : arena.monsters) - { + for (Entity e : monsterManager.getMonsters()) { if (!(e instanceof Creature)) - continue; + continue; // TODO: Remove the try-catch when Bukkit API is fixed. c = (Creature) e; - try { target = c.getTarget(); } catch (ClassCastException cce) { continue; } - - if (target instanceof Player && arena.inArena((Player) target)) + try { + target = c.getTarget(); + } + catch (ClassCastException cce) { continue; - - c.setTarget(MAUtils.getClosestPlayer(e, arena)); + } + + if (target instanceof Player && arena.getPlayersInArena().contains((Player) target)) { + continue; + } + + c.setTarget(MAUtils.getClosestPlayer(plugin, e, arena)); } } } \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/MAUtils.java b/src/com/garbagemule/MobArena/MAUtils.java index 30a7ec1..adaba4d 100644 --- a/src/com/garbagemule/MobArena/MAUtils.java +++ b/src/com/garbagemule/MobArena/MAUtils.java @@ -1,14 +1,11 @@ package com.garbagemule.MobArena; -import java.lang.reflect.Field; -import java.net.URI; -import java.net.HttpURLConnection; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import java.util.HashSet; +import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.LinkedList; @@ -16,15 +13,8 @@ import java.util.Map; import java.util.HashMap; import java.util.Random; import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import org.bukkit.block.Sign; -import org.bukkit.command.CommandSender; -import org.bukkit.craftbukkit.CraftWorld; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.DyeColor; import org.bukkit.World; import org.bukkit.Material; import org.bukkit.Location; @@ -32,101 +22,22 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.entity.Wolf; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.PlayerInventory; -//import org.bukkit.util.config.Configuration; -import org.getspout.spoutapi.SpoutManager; -import org.getspout.spoutapi.player.SpoutPlayer; +import org.bukkit.plugin.java.JavaPlugin; -import com.garbagemule.MobArena.util.Config; +import com.garbagemule.MobArena.MAUtils; +import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.Msg; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; +import com.garbagemule.MobArena.region.ArenaRegion; import com.garbagemule.MobArena.util.EntityPosition; -import com.garbagemule.MobArena.util.InventoryItem; +import com.garbagemule.MobArena.util.ItemParser; +import com.garbagemule.MobArena.util.config.Config; +import com.garbagemule.MobArena.util.config.ConfigUtils; public class MAUtils { public static final String sep = File.separator; - // Weapons - public static final List WEAPONS_TYPE = new LinkedList(); - public static final List SWORDS_TYPE = new LinkedList(); - public static final List AXES_TYPE = new LinkedList(); - public static final List PICKAXES_TYPE = new LinkedList(); - public static final List SPADES_TYPE = new LinkedList(); - public static final List HOES_TYPE = new LinkedList(); - // Armor - public static final List ARMORS_TYPE = new LinkedList(); - public static final List HELMETS_TYPE = new LinkedList(); - public static final List CHESTPLATES_TYPE = new LinkedList(); - public static final List LEGGINGS_TYPE = new LinkedList(); - public static final List BOOTS_TYPE = new LinkedList(); - static - { - // Weapons - SWORDS_TYPE.add(Material.WOOD_SWORD); - SWORDS_TYPE.add(Material.STONE_SWORD); - SWORDS_TYPE.add(Material.GOLD_SWORD); - SWORDS_TYPE.add(Material.IRON_SWORD); - SWORDS_TYPE.add(Material.DIAMOND_SWORD); - - AXES_TYPE.add(Material.WOOD_AXE); - AXES_TYPE.add(Material.STONE_AXE); - AXES_TYPE.add(Material.GOLD_AXE); - AXES_TYPE.add(Material.IRON_AXE); - AXES_TYPE.add(Material.DIAMOND_AXE); - - PICKAXES_TYPE.add(Material.WOOD_PICKAXE); - PICKAXES_TYPE.add(Material.STONE_PICKAXE); - PICKAXES_TYPE.add(Material.GOLD_PICKAXE); - PICKAXES_TYPE.add(Material.IRON_PICKAXE); - PICKAXES_TYPE.add(Material.DIAMOND_PICKAXE); - - SPADES_TYPE.add(Material.WOOD_SPADE); - SPADES_TYPE.add(Material.STONE_SPADE); - SPADES_TYPE.add(Material.GOLD_SPADE); - SPADES_TYPE.add(Material.IRON_SPADE); - SPADES_TYPE.add(Material.DIAMOND_SPADE); - - HOES_TYPE.add(Material.WOOD_HOE); - HOES_TYPE.add(Material.STONE_HOE); - HOES_TYPE.add(Material.GOLD_HOE); - HOES_TYPE.add(Material.IRON_HOE); - HOES_TYPE.add(Material.DIAMOND_HOE); - - WEAPONS_TYPE.addAll(SWORDS_TYPE); - WEAPONS_TYPE.addAll(AXES_TYPE); - WEAPONS_TYPE.addAll(PICKAXES_TYPE); - WEAPONS_TYPE.addAll(SPADES_TYPE); - WEAPONS_TYPE.addAll(HOES_TYPE); - - // Armor - HELMETS_TYPE.add(Material.LEATHER_HELMET); - HELMETS_TYPE.add(Material.GOLD_HELMET); - HELMETS_TYPE.add(Material.CHAINMAIL_HELMET); - HELMETS_TYPE.add(Material.IRON_HELMET); - HELMETS_TYPE.add(Material.DIAMOND_HELMET); - HELMETS_TYPE.add(Material.PUMPKIN); - - CHESTPLATES_TYPE.add(Material.LEATHER_CHESTPLATE); - CHESTPLATES_TYPE.add(Material.GOLD_CHESTPLATE); - CHESTPLATES_TYPE.add(Material.CHAINMAIL_CHESTPLATE); - CHESTPLATES_TYPE.add(Material.IRON_CHESTPLATE); - CHESTPLATES_TYPE.add(Material.DIAMOND_CHESTPLATE); - - LEGGINGS_TYPE.add(Material.LEATHER_LEGGINGS); - LEGGINGS_TYPE.add(Material.GOLD_LEGGINGS); - LEGGINGS_TYPE.add(Material.CHAINMAIL_LEGGINGS); - LEGGINGS_TYPE.add(Material.IRON_LEGGINGS); - LEGGINGS_TYPE.add(Material.DIAMOND_LEGGINGS); - - BOOTS_TYPE.add(Material.LEATHER_BOOTS); - BOOTS_TYPE.add(Material.GOLD_BOOTS); - BOOTS_TYPE.add(Material.CHAINMAIL_BOOTS); - BOOTS_TYPE.add(Material.IRON_BOOTS); - BOOTS_TYPE.add(Material.DIAMOND_BOOTS); - - ARMORS_TYPE.addAll(HELMETS_TYPE); - ARMORS_TYPE.addAll(CHESTPLATES_TYPE); - ARMORS_TYPE.addAll(LEGGINGS_TYPE); - ARMORS_TYPE.addAll(BOOTS_TYPE); - } @@ -136,168 +47,35 @@ public class MAUtils // ///////////////////////////////////////////////////////////////////// */ - public static Map getArenaContainers(Config config, World world, String arena) - { - Map containers = new HashMap(); - String arenaPath = "arenas." + arena + ".coords.containers"; - - if (config.getKeys(arenaPath) == null) - return containers; - - for (String point : config.getKeys(arenaPath)) - containers.put(point, makeLocation(world, config.getString(arenaPath + "." + point))); - - return containers; - } - - /** - * Grab all the spawnpoints for a specific arena. - */ - public static Map getArenaSpawnpoints(Config config, World world, String arena) - { - Map spawnpoints = new HashMap(); - String arenaPath = "arenas." + arena + ".coords.spawnpoints"; - - if (config.getKeys(arenaPath) == null) - return spawnpoints; - - for (String point : config.getKeys(arenaPath)) - if (!point.matches("^(.)*boss(.)*$")) - spawnpoints.put(point, makeLocation(world, config.getString(arenaPath + "." + point))); - - return spawnpoints; - } - - public static Map getArenaBossSpawnpoints(Config config, World world, String arena) - { - Map spawnpoints = new HashMap(); - String arenaPath = "arenas." + arena + ".coords.spawnpoints"; - - if (config.getKeys(arenaPath) == null) - return spawnpoints; - - for (String point : config.getKeys(arenaPath)) - if (point.matches("^(.)*boss(.)*$")) - spawnpoints.put(point, makeLocation(world, config.getString(arenaPath + "." + point))); - - return spawnpoints; - } - - /** - * Returns a map of classnames mapped to lists of ItemStacks. - */ - public static Map> getClassItems(Config config, String type) - { - Map> result = new HashMap>(); - - for (String className : config.getKeys("classes")) - result.put(className, makeItemStackList(config.getString("classes." + className + "." + type))); - - return result; - } - - public static Map> getClassPerms(Config config) - { - Map> result = new HashMap>(); - - Set classes = config.getKeys("classes"); - if (classes == null) return result; - - for (String c : classes) - { - // Get all the permissions for the class and return if empty. - List keys = config.getStringList("classes." + c + ".permissions", new LinkedList()); - if (keys.isEmpty()) continue; - - // If the string starts with a hyphen (-), use false. - Map perms = new HashMap(); - for (String p : keys) - { - boolean b = !p.startsWith("-"); - String s = b ? p : p.substring(1); - perms.put(s,b); - } - - result.put(c,perms); - } - - return result; - } - - public static List getEntryFee(Config config, String arena) - { - return makeItemStackList(config.getString("arenas." + arena + ".settings.entry-fee", null)); - } - - /** - * Takes a comma-separated list of items in the : format and - * returns a list of ItemStacks created from that data. - */ - public static List makeItemStackList(String string) - { - List result = new LinkedList(); - if (string == null || string.isEmpty()) return result; - - // Trim commas and whitespace, and split items by commas - string = string.trim(); - if (string.endsWith(",")) - string = string.substring(0, string.length()-1); - String[] items = string.split(","); - - for (String item : items) - { - // Trim whitespace and split by colons. - item = item.trim(); - String[] parts = item.split(":"); - - // Grab the amount. - int amount = 1; - if (parts.length == 1 && parts[0].matches("\\$[0-9]+")) - amount = Integer.parseInt(parts[0].substring(1, parts[0].length())); - else if (parts.length == 2 && parts[1].matches("(-)?[0-9]+")) - amount = Integer.parseInt(parts[1]); - else if (parts.length == 3 && parts[2].matches("(-)?[0-9]+")) - amount = Integer.parseInt(parts[2]); - - - // Make the ItemStack. - ItemStack stack = (parts.length == 3) ? - makeItemStack(parts[0], amount, parts[1]) : - makeItemStack(parts[0], amount); - - if (stack != null) - result.add(stack); - } - return result; - } - /** * Generates a map of wave numbers and rewards based on the * type of wave ("after" or "every") and the config-file. If * no keys exist in the config-file, an empty map is returned. */ - public static Map> getArenaRewardMap(Config config, String arena, String type) + public static Map> getArenaRewardMap(MobArena plugin, Config config, String arena, String type) { - String arenaPath = "arenas." + arena + ".rewards.waves."; + //String arenaPath = "arenas." + arena + ".rewards.waves."; + String typePath = ConfigUtils.waveRewardList(arena, type); Map> result = new HashMap>(); - if (config.getKeys(arenaPath + type) == null) + if (config.getKeys(typePath) == null) { if (type.equals("every")) { - config.setProperty(arenaPath + "every.3", "feather, bone, stick"); - config.setProperty(arenaPath + "every.5", "dirt:4, gravel:4, stone:4"); - config.setProperty(arenaPath + "every.10", "iron_ingot:10, gold_ingot:8"); + config.set(typePath + ".3", "feather, bone, stick"); + config.set(typePath + ".5", "dirt:4, gravel:4, stone:4"); + config.set(typePath + ".10", "iron_ingot:10, gold_ingot:8"); } else if (type.equals("after")) { - config.setProperty(arenaPath + "after.7", "minecart, storage_minecart, powered_minecart"); - config.setProperty(arenaPath + "after.13", "iron_sword, iron_pickaxe, iron_spade"); - config.setProperty(arenaPath + "after.16", "diamond_sword"); + config.set(typePath + ".7", "minecart, storage_minecart, powered_minecart"); + config.set(typePath + ".13", "iron_sword, iron_pickaxe, iron_spade"); + config.set(typePath + ".16", "diamond_sword"); } } - Set waves = config.getKeys(arenaPath + type); + //Set waves = config.getKeys(arenaPath + type); + Set waves = config.getKeys(typePath); if (waves == null) return result; for (String n : waves) @@ -306,25 +84,13 @@ public class MAUtils continue; int wave = Integer.parseInt(n); - String rewards = config.getString(arenaPath + type + "." + n); + String path = ConfigUtils.waveReward(arena, type, wave); + String rewards = config.getString(path); - result.put(wave, makeItemStackList(rewards)); + result.put(wave, ItemParser.parseItems(rewards)); } return result; } - - public static List getAllowedCommands(Config config) - { - String commands = config.getString("global-settings.allowed-commands"); - if (commands == null) - { - config.setProperty("global-settings.allowed-commands", "/list, /pl"); - config.save(); - commands = config.getString("global-settings.allowed-commands"); - } - - return stringToList(commands); - } @@ -334,293 +100,6 @@ public class MAUtils // ///////////////////////////////////////////////////////////////////// */ - public static PlayerInventory clearInventory(Player p) - { - PlayerInventory inv = p.getInventory(); - inv.clear(); - inv.setHelmet(null); - inv.setChestplate(null); - inv.setLeggings(null); - inv.setBoots(null); - return inv; - } - - public static boolean storeInventory(Player p) - { - // Set up the files and paths - String invPath = "plugins" + sep + "MobArena" + sep + "inventories"; - new File(invPath).mkdir(); - File backupFile = new File(invPath + sep + p.getName() + ".inv"); - - // If a backup file already exists, restore the inventory first - if (backupFile.exists() && !restoreInventory(p)) - return false; - - // Grab the inventory contents. - ItemStack[] items = p.getInventory().getContents(); - ItemStack[] armor = p.getInventory().getArmorContents(); - - try - { - backupFile.createNewFile(); - - InventoryItem[] inv = new InventoryItem[items.length + armor.length]; - for (int i = 0; i < items.length; i++) - inv[i] = InventoryItem.parseItemStack(items[i]); - for (int i = 0; i < armor.length; i++) - inv[i + items.length] = InventoryItem.parseItemStack(armor[i]); - - FileOutputStream fos = new FileOutputStream(backupFile); - ObjectOutputStream oos = new ObjectOutputStream(fos); - oos.writeObject(inv); - oos.close(); - } - catch (Exception e) - { - e.printStackTrace(); - MobArena.warning("Could not create backup file for " + p.getName() + "."); - return false; - } - - clearInventory(p); - return true; - } - - public static boolean restoreInventory(Player p) - { - // Grab the items from the MobArena .inv file - ItemStack[] stacks = getInventoryFile(p); - if (stacks == null) - { - MobArena.warning("Couldn't restore player inventory for '" + p.getName() + "'"); - return false; - } - - // If the player isn't online, hack the playerName.dat file - if (!p.isOnline()) - System.out.println("THE WORLD IS GOING TO END! SOMETHING IS WRONG!");//return writeInventoryData(p, stacks); - - // Otherwise, restore the inventory directly - ItemStack[] items = new ItemStack[stacks.length-4]; - ItemStack[] armor = new ItemStack[4]; - - for (int i = 0; i < stacks.length - 4; i++) - items[i] = stacks[i]; - for (int i = 0; i < 4; i++) - armor[i] = stacks[stacks.length - 4 + i]; - - // Restore the inventory. - PlayerInventory inv = p.getInventory(); - inv.setArmorContents(armor); - for (int i = 0; i < items.length; i++) - inv.setItem(i, items[i]); - - return true; - } - - public static ItemStack[] getInventoryFile(Player p) - { - String invPath = "plugins" + sep + "MobArena" + sep + "inventories"; - File backupFile = new File(invPath + sep + p.getName() + ".inv"); - - try - { - // If the backup-file couldn't be found, return. - if (!backupFile.exists()) - return null; - - // Grab the MAInventoryItem array from the backup-file. - FileInputStream fis = new FileInputStream(backupFile); - ObjectInputStream ois = new ObjectInputStream(fis); - InventoryItem[] fromFile = (InventoryItem[]) ois.readObject(); - ois.close(); - - // Delete the file - backupFile.delete(); - - return InventoryItem.toItemStacks(fromFile); - } - catch (Exception e) - { - e.printStackTrace(); - MobArena.warning("Could not get inventory file for '" + p.getName() + "'"); - return null; - } - } - - /* Checks if all inventory and armor slots are empty. */ - public static boolean hasEmptyInventory(Player p) - { - ItemStack[] inventory = p.getInventory().getContents(); - ItemStack[] armor = p.getInventory().getArmorContents(); - - // For inventory, check for null - for (ItemStack stack : inventory) - if (stack != null) return false; - - // For armor, check for id 0, or AIR - for (ItemStack stack : armor) - if (stack.getTypeId() != 0) return false; - - return true; - } - - /** - * Gives the player all of the items in the list of ItemStacks. - */ - public static void giveItems(Player p, List stacks, boolean autoEquip, boolean rewards, MobArena plugin) - { - if (stacks == null) - return; - - // Give the player some items! - PlayerInventory inv = p.getInventory(); - for (ItemStack stack : stacks) - { - if (stack == null) - continue; - - // If this is money, don't add to inventory. - if (stack.getTypeId() == MobArena.ECONOMY_MONEY_ID) - { - if (plugin != null && plugin.Method != null) - plugin.Method.getAccount(p.getName()).add(stack.getAmount()); - - continue; - } - - // If these are rewards, don't tamper with them. - if (rewards) - { - giveItem(inv, stack); - continue; - } - - // If this is an armor piece, equip it. - if (autoEquip && ARMORS_TYPE.contains(stack.getType())) - { - equipArmorPiece(stack, inv); - continue; - } - - // If this is a weapon, set its durability to "unlimited". - if (WEAPONS_TYPE.contains(stack.getType())) - stack.setDurability(Short.MIN_VALUE); - - giveItem(inv, stack); - } - } - - public static void giveItems(Player p, List stacks, boolean autoEquip, MobArena plugin) - { - giveItems(p, stacks, autoEquip, false, plugin); - } - - public static void giveItem(PlayerInventory inv, ItemStack stack) - { - // If the stack isn't too big, just add it - if (stack.getAmount() <= 64) - { - inv.addItem(stack); - return; - } - - // Otherwise, grab the id, durability and data. - int id = stack.getTypeId(); - int amount = stack.getAmount(); - short durability = stack.getDurability(); - Byte data = stack.getData() != null ? stack.getData().getData() : null; - - // Initialize the quotient and remainder. - int quotient = amount / 64; - int remainder = amount % 64; - - // Add a bunch of stacks of amount 64. - for (int i = 0; i < quotient; i++) - inv.addItem(new ItemStack(id, 64, durability, data)); - - // Add the rest. - if (remainder > 0) - inv.addItem(new ItemStack(id, remainder, durability, data)); - } - - public static void giveRewards(Player p, List stacks, MobArena plugin) - { - giveItems(p, stacks, false, true, plugin); - } - - public static int getPetAmount(Player p) - { - int result = 0; - - for (ItemStack stack : p.getInventory().getContents()) - { - if (stack == null || stack.getTypeId() != 352) - continue; - - result += stack.getAmount(); - } - - return result; - } - - /* Helper method for equipping armor pieces. */ - public static void equipArmorPiece(ItemStack stack, PlayerInventory inv) - { - Material type = stack.getType(); - - if (HELMETS_TYPE.contains(type)) - inv.setHelmet(stack); - else if (CHESTPLATES_TYPE.contains(type)) - inv.setChestplate(stack); - else if (LEGGINGS_TYPE.contains(type)) - inv.setLeggings(stack); - else if (BOOTS_TYPE.contains(type)) - inv.setBoots(stack); - } - - /* Helper methods for making ItemStacks out of strings and ints */ - public static ItemStack makeItemStack(String name, int amount, String data) - { - // If this is economy money, create a dummy ItemStack. - if (name.matches("\\$[0-9]+")) - return new ItemStack(MobArena.ECONOMY_MONEY_ID, amount); - - try - { - byte offset = 0; - - Material material = (name.matches("[0-9]+")) ? - Material.getMaterial(Integer.parseInt(name)) : - Material.valueOf(name.toUpperCase()); - - if (material == Material.INK_SACK) - offset = 15; - - if (material == Material.INK_SACK || material == Material.WOOL) - { - DyeColor dye = (data.matches("[0-9]+")) ? - DyeColor.getByData((byte) Math.abs(offset - Integer.parseInt(data))) : - DyeColor.valueOf(data.toUpperCase()); - - return new ItemStack(material, amount, (short) Math.abs(offset - dye.getData())); - } - else - { - return new ItemStack(material, amount, (short) Integer.parseInt(data)); - } - } - catch (Exception e) - { - MobArena.warning("Could not create item \"" + name + "\". Check config.yml"); - return null; - } - } - public static ItemStack makeItemStack(String name, int amount) - { - return makeItemStack(name, amount, "0"); - } - /* Helper method for grabbing a random reward */ public static ItemStack getRandomReward(List rewards) { @@ -661,420 +140,14 @@ public class MAUtils - /* ///////////////////////////////////////////////////////////////////// // - - REGION METHODS - - // ///////////////////////////////////////////////////////////////////// */ - - /** - * Check if a Location is inside two points (x1,y1,z1) (x2,y2,z2) - */ - public static boolean inRegion(Location loc, double x1, double y1, double z1, double x2, double y2, double z2) - { - double x = loc.getBlockX(); - double y = loc.getBlockY(); - double z = loc.getBlockZ(); - - return x >= x1 && x <= x2 && - y >= y1 && y <= y2 && - z >= z1 && z <= z2; - } - - /** - * Create a frame spanned by the two input coordinates. - * @return An int arry holding x,y,z and the original type IDs of each block. - */ - public static Set showRegion(Player p, World world, Location p1, Location p2, int id, byte color) - { - Set result = new HashSet(); - - int x1 = p1.getBlockX(); int y1 = p1.getBlockY(); int z1 = p1.getBlockZ(); - int x2 = p2.getBlockX(); int y2 = p2.getBlockY(); int z2 = p2.getBlockZ(); - - int[] buffer; - - for (int i = x1; i <= x2; i++) - { - buffer = new int[] {i, y1, z1, world.getBlockTypeIdAt(i, y1, z1)}; - result.add(buffer); - p.sendBlockChange(new Location(world, i, y1, z1), id, color); - - buffer = new int[] {i, y2, z1, world.getBlockTypeIdAt(i, y2, z1)}; - result.add(buffer); - p.sendBlockChange(new Location(world, i, y2, z1), id, color); - - buffer = new int[] {i, y1, z2, world.getBlockTypeIdAt(i, y1, z2)}; - result.add(buffer); - p.sendBlockChange(new Location(world, i, y1, z2), id, color); - - buffer = new int[] {i, y2, z2, world.getBlockTypeIdAt(i, y2, z2)}; - result.add(buffer); - p.sendBlockChange(new Location(world, i, y2, z2), id, color); - } - for (int j = y1+1; j <= y2-1; j++) - { - buffer = new int[] {x1, j, z1, world.getBlockTypeIdAt(x1, j, z1)}; - result.add(buffer); - p.sendBlockChange(new Location(world, x1, j, z1), id, color); - - buffer = new int[] {x2, j, z1, world.getBlockTypeIdAt(x2, j, z1)}; - result.add(buffer); - p.sendBlockChange(new Location(world, x2, j, z1), id, color); - - buffer = new int[] {x1, j, z2, world.getBlockTypeIdAt(x1, j, z2)}; - result.add(buffer); - p.sendBlockChange(new Location(world, x1, j, z2), id, color); - - buffer = new int[] {x2, j, z2, world.getBlockTypeIdAt(x2, j, z2)}; - result.add(buffer); - p.sendBlockChange(new Location(world, x2, j, z2), id, color); - } - for (int k = z1+1; k <= z2-1; k++) - { - buffer = new int[] {x1, y1, k, world.getBlockTypeIdAt(x1, y1, k)}; - result.add(buffer); - p.sendBlockChange(new Location(world, x1, y1, k), id, color); - - buffer = new int[] {x2, y1, k, world.getBlockTypeIdAt(x2, y1, k)}; - result.add(buffer); - p.sendBlockChange(new Location(world, x2, y1, k), id, color); - - buffer = new int[] {x1, y2, k, world.getBlockTypeIdAt(x1, y2, k)}; - result.add(buffer); - p.sendBlockChange(new Location(world, x1, y2, k), id, color); - - buffer = new int[] {x2, y2, k, world.getBlockTypeIdAt(x2, y2, k)}; - result.add(buffer); - p.sendBlockChange(new Location(world, x2, y2, k), id, color); - } - return result; - } - - public static Set showRegion(Player p, World world, Location p1, Location p2, int id) - { - return showRegion(p, world, p1, p2, id, (byte) 0); - } - - /** - * Take all the blocks with coordinates (buffer[0], buffer[1], buffer[2]) and set - * their type ID to buffer[3]. Used to hide regions shown by showRegion. - */ - public static void hideRegion(int[] buffer) - { - - } - - /** - * Create a Location object from the config-file. - */ - public static Location getArenaCoord(Config config, World world, String arena, String coord) - { - //config.load(); - String str = config.getString("arenas." + arena + ".coords." + coord); - if (str == null) - return null; - return makeLocation(world, str); - } - - /** - * Save an arena location to the Config. - */ - public static void setArenaCoord(Config config, Arena arena, String coord, Location loc) - { - if (coord.equals("arena") || coord.equals("lobby") || coord.equals("spectator")) - loc.setY(loc.getY() + 1); - - config.setProperty("arenas." + arena.configName() + ".coords." + coord, makeCoord(loc)); - config.save(); - arena.load(config); - - if (coord.equals("p1") || coord.equals("p2")) - fixRegion(config, loc.getWorld(), arena); - if (coord.equals("l1") || coord.equals("l2")) - fixLobby(config, loc.getWorld(), arena); - } - - public static boolean delArenaCoord(Config config, Arena arena, String coord) - { - if (config.getString("arenas." + arena.configName() + ".coords." + coord) == null) - return false; - - config.removeProperty("arenas." + arena.configName() + ".coords." + coord); - config.save(); - arena.load(config); - return true; - } - - public static void fixRegion(Config config, World world, Arena arena) - { - if (arena.p1 == null || arena.p2 == null) - return; - - if (arena.p1.getX() > arena.p2.getX()) - { - double tmp = arena.p1.getX(); - arena.p1.setX(arena.p2.getX()); - arena.p2.setX(tmp); - } - - if (arena.p1.getZ() > arena.p2.getZ()) - { - double tmp = arena.p1.getZ(); - arena.p1.setZ(arena.p2.getZ()); - arena.p2.setZ(tmp); - } - - if (arena.p1.getY() > arena.p2.getY()) - { - double tmp = arena.p1.getY(); - arena.p1.setY(arena.p2.getY()); - arena.p2.setY(tmp); - } - - if (!arena.world.getName().equals(world.getName())) - arena.world = world; - - arena.serializeConfig(); - arena.load(config); - } - - private static void fixLobby(Config config, World world, Arena arena) - { - if (arena.l1 == null || arena.l2 == null) - return; - - if (arena.l1.getX() > arena.l2.getX()) - { - double tmp = arena.l1.getX(); - arena.l1.setX(arena.l2.getX()); - arena.l2.setX(tmp); - } - - if (arena.l1.getZ() > arena.l2.getZ()) - { - double tmp = arena.l1.getZ(); - arena.l1.setZ(arena.l2.getZ()); - arena.l2.setZ(tmp); - } - - if (arena.l1.getY() > arena.l2.getY()) - { - double tmp = arena.l1.getY(); - arena.l1.setY(arena.l2.getY()); - arena.l2.setY(tmp); - } - arena.serializeConfig(); - arena.load(config); - } - - /** - * Create a Location from the input String in the input World. - */ - public static Location makeLocation(World world, String str, boolean extras) - { - String[] parts = str.split(","); - - double x = Double.parseDouble(parts[0].trim()); - double y = Double.parseDouble(parts[1].trim()); - double z = Double.parseDouble(parts[2].trim()); - - if (extras && parts.length > 3) - { - float yaw = Float.parseFloat(parts[3].trim()); - float pitch = Float.parseFloat(parts[4].trim()); - return new Location(world, x, y, z, yaw, pitch); - } - - return new Location(world, x, y, z); - } - - public static Location makeLocation(World world, String str) - { - return makeLocation(world, str, true); - } - - /** - * Create a location String from the input Location. - */ - public static String makeCoord(Location loc, boolean extras) - { - int x = loc.getBlockX(); - int y = loc.getBlockY(); - int z = loc.getBlockZ(); - - if (extras) - { - float yaw = loc.getYaw(); - float pitch = loc.getPitch(); - return x + "," + y + "," + z + "," + yaw + "," + pitch; - } - - return x + "," + y + "," + z; - } - - public static String makeCoord(Location loc) - { - return makeCoord(loc, true); - } - - /** - * Check if a location is within any arena region. - */ - public static boolean inRegions(Location loc, Arena... arenas) - { - for (Arena arena : arenas) - { - if (arena.inRegion(loc)) - return true; - } - - return false; - } - - public static double getDouble(Config config, String path) - { - return getDouble(config, path, 0D); - } - - public static double getDouble(Config config, String path, double def) - { - Object o = config.getProperty(path); - if (o instanceof Double) - return (Double) o; - else if (o instanceof Number) - return (Integer) o; - return def; - } - - public static int getInt(Config config, String path) - { - return getInt(config, path, 0); - } - - public static int getInt(Config config, String path, int def) - { - Object o = config.getProperty(path); - if (o instanceof Integer) - return (Integer) o; - return def; - } - - - /* ///////////////////////////////////////////////////////////////////// // MISC METHODS // ///////////////////////////////////////////////////////////////////// */ - public static boolean tellSpoutPlayer(Player p, Msg msg, String s, Material logo) - { - // Grab the SpoutPlayer. - SpoutPlayer sp = MobArena.hasSpout ? SpoutManager.getPlayer(p) : null; - - if (msg.hasSpoutMsg() && sp != null && sp.isSpoutCraftEnabled()) - { - // Grab the message text. - String text = msg.toSpoutString(s); - - // If more than 26 characters, truncate. - if (text.length() > 26) - text = text.substring(0, 26); - - // If the logo is null, use an iron sword. - if (logo == null) - logo = msg.getLogo(); - - // Send the notification. - sp.sendNotification("MobArena", text, logo, (short) 0, 2000); - return true; - } - else return tellPlayer(p, msg.toString(s)); - } - public static boolean tellSpoutPlayer(Player p, Msg msg, Material logo) - { - return tellSpoutPlayer(p, msg, null, logo); - } - - public static boolean tellSpoutPlayer(Player p, Msg msg, String s) - { - return tellSpoutPlayer(p, msg, s, null); - } - - public static boolean tellSpoutPlayer(Player p, Msg msg) - { - return tellSpoutPlayer(p, msg, null, null); - } - - public static boolean tellPlayer(CommandSender p, String msg) - { - // If the input sender is null or the string is empty, return. - if (p == null || msg.equals(" ")) - return false; - - // Otherwise, send the message with the [MobArena] tag. - p.sendMessage(ChatColor.GREEN + "[MobArena] " + ChatColor.WHITE + msg); - return true; - } - - public static boolean tellPlayer(CommandSender p, Msg msg, String s, boolean spout, Material logo) - { - if (spout && p instanceof Player) - return tellSpoutPlayer((Player) p, msg, s, logo); - - return tellPlayer(p, msg.toString(s)); - } - - public static boolean tellPlayer(CommandSender p, Msg msg, String s, Material logo) - { - return tellPlayer(p, msg, s, MobArena.hasSpout, logo); - } - - public static boolean tellPlayer(CommandSender p, Msg msg, String s) - { - return tellPlayer(p, msg, s, MobArena.hasSpout, null); - } - - public static boolean tellPlayer(CommandSender p, Msg msg) - { - return tellPlayer(p, msg, null, MobArena.hasSpout, null); - } - - /** - * Sends a message to all players in and around the arena. - */ - public static void tellAll(Arena arena, Msg msg, String s, boolean notifyPlayers) - { - Set tmp = new HashSet(); - tmp.addAll(arena.arenaPlayers); - tmp.addAll(arena.lobbyPlayers); - tmp.addAll(arena.readyPlayers); - tmp.addAll(arena.notifyPlayers); - tmp.addAll(arena.specPlayers); - if (notifyPlayers) tmp.addAll(arena.notifyPlayers); - for (Player p : tmp) - tellPlayer(p, msg, s); - } - - public static void tellAll(Arena arena, Msg msg, String s) - { - tellAll(arena, msg, s, false); - } - - public static void tellAll(Arena arena, Msg msg, boolean notifyPlayers) - { - tellAll(arena, msg, null, notifyPlayers); - } - - public static void tellAll(Arena arena, Msg msg) - { - tellAll(arena, msg, null, false); - } - - public static Player getClosestPlayer(Entity e, Arena arena) - { + public static Player getClosestPlayer(MobArena plugin, Entity e, Arena arena) { // Set up the comparison variable and the result. double current = Double.POSITIVE_INFINITY; Player result = null; @@ -1082,19 +155,16 @@ public class MAUtils /* Iterate through the ArrayList, and update current and result every * time a squared distance smaller than current is found. */ //for (Player p : arena.livePlayers) - for (Player p : arena.arenaPlayers) - { - if (!arena.world.equals(p.getWorld())) - { - MobArena.info("Player '" + p.getName() + "' is not in the right world. Kicking..."); + for (Player p : arena.getPlayersInArena()) { + if (!arena.getWorld().equals(p.getWorld())) { + plugin.info("Player '" + p.getName() + "' is not in the right world. Kicking..."); p.kickPlayer("[MobArena] Cheater! (Warped out of the arena world.)"); - tellPlayer(p, "You warped out of the arena world."); + Messenger.tellPlayer(p, "You warped out of the arena world."); continue; } - double dist = distanceSquared(p, e.getLocation()); - if (dist < current && dist < 256D) - { + double dist = distanceSquared(plugin, p, e.getLocation()); + if (dist < current && dist < 256D) { current = dist; result = p; } @@ -1102,31 +172,19 @@ public class MAUtils return result; } - public static double distanceSquared(Player p, Location l) - { - try - { + public static double distanceSquared(MobArena plugin, Player p, Location l) { + try { return p.getLocation().distanceSquared(l); } - catch(Exception e) - { + catch (Exception e) { p.kickPlayer("Banned for life! No, but stop trying to cheat in MobArena!"); - MobArena.warning(p.getName() + " tried to cheat in MobArena and has been kicked."); + if (plugin != null) { + plugin.warning(p.getName() + " tried to cheat in MobArena and has been kicked."); + } return Double.MAX_VALUE; } } - /** - * Convert a proper arena name to a config-file name. - * All spaces are replaced by underscores, and the whole String is - * lowercased. - */ - public static String nameArenaToConfig(String name) - { - String tmp = name.replace(" ", "_"); - return tmp.toLowerCase(); - } - /** * Convert a config-name to a proper spaced and capsed arena name. * The input String is split around all underscores, and every part @@ -1135,13 +193,13 @@ public class MAUtils public static String nameConfigToArena(String name) { String[] parts = name.split("_"); - if (parts.length == 1) + if (parts.length == 1) { return toCamelCase(parts[0]); + } String separator = " "; StringBuffer buffy = new StringBuffer(name.length()); - for (String part : parts) - { + for (String part : parts) { buffy.append(toCamelCase(part)); buffy.append(separator); } @@ -1154,53 +212,42 @@ public class MAUtils * Returns the input String with a capital first letter, and all the * other letters become lower case. */ - public static String toCamelCase(String name) - { + public static String toCamelCase(String name) { return name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase(); } /** * Turn a list into a space-separated string-representation of the list. */ - public static String listToString(List list, boolean none, MobArena plugin) + public static String listToString(Collection list, boolean none, MobArena plugin) { - if (list == null || list.isEmpty()) - { - if (none) - return Msg.MISC_NONE.toString(); - else - return ""; + if (list == null || list.isEmpty()) { + return (none ? Msg.MISC_NONE.toString() : ""); } StringBuffer buffy = new StringBuffer(); int trimLength = 0; - E type = list.get(0); - if (type instanceof Player) - { - for (E e : list) - { + E type = list.iterator().next(); + if (type instanceof Player) { + for (E e : list) { buffy.append(((Player) e).getName()); buffy.append(" "); } } - else if (type instanceof ItemStack) - { + else if (type instanceof ItemStack) { trimLength = 2; ItemStack stack; - for (E e : list) - { + for (E e : list) { stack = (ItemStack) e; - if (stack.getTypeId() == MobArena.ECONOMY_MONEY_ID) - { - if (plugin.Method != null) - { - buffy.append(plugin.Method.format(stack.getAmount())); + if (stack.getTypeId() == MobArena.ECONOMY_MONEY_ID) { + String formatted = plugin.economyFormat(stack.getAmount()); + if (formatted != null) { + buffy.append(formatted); buffy.append(", "); } - else - { - MobArena.warning("Tried to do some money stuff, but no economy plugin was detected!"); + else { + plugin.warning("Tried to do some money stuff, but no economy plugin was detected!"); return buffy.toString(); } continue; @@ -1212,18 +259,15 @@ public class MAUtils buffy.append(", "); } } - else - { - for (E e : list) - { + else { + for (E e : list) { buffy.append(e.toString()); buffy.append(" "); } } return buffy.toString().substring(0, buffy.length() - trimLength); } - public static String listToString(List list, MobArena plugin) { return listToString(list, true, plugin); } - public static String listToString(List list) { return listToString(list, true, (MobArena) Bukkit.getServer().getPluginManager().getPlugin("MobArena")); } + public static String listToString(Collection list, JavaPlugin plugin) { return listToString(list, true, (MobArena) plugin); } /** * Returns a String-list version of a comma-separated list. @@ -1241,200 +285,6 @@ public class MAUtils return result; } - /** - * Turns the current set of players into an array, and grabs a random - * element out of it. - */ - public static Player getRandomPlayer(Arena arena) - { - Random random = new Random(); - //Player[] array = (Player[]) arena.livePlayers.toArray(); - Player[] array = (Player[]) arena.arenaPlayers.toArray(); - return array[random.nextInt(array.length)]; - } - - /** - * Verifies that all important variables are declared. Returns true - * if, and only if, the warppoints, region, distribution coefficients, - * and spawnpoints are all set up. - */ - public static boolean verifyData(Arena arena) - { - return ((arena.arenaLoc != null) && - (arena.lobbyLoc != null) && - (arena.spectatorLoc != null) && - (arena.p1 != null) && - (arena.p2 != null) && - (arena.spawnpoints.size() > 0)); - } - - public static boolean verifyLobby(Arena arena) - { - return ((arena.l1 != null) && - (arena.l2 != null)); - } - - public static void checkData(Arena arena, CommandSender p) - { - if (arena.arenaLoc == null) - tellPlayer(p, "Missing warp: arena"); - if (arena.lobbyLoc == null) - tellPlayer(p, "Missing warp: lobby"); - if (arena.spectatorLoc == null) - tellPlayer(p, "Missing warp: spectator"); - if (arena.p1 == null) - tellPlayer(p, "Missing region point: p1"); - if (arena.p2 == null) - tellPlayer(p, "Missing region point: p2"); - if (arena.spawnpoints.size() <= 0) - tellPlayer(p, "Missing spawnpoints"); - if (arena.setup) - tellPlayer(p, "Arena is ready to be used!"); - } - - /** - * Checks if there is a new update of MobArena and notifies the - * player if the boolean specified is true - */ - public static void checkForUpdates(MobArena plugin, final Player p, boolean response) - { - String site = "http://forums.bukkit.org/threads/19144/"; - try - { - // Make a URI of the site address - URI baseURI = new URI(site); - - // Open the connection and don't redirect. - HttpURLConnection con = (HttpURLConnection) baseURI.toURL().openConnection(); - con.setConnectTimeout(5000); - con.setInstanceFollowRedirects(false); - - String header = con.getHeaderField("Location"); - - // If something's wrong with the connection... - if (header == null) - { - tellPlayer(p, "Couldn't connect to the MobArena thread."); - return; - } - - // Otherwise, grab the location header to get the real URI. - String url = new URI(con.getHeaderField("Location")).toString(); - - // Set up the regex and matcher - Pattern regex = Pattern.compile("v([0-9]+-)*[0-9]+"); - Matcher matcher = regex.matcher(url); - if (!matcher.find()) - return; - - // Split the version strings - String[] forumVersion = matcher.group().substring(1).split("-"); - String[] thisVersion = plugin.getDescription().getVersion().split("\\."); - - // If the current version is older than the forum version, notify. - for (int i = 0; i < Math.min(forumVersion.length, thisVersion.length); i++) - { - if (Integer.parseInt(forumVersion[i]) > Integer.parseInt(thisVersion[i])) - { - tellPlayer(p, "There is a new version of MobArena available!");; - return; - } - } - - if (response) tellPlayer(p, "Your version of MobArena is up to date!"); - } - catch (Exception e) - { - e.printStackTrace(); - } - } - - public static int getSpawnMonsters(World world) - { - try - { - Field f = getSpawnMonstersField(world); - net.minecraft.server.World w = (net.minecraft.server.World) ((CraftWorld) world).getHandle(); - return f.getInt(w); - } - catch (Exception e) - { - e.printStackTrace(); - return 0; - } - } - - private static Field getSpawnMonstersField(World world) - { - try - { - int version = 1240; - - Pattern pattern = Pattern.compile("b([0-9][0-9][0-9][0-9])jnks"); - Matcher matcher = pattern.matcher(Bukkit.getVersion()); - if (matcher.find()) - { - String ver = matcher.group(1); - version = (ver.matches("[0-9]+")) ? Integer.parseInt(ver) : 0; - } - - String fieldName = (version >= 1191) ? "difficulty" : "spawnMonsters"; - return net.minecraft.server.World.class.getDeclaredField(fieldName); - } - catch (Exception e) - { - e.printStackTrace(); - MobArena.error("Your CraftBukkit version is messed up somehow..."); - } - - return null; - } - - public static void setSpawnFlags(MobArena plugin, World world, int spawnMonsters, boolean allowMonsters, boolean allowAnimals) - { - for (Arena arena : plugin.getAM().getArenasInWorld(world)) - if (arena.running) - return; - - //WorldServer ws = ((CraftWorld) world).getHandle(); - //ws.spawnMonsters = spawnMonsters; - //ws.allowMonsters = allowMonsters; - //ws.allowAnimals = allowAnimals; - - try - { - net.minecraft.server.World w = (net.minecraft.server.World) ((CraftWorld) world).getHandle(); - w.allowMonsters = allowMonsters; - w.allowAnimals = allowAnimals; - - Field f = getSpawnMonstersField(world); - f.setInt(w, spawnMonsters); - } - catch (Exception e) - { - e.printStackTrace(); - } - } - - public static String getDuration(long duration) - { - long seconds = duration / 1000; - long secs = seconds % 60; - long mins = (seconds - secs) / 60 % 60; - long hrs = ((seconds - secs) - (mins * 60)) / 60 / 60; - return hrs + ":" + ((mins < 10) ? "0" + mins : mins) + ":" + ((secs < 10) ? "0" + secs : secs); - } - - public static long parseDuration(String duration) - { - String[] elements = duration.split(":"); - long hrs = Long.parseLong(elements[0]) * 60 * 60; - long mins = Long.parseLong(elements[1]) * 60; - long secs = Long.parseLong(elements[2]); - - return (hrs + mins + secs) * 1000; - } - /** * Stand back, I'm going to try science! */ @@ -1444,13 +294,12 @@ public class MAUtils undoItHippieMonster(name, plugin, false); // Grab the Configuration and ArenaMaster - ArenaMaster am = plugin.getAM(); + ArenaMaster am = plugin.getArenaMaster(); // Create the arena node in the config-file. World world = loc.getWorld(); Arena arena = am.createArenaNode(name, world); - am.arenas.add(arena); - am.selectedArena = arena; + am.setSelectedArena(arena); // Get the hippie bounds. int x1 = (int)loc.getX() - radius; @@ -1461,7 +310,7 @@ public class MAUtils int z2 = (int)loc.getZ() + radius; int lx1 = x1; - int lx2 = x1 + am.classes.size() + 3; + int lx2 = x1 + am.getClasses().size() + 3; int ly1 = y1-6; int ly2 = y1-2; int lz1 = z1; @@ -1494,7 +343,7 @@ public class MAUtils catch (Exception e) { e.printStackTrace(); - MobArena.warning("Couldn't create backup file. Aborting auto-generate..."); + plugin.warning("Couldn't create backup file. Aborting auto-generate..."); return false; } @@ -1586,7 +435,8 @@ public class MAUtils world.getBlockAt(i,j,k).setTypeId(0); // Place the hippie signs - Iterator iterator = am.classes.iterator(); + //Iterator iterator = am.getClasses().iterator(); + Iterator iterator = am.getClasses().keySet().iterator(); for (int i = lx1+2; i <= lx2-2; i++) // Signs { world.getBlockAt(i,ly1+1,lz2-1).setTypeIdAndData(63, (byte)0x8, false); @@ -1595,18 +445,22 @@ public class MAUtils } world.getBlockAt(lx2-2,ly1+1,lz1+2).setType(Material.IRON_BLOCK); - // Set up the monster points. - MAUtils.setArenaCoord(plugin.getMAConfig(), arena, "p1", new Location(world, x1, ly1, z1)); - MAUtils.setArenaCoord(plugin.getMAConfig(), arena, "p2", new Location(world, x2, y2+1, z2)); - MAUtils.setArenaCoord(plugin.getMAConfig(), arena, "arena", new Location(world, loc.getX(), y1+1, loc.getZ())); - MAUtils.setArenaCoord(plugin.getMAConfig(), arena, "lobby", new Location(world, x1+2, ly1+1, z1+2)); - MAUtils.setArenaCoord(plugin.getMAConfig(), arena, "spectator", new Location(world, loc.getX(), y2+1, loc.getZ())); - MAUtils.setArenaCoord(plugin.getMAConfig(), arena, "spawnpoints.s1", new Location(world, x1+3, y1+2, z1+3)); - MAUtils.setArenaCoord(plugin.getMAConfig(), arena, "spawnpoints.s2", new Location(world, x1+3, y1+2, z2-3)); - MAUtils.setArenaCoord(plugin.getMAConfig(), arena, "spawnpoints.s3", new Location(world, x2-3, y1+2, z1+3)); - MAUtils.setArenaCoord(plugin.getMAConfig(), arena, "spawnpoints.s4", new Location(world, x2-3, y1+2, z2-3)); + // Set up the monster points. + ArenaRegion region = arena.getRegion(); + region.set("p1", new Location(world, x1, ly1, z1)); + region.set("p2", new Location(world, x2, y2+1, z2)); - am.updateAll(); + region.set("arena", new Location(world, loc.getX(), y1+1, loc.getZ())); + region.set("lobby", new Location(world, x1+2, ly1+1, z1+2)); + region.set("spectator", new Location(world, loc.getX(), y2+1, loc.getZ())); + + region.addSpawn("s1", new Location(world, x1+3, y1+2, z1+3)); + region.addSpawn("s2", new Location(world, x1+3, y1+2, z2-3)); + region.addSpawn("s3", new Location(world, x2-3, y1+2, z1+3)); + region.addSpawn("s4", new Location(world, x2-3, y1+2, z2-3)); + region.save(); + + am.reloadConfig(); return true; } @@ -1627,11 +481,11 @@ public class MAUtils } catch (Exception e) { - if (error) MobArena.warning("Couldn't find backup file for arena '" + name + "'"); + if (error) plugin.warning("Couldn't find backup file for arena '" + name + "'"); return false; } - World world = Bukkit.getServer().getWorld(preciousPatch.keySet().iterator().next().getWorld()); + World world = plugin.getServer().getWorld(preciousPatch.keySet().iterator().next().getWorld()); for (Map.Entry entry : preciousPatch.entrySet()) { @@ -1639,12 +493,12 @@ public class MAUtils } Config config = plugin.getMAConfig(); - config.removeProperty("arenas." + name); + config.remove("arenas." + name); config.save(); file.delete(); - plugin.getAM().updateAll(); + plugin.getArenaMaster().reloadConfig(); return true; } } \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/Messenger.java b/src/com/garbagemule/MobArena/Messenger.java new file mode 100644 index 0000000..bdaa140 --- /dev/null +++ b/src/com/garbagemule/MobArena/Messenger.java @@ -0,0 +1,103 @@ +package com.garbagemule.MobArena; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.getspout.spoutapi.SpoutManager; +import org.getspout.spoutapi.player.SpoutPlayer; + +import com.garbagemule.MobArena.framework.Arena; + +public class Messenger +{ + public static boolean tellSpoutPlayer(Player p, Msg msg, String s, Material logo) { + // Grab the SpoutPlayer. + SpoutPlayer sp = MobArena.hasSpout ? SpoutManager.getPlayer(p) : null; + + if (msg.hasSpoutMsg() && sp != null && sp.isSpoutCraftEnabled()) { + // Grab the message text. + String text = msg.toSpoutString(s); + + // If more than 26 characters, truncate. + if (text.length() > 26) + text = text.substring(0, 26); + + // If the logo is null, use an iron sword. + if (logo == null) + logo = msg.getLogo(); + + // Send the notification. + sp.sendNotification("MobArena", text, logo, (short) 0, 2000); + return true; + } + else { + return tellPlayer(p, msg.toString(s)); + } + } + + public static boolean tellSpoutPlayer(Player p, Msg msg, Material logo) { + return tellSpoutPlayer(p, msg, null, logo); + } + + public static boolean tellSpoutPlayer(Player p, Msg msg, String s) { + return tellSpoutPlayer(p, msg, s, null); + } + + public static boolean tellSpoutPlayer(Player p, Msg msg) { + return tellSpoutPlayer(p, msg, null, null); + } + + public static boolean tellPlayer(CommandSender p, String msg) { + // If the input sender is null or the string is empty, return. + if (p == null || msg.equals(" ")) + return false; + + // Otherwise, send the message with the [MobArena] tag. + p.sendMessage(ChatColor.GREEN + "[MobArena] " + ChatColor.WHITE + msg); + return true; + } + + public static boolean tellPlayer(CommandSender p, Msg msg, String s, boolean spout, Material logo) { + if (spout && p instanceof Player) + return tellSpoutPlayer((Player) p, msg, s, logo); + + return tellPlayer(p, msg.toString(s)); + } + + public static boolean tellPlayer(CommandSender p, Msg msg, String s, Material logo) { + return tellPlayer(p, msg, s, MobArena.hasSpout, logo); + } + + public static boolean tellPlayer(CommandSender p, Msg msg, String s) { + return tellPlayer(p, msg, s, MobArena.hasSpout, null); + } + + public static boolean tellPlayer(CommandSender p, Msg msg) { + return tellPlayer(p, msg, null, MobArena.hasSpout, null); + } + + public static void tellAll(Arena arena, Msg msg, String s, boolean notifyPlayers) { + List players = new ArrayList(); + players.addAll(arena.getPlayersInArena()); + players.addAll(arena.getPlayersInLobby()); + players.addAll(arena.getSpectators()); + for (Player p : players) + tellPlayer(p, msg, s); + } + + public static void tellAll(Arena arena, Msg msg, String s) { + tellAll(arena, msg, s, false); + } + + public static void tellAll(Arena arena, Msg msg, boolean notifyPlayers) { + tellAll(arena, msg, null, notifyPlayers); + } + + public static void tellAll(Arena arena, Msg msg) { + tellAll(arena, msg, null, false); + } +} diff --git a/src/com/garbagemule/MobArena/MobArena.java b/src/com/garbagemule/MobArena/MobArena.java index c4549ed..1a60211 100644 --- a/src/com/garbagemule/MobArena/MobArena.java +++ b/src/com/garbagemule/MobArena/MobArena.java @@ -1,221 +1,279 @@ package com.garbagemule.MobArena; import java.io.File; +import java.util.HashSet; import java.util.Random; +import java.util.Set; + +import net.milkbowl.vault.economy.Economy; +import net.milkbowl.vault.economy.EconomyResponse; +import net.milkbowl.vault.economy.EconomyResponse.ResponseType; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.Event.Priority; -import org.bukkit.event.block.BlockListener; -import org.bukkit.event.player.PlayerListener; -import org.bukkit.event.entity.EntityListener; import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.PluginDescriptionFile; -import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.PluginManager; -//import org.bukkit.util.config.Configuration; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.ServicesManager; +import org.bukkit.plugin.java.JavaPlugin; +import com.garbagemule.MobArena.ArenaMasterImpl; +import com.garbagemule.MobArena.MAMessages; +import com.garbagemule.MobArena.commands.CommandHandler; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; +import com.garbagemule.MobArena.health.HealthStrategy; +import com.garbagemule.MobArena.health.HealthStrategyHeroes; +import com.garbagemule.MobArena.health.HealthStrategyStandard; +import com.garbagemule.MobArena.listeners.MAGlobalListener; import com.garbagemule.MobArena.listeners.MagicSpellsListener; -import com.garbagemule.MobArena.spout.Spouty; -import com.garbagemule.MobArena.util.Config; +import com.garbagemule.MobArena.listeners.SpoutScreenListener; import com.garbagemule.MobArena.util.FileUtils; -import com.garbagemule.register.payment.Method; -import com.garbagemule.register.payment.Methods; +import com.garbagemule.MobArena.util.config.Config; +import com.garbagemule.MobArena.util.config.ConfigUtils; +import com.garbagemule.MobArena.util.inventory.InventoryManager; /** * MobArena * @author garbagemule */ -public class MobArena extends JavaPlugin implements MobArenaPlugin +public class MobArena extends JavaPlugin { - //private Configuration config; private Config config; - private ArenaMaster am; + private ArenaMaster arenaMaster; - // Economy stuff - protected Method Method; + // Inventories from disconnects + private Set inventoriesToRestore; + + // Heroes + private boolean hasHeroes; + private HealthStrategy healthStrategy; + + // Vault + private Economy economy; // Spout stuff public static boolean hasSpout; - // Global variables - public static PluginDescriptionFile desc; - public static File dir, arenaDir; - public static final double MIN_PLAYER_DISTANCE = 15D; public static final double MIN_PLAYER_DISTANCE_SQUARED = 225D; public static final int ECONOMY_MONEY_ID = -29; public static Random random = new Random(); - public void onEnable() - { - // Description file and data folders - desc = getDescription(); - dir = getDataFolder(); - arenaDir = new File(dir, "arenas"); - if (!dir.exists()) dir.mkdirs(); - if (!arenaDir.exists()) arenaDir.mkdir(); - + public void onEnable() { // Create default files and initialize config-file - FileUtils.extractDefaults("config.yml"); - loadConfig(); + FileUtils.extractDefaults(this, "config.yml"); + loadConfigFile(); // Download external libraries if needed. - FileUtils.fetchLibs(config); + FileUtils.fetchLibs(this, config); // Set up soft dependencies - setupRegister(); + setupVault(); + setupHeroes(); setupSpout(); setupMagicSpells(); + setupStrategies(); - // Set up the ArenaMaster and the announcements - am = new ArenaMasterStandard(this); - am.initialize(); + // Set up the ArenaMaster + arenaMaster = new ArenaMasterImpl(this); + arenaMaster.initialize(); + // Register any inventories to restore. + registerInventories(); + + // Make sure all the announcements are configured. MAMessages.init(this); // Register event listeners registerListeners(); // Announce enable! - info("v" + desc.getVersion() + " enabled."); + info("v" + this.getDescription().getVersion() + " enabled."); } - public void onDisable() - { + public void onDisable() { // Disable Spout features. hasSpout = false; // Force all arenas to end. - if (am == null) return; - for (Arena arena : am.arenas) + if (arenaMaster == null) return; + for (Arena arena : arenaMaster.getArenas()) { arena.forceEnd(); - am.arenaMap.clear(); + } + arenaMaster.resetArenaMap(); info("disabled."); } - private void loadConfig() - { - File file = new File(dir, "config.yml"); + private void loadConfigFile() { + File dir = this.getDataFolder(); + if (!dir.exists()) dir.mkdir(); + + File file = new File(this.getDataFolder(), "config.yml"); config = new Config(file); config.load(); + + updateSettings(config); config.setHeader(getHeader()); + config.save(); } - private void registerListeners() - { + private void registerListeners() { // Bind the /ma, /mobarena commands to MACommands. - MACommands commandExecutor = new MACommands(this, am); - getCommand("ma").setExecutor(commandExecutor); - getCommand("mobarena").setExecutor(commandExecutor); + CommandHandler handler = new CommandHandler(this); + getCommand("ma").setExecutor(handler); + getCommand("mobarena").setExecutor(handler); - // Create event listeners. - PluginManager pm = getServer().getPluginManager(); - PlayerListener playerListener = new MAPlayerListener(this, am); - EntityListener entityListener = new MAEntityListener(am); - BlockListener blockListener = new MABlockListener(am); + PluginManager pm = this.getServer().getPluginManager(); + pm.registerEvents(new MAGlobalListener(this, arenaMaster), this); - // Register events. - pm.registerEvent(Event.Type.BLOCK_BREAK, blockListener, Priority.Highest, this); - pm.registerEvent(Event.Type.BLOCK_BURN, blockListener, Priority.Highest, this); - pm.registerEvent(Event.Type.BLOCK_PLACE, blockListener, Priority.Highest, this); - pm.registerEvent(Event.Type.BLOCK_IGNITE, blockListener, Priority.Highest, this); - pm.registerEvent(Event.Type.SIGN_CHANGE, blockListener, Priority.Normal, this); - pm.registerEvent(Event.Type.PLAYER_INTERACT, playerListener, Priority.Normal, this); - pm.registerEvent(Event.Type.PLAYER_DROP_ITEM, playerListener, Priority.Normal, this); - pm.registerEvent(Event.Type.PLAYER_BUCKET_EMPTY, playerListener, Priority.Normal, this); - pm.registerEvent(Event.Type.PLAYER_TELEPORT, playerListener, Priority.Normal, this); - pm.registerEvent(Event.Type.PLAYER_QUIT, playerListener, Priority.Normal, this); - pm.registerEvent(Event.Type.PLAYER_KICK, playerListener, Priority.Normal, this); - pm.registerEvent(Event.Type.PLAYER_JOIN, playerListener, Priority.Normal, this); - pm.registerEvent(Event.Type.PLAYER_ANIMATION, playerListener, Priority.Normal, this); - pm.registerEvent(Event.Type.ENTITY_DAMAGE, entityListener, Priority.Low, this); // Must cancel before Heroes - pm.registerEvent(Event.Type.ENTITY_DEATH, entityListener, Priority.Lowest, this); // Lowest because of Tombstone - pm.registerEvent(Event.Type.ENTITY_REGAIN_HEALTH, entityListener, Priority.Normal, this); - pm.registerEvent(Event.Type.ENTITY_EXPLODE, entityListener, Priority.Highest, this); - pm.registerEvent(Event.Type.ENTITY_COMBUST, entityListener, Priority.Normal, this); - pm.registerEvent(Event.Type.ENTITY_TARGET, entityListener, Priority.Normal, this); - pm.registerEvent(Event.Type.ENDERMAN_PICKUP, entityListener, Priority.Normal, this); - pm.registerEvent(Event.Type.ENDERMAN_PLACE, entityListener, Priority.Normal, this); - pm.registerEvent(Event.Type.CREATURE_SPAWN, entityListener, Priority.Highest, this); - pm.registerEvent(Event.Type.PLAYER_COMMAND_PREPROCESS, playerListener, Priority.Monitor, this); // I know Monitor is bad, but other plugins suck! :( + if (hasSpout) { + pm.registerEvents(new SpoutScreenListener(this), this); + } } // Permissions stuff - public boolean has(Player p, String s) - { - // If the permission is set, check if player has permission - if (p.isPermissionSet(s)) - return p.hasPermission(s); - - // Otherwise, only allow commands that aren't admin/setup commands. - return !s.matches("^mobarena\\.setup\\..*$") && !s.matches("^mobarena\\.admin\\..*$"); + public boolean has(Player p, String s) { + return p.hasPermission(s); + } + + public boolean has(CommandSender sender, String s) { + if (sender instanceof ConsoleCommandSender) { + return true; + } + return has((Player) sender, s); } // Console printing - public static void info(String msg) { Bukkit.getServer().getLogger().info("[MobArena] " + msg); } - public static void warning(String msg) { Bukkit.getServer().getLogger().warning("[MobArena] " + msg); } - public static void error(String msg) { Bukkit.getServer().getLogger().severe("[MobArena] " + msg); } + public void info(String msg) { getServer().getLogger().info("[MobArena] " + msg); } + public void warning(String msg) { getServer().getLogger().warning("[MobArena] " + msg); } + public void error(String msg) { getServer().getLogger().severe("[MobArena] " + msg); } - @Override - public void tell(CommandSender sender, String msg) { - if (sender == null || msg.equals("") || msg.equals(" ")) + private void setupVault() { + Plugin vaultPlugin = this.getServer().getPluginManager().getPlugin("Vault"); + if (vaultPlugin == null) { + warning("Vault was not found. Economy rewards will not work!"); return; + } - sender.sendMessage(ChatColor.GREEN + "[MobArena] " + ChatColor.WHITE + msg); + ServicesManager manager = this.getServer().getServicesManager(); + RegisteredServiceProvider e = manager.getRegistration(net.milkbowl.vault.economy.Economy.class); + + if (e != null) { + economy = e.getProvider(); + } else { + warning("Vault found, but no economy plugin detected. Economy rewards will not work!"); + } } - @Override - public void tell(CommandSender sender, Msg msg) { - tell(sender, msg.toString()); + private void setupHeroes() { + Plugin heroesPlugin = this.getServer().getPluginManager().getPlugin("Heroes"); + if (heroesPlugin == null) return; + + hasHeroes = true; } - private void setupRegister() - { - Methods.setMethod(getServer().getPluginManager()); - - Method = Methods.getMethod(); - if (Method != null) - info("Payment method found (" + Method.getName() + " version: " + Method.getVersion() + ")"); - else - info("No payment method found!"); - } - - private void setupSpout() - { - if (hasSpout) return; - + private void setupSpout() { Plugin spoutPlugin = this.getServer().getPluginManager().getPlugin("Spout"); - hasSpout = spoutPlugin != null; - if (!hasSpout) return; + if (spoutPlugin == null) return; - Spouty.registerEvents(this); + hasSpout = true; } - private void setupMagicSpells() - { + private void setupMagicSpells() { Plugin spells = this.getServer().getPluginManager().getPlugin("MagicSpells"); if (spells == null) return; - PluginManager pm = getServer().getPluginManager(); - - pm.registerEvent(Event.Type.CUSTOM_EVENT, new MagicSpellsListener(this), Priority.Normal, this); + this.getServer().getPluginManager().registerEvents(new MagicSpellsListener(this), this); } - public Config getMAConfig() { return config; } - public ArenaMaster getAM() { return am; } // More convenient. + private void setupStrategies() { + healthStrategy = (hasHeroes ? new HealthStrategyHeroes() : new HealthStrategyStandard()); + } - @Override - public ArenaMaster getArenaMaster() { return am; } + public HealthStrategy getHealthStrategy() { + return healthStrategy; + } - private String getHeader() - { + public Config getMAConfig() { + return config; + } + + public ArenaMaster getArenaMaster() { + return arenaMaster; + } + + private void updateSettings(Config config) { + Set arenas = config.getKeys("arenas"); + if (arenas == null) return; + + for (String arena : arenas) { + String path = "arenas." + arena + ".settings"; + ConfigUtils.replaceAllNodes(this, config, path, "settings.yml"); + } + } + + private String getHeader() { String sep = System.getProperty("line.separator"); - return "# MobArena v" + desc.getVersion() + " - Config-file" + sep + - "# Read the Wiki for details on how to set up this file: http://goo.gl/F5TTc" + sep + - "# Note: You -must- use spaces instead of tabs!"; + return "MobArena v" + this.getDescription().getVersion() + " - Config-file" + sep + + "Read the Wiki for details on how to set up this file: http://goo.gl/F5TTc" + sep + + "Note: You -must- use spaces instead of tabs!\r"; + } + + private void registerInventories() { + this.inventoriesToRestore = new HashSet(); + + File dir = new File(getDataFolder(), "inventories"); + if (!dir.exists()) { + dir.mkdir(); + return; + } + + for (File f : dir.listFiles()) { + if (f.getName().endsWith(".inv")) { + inventoriesToRestore.add(f.getName().substring(0, f.getName().indexOf("."))); + } + } + } + + public void restoreInventory(Player p) { + if (!inventoriesToRestore.contains(p.getName())) { + return; + } + + if (InventoryManager.restoreFromFile(this, p)) { + inventoriesToRestore.remove(p.getName()); + } + } + + public boolean giveMoney(Player p, int amount) { + if (economy != null) { + EconomyResponse result = economy.depositPlayer(p.getName(), amount); + return (result.type == ResponseType.SUCCESS); + } + return false; + } + + public boolean takeMoney(Player p, int amount) { + if (economy != null) { + EconomyResponse result = economy.withdrawPlayer(p.getName(), amount); + return (result.type == ResponseType.SUCCESS); + } + return false; + } + + public boolean hasEnough(Player p, double amount) { + if (economy != null) { + return (economy.getBalance(p.getName()) >= amount); + } + return true; + } + + public String economyFormat(double amount) { + if (economy != null) { + return economy.format(amount); + } + return null; } } \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/MobArenaHandler.java b/src/com/garbagemule/MobArena/MobArenaHandler.java index 1b429f8..147a33c 100644 --- a/src/com/garbagemule/MobArena/MobArenaHandler.java +++ b/src/com/garbagemule/MobArena/MobArenaHandler.java @@ -6,16 +6,18 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; +import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.framework.Arena; + public class MobArenaHandler { private MobArena plugin; /** * Primary constructor. - * The boolean 'ma' is flagged true, and the field 'plugin' is initalized, if the server is running MobArena. + * The field 'plugin' is initalized, if the server is running MobArena. */ - public MobArenaHandler() - { + public MobArenaHandler() { plugin = (MobArena) Bukkit.getServer().getPluginManager().getPlugin("MobArena"); } @@ -32,12 +34,13 @@ public class MobArenaHandler * @param loc A location. * @return true, if the Location is inside of any arena region. */ - public boolean inRegion(Location loc) - { - for (Arena arena : plugin.getAM().arenas) - if (arena.inRegion(loc)) + public boolean inRegion(Location loc) { + for (Arena arena : plugin.getArenaMaster().getArenas()) { + if (arena.getRegion().contains(loc)) { return true; - + } + } + return false; } @@ -47,9 +50,8 @@ public class MobArenaHandler * @param loc A location * @return true, if the Location is inside of the arena region. */ - public boolean inRegion(Arena arena, Location loc) - { - return (arena != null && arena.inRegion(loc)); + public boolean inRegion(Arena arena, Location loc) { + return (arena != null && arena.getRegion().contains(loc)); } /** @@ -58,13 +60,12 @@ public class MobArenaHandler * @param loc A location * @return true, if the Location is inside of the arena region. */ - public boolean inRegion(String arenaName, Location loc) - { - Arena arena = plugin.getAM().getArenaWithName(arenaName); + public boolean inRegion(String arenaName, Location loc) { + Arena arena = plugin.getArenaMaster().getArenaWithName(arenaName); if (arena == null) throw new NullPointerException("There is no arena with that name"); - - return arena.inRegion(loc); + + return arena.getRegion().contains(loc); } /** @@ -72,8 +73,7 @@ public class MobArenaHandler * @param loc A location. * @return true, if the Location is inside of the region of an arena that is currently running. */ - public boolean inRunningRegion(Location loc) - { + public boolean inRunningRegion(Location loc) { return inRegion(loc, false, true); } @@ -82,8 +82,7 @@ public class MobArenaHandler * @param loc A location. * @return true, if the Location is inside of the region of an arena that is currently enabled. */ - public boolean inEnabledRegion(Location loc) - { + public boolean inEnabledRegion(Location loc) { return inRegion(loc, true, false); } @@ -94,17 +93,19 @@ public class MobArenaHandler * @param running if true, the method will check if the arena is running, overrides enabled * @return true, if the location is inside of the region of an arena that is currently enabled/running, depending on the parameters. */ - private boolean inRegion(Location loc, boolean enabled, boolean running) - { + private boolean inRegion(Location loc, boolean enabled, boolean running) { // If the plugin doesn't exist, always return false. - if (plugin.getAM() == null) return false; - + if (plugin.getArenaMaster() == null) return false; + // Return true if location is within just one arena's region. - for (Arena arena : plugin.getAM().arenas) - if (arena.inRegion(loc)) - if ((running && arena.running) || (enabled && arena.enabled)) + for (Arena arena : plugin.getArenaMaster().getArenas()) { + if (arena.getRegion().contains(loc)) { + if ((running && arena.isRunning()) || (enabled && arena.isEnabled())) { return true; - + } + } + } + return false; } @@ -121,9 +122,8 @@ public class MobArenaHandler * @param player The player * @return true, if the player is in an arena */ - public boolean isPlayerInArena(Player player) - { - return (plugin.getAM().getArenaWithPlayer(player) != null); + public boolean isPlayerInArena(Player player) { + return (plugin.getArenaMaster().getArenaWithPlayer(player) != null); } /** @@ -131,9 +131,8 @@ public class MobArenaHandler * @param playerName The name of the player * @return true, if the player is in an arena */ - public boolean isPlayerInArena(String playerName) - { - return (plugin.getAM().getArenaWithPlayer(playerName) != null); + public boolean isPlayerInArena(String playerName) { + return (plugin.getArenaMaster().getArenaWithPlayer(playerName) != null); } /** @@ -141,12 +140,11 @@ public class MobArenaHandler * @param player The player * @return The class name of the player if the player is in the arena, null otherwise */ - public String getPlayerClass(Player player) - { - Arena arena = plugin.getAM().getArenaWithPlayer(player); + public String getPlayerClass(Player player) { + Arena arena = plugin.getArenaMaster().getArenaWithPlayer(player); if (arena == null) return null; - - return arena.classMap.get(player); + + return getPlayerClass(arena, player); } /** @@ -156,9 +154,14 @@ public class MobArenaHandler * @param player The player to look up * @return The class name of the player, if the player is in the arena, null otherwise */ - public String getPlayerClass(Arena arena, Player player) - { - return arena.classMap.get(player); + public String getPlayerClass(Arena arena, Player player) { + ArenaPlayer ap = arena.getArenaPlayer(player); + if (ap == null) return null; + + ArenaClass ac = ap.getArenaClass(); + if (ac == null) return null; + + return ac.getName(); } /** @@ -166,9 +169,8 @@ public class MobArenaHandler * @param entity The monster entity * @return true, if the monster is in an arena */ - public boolean isMonsterInArena(LivingEntity entity) - { - return plugin.getAM().getArenaWithMonster(entity) != null; + public boolean isMonsterInArena(LivingEntity entity) { + return plugin.getArenaMaster().getArenaWithMonster(entity) != null; } /** @@ -176,9 +178,8 @@ public class MobArenaHandler * @param wolf The pet wolf * @return true, if the pet is in an arena */ - public boolean isPetInArena(LivingEntity wolf) - { - return plugin.getAM().getArenaWithPet(wolf) != null; + public boolean isPetInArena(LivingEntity wolf) { + return plugin.getArenaMaster().getArenaWithPet(wolf) != null; } @@ -194,9 +195,8 @@ public class MobArenaHandler * @param loc A location * @return an Arena object, or null */ - public Arena getArenaAtLocation(Location loc) - { - return plugin.getAM().getArenaAtLocation(loc); + public Arena getArenaAtLocation(Location loc) { + return plugin.getArenaMaster().getArenaAtLocation(loc); } /** @@ -204,9 +204,8 @@ public class MobArenaHandler * @param p A player * @return an Arena object, or null */ - public Arena getArenaWithPlayer(Player p) - { - return plugin.getAM().getArenaWithPlayer(p); + public Arena getArenaWithPlayer(Player p) { + return plugin.getArenaMaster().getArenaWithPlayer(p); } /** @@ -214,9 +213,8 @@ public class MobArenaHandler * @param wolf A pet wolf * @return an Arena object, or null */ - public Arena getArenaWithPet(Entity wolf) - { - return plugin.getAM().getArenaWithPet(wolf); + public Arena getArenaWithPet(Entity wolf) { + return plugin.getArenaMaster().getArenaWithPet(wolf); } /** @@ -224,8 +222,7 @@ public class MobArenaHandler * @param monster A monster * @return an Arena object, or null */ - public Arena getArenaWithMonster(Entity monster) - { - return plugin.getAM().getArenaWithMonster(monster); + public Arena getArenaWithMonster(Entity monster) { + return plugin.getArenaMaster().getArenaWithMonster(monster); } } diff --git a/src/com/garbagemule/MobArena/MobArenaListener.java b/src/com/garbagemule/MobArena/MobArenaListener.java deleted file mode 100644 index 0391c6b..0000000 --- a/src/com/garbagemule/MobArena/MobArenaListener.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.garbagemule.MobArena; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; - -import com.garbagemule.MobArena.waves.Wave.WaveBranch; -import com.garbagemule.MobArena.waves.Wave.WaveType; - -public abstract class MobArenaListener -{ - protected MobArena plugin; - - public MobArenaListener() - { - plugin = (MobArena) Bukkit.getServer().getPluginManager().getPlugin("MobArena"); - plugin.getAM().listeners.add(this); - } - - public void onArenaStart(Arena arena) {} - public void onArenaEnd(Arena arena) {} - public void onWave(Arena arena, int waveNumber, String waveName, WaveBranch waveBranch, WaveType waveType) {} - public void onPlayerJoin(Arena arena, Player p) {} - public void onPlayerLeave(Arena arena, Player p) {} - public void onPlayerDeath(Arena arena, Player p) {} -} diff --git a/src/com/garbagemule/MobArena/MobArenaPlugin.java b/src/com/garbagemule/MobArena/MobArenaPlugin.java deleted file mode 100644 index 33ef25e..0000000 --- a/src/com/garbagemule/MobArena/MobArenaPlugin.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.garbagemule.MobArena; - -import org.bukkit.command.CommandSender; - -import com.garbagemule.MobArena.util.Config; - -public interface MobArenaPlugin -{ - /** - * Get the Config object associated with this MobArena instance. - * @return the Config object used by MobArena - */ - public Config getMAConfig(); - - /** - * Get the ArenaMaster used by this instance of MobArena. - * @return the ArenaMaster object - */ - public ArenaMaster getArenaMaster(); - - /** - * Send a message to a player or the console. - * The message is prefixed with [MobArena]. - * @param recipient the player or console to send the message to - * @param msg the message to send - */ - public void tell(CommandSender recipient, String msg); - - /** - * Send a predefined announcement to a player or the console. - * Convenience method: the above method is called with Msg.toString() - * @param recipient the player or console to send the message to - * @param msg the message to send - */ - public void tell(CommandSender recipient, Msg msg); -} diff --git a/src/com/garbagemule/MobArena/MonsterManager.java b/src/com/garbagemule/MobArena/MonsterManager.java new file mode 100644 index 0000000..4f97228 --- /dev/null +++ b/src/com/garbagemule/MobArena/MonsterManager.java @@ -0,0 +1,130 @@ +package com.garbagemule.MobArena; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Wolf; +import org.bukkit.inventory.ItemStack; + +import com.garbagemule.MobArena.waves.MABoss; + +public class MonsterManager +{ + private Set monsters, sheep; + private Set pets; + private Map bosses; + private Map> suppliers; + + public MonsterManager() { + this.monsters = new HashSet(); + this.sheep = new HashSet(); + this.pets = new HashSet(); + this.bosses = new HashMap(); + this.suppliers = new HashMap>(); + } + + public void reset() { + monsters.clear(); + sheep.clear(); + pets.clear(); + bosses.clear(); + suppliers.clear(); + } + + public void clear() { + removeAll(monsters); + removeAll(sheep); + removeAll(pets); + removeAll(bosses.keySet()); + removeAll(suppliers.keySet()); + + reset(); + } + + private void removeAll(Collection collection) { + for (LivingEntity e : collection) { + if (e != null) { + e.remove(); + } + } + } + + public Set getMonsters() { + return monsters; + } + + public void addMonster(LivingEntity e) { + monsters.add(e); + } + + public boolean removeMonster(Entity e) { + return monsters.remove(e); + } + + public Set getExplodingSheep() { + return sheep; + } + + public void addExplodingSheep(LivingEntity e) { + sheep.add(e); + } + + public boolean removeExplodingSheep(LivingEntity e) { + return sheep.remove(e); + } + + public Set getPets() { + return pets; + } + + public void addPet(Wolf w) { + pets.add(w); + } + + public boolean hasPet(Entity e) { + return pets.contains(e); + } + + public void removePets(Player p) { + for (Wolf w : pets) { + if (w == null || !(w.getOwner() instanceof Player) || !((Player) w.getOwner()).getName().equals(p.getName())) + continue; + + w.setOwner(null); + w.remove(); + } + } + + public void addSupplier(LivingEntity e, List drops) { + suppliers.put(e, drops); + } + + public List getLoot(Entity e) { + return suppliers.get(e); + } + + public MABoss addBoss(LivingEntity e, int maxHealth) { + MABoss b = new MABoss(e, maxHealth); + bosses.put(e, b); + return b; + } + + public MABoss removeBoss(LivingEntity e) { + return bosses.remove(e); + } + + public MABoss getBoss(LivingEntity e) { + return bosses.get(e); + } + + public Set getBossMonsters() { + return bosses.keySet(); + } +} diff --git a/src/com/garbagemule/MobArena/Msg.java b/src/com/garbagemule/MobArena/Msg.java index cbe8a61..ede3e66 100644 --- a/src/com/garbagemule/MobArena/Msg.java +++ b/src/com/garbagemule/MobArena/Msg.java @@ -53,6 +53,8 @@ public enum Msg WAVE_DEFAULT("Wave #%!", "Wave #%!", Material.YELLOW_FLOWER), WAVE_SPECIAL("Wave #%! [SPECIAL]", "Wave #%! [SPECIAL]", Material.RED_ROSE), WAVE_SWARM("Wave #%! [SWARM]", "Wave #%! [SWARM]", Material.LONG_GRASS), + WAVE_SUPPLY("Wave #%! [SUPPLY]", "Wave #%! [SUPPLY]", Material.BREAD), + WAVE_UPGRADE("Wave #%! [UPGRADE]", "Wave #%! [UPGRADE]", Material.DIAMOND), WAVE_BOSS("Wave #%! [BOSS]", "Wave #%! [BOSS]", Material.FIRE), WAVE_BOSS_ABILITY("Boss used ability: %!", "Boss: %", Material.FIRE), WAVE_BOSS_LOW_HEALTH("Boss is almost dead!", "Boss almost dead!", Material.FIRE), @@ -61,6 +63,10 @@ public enum Msg MISC_LIST_ARENAS("Available arenas: %"), MISC_COMMAND_NOT_ALLOWED("You can't use that command in the arena!"), MISC_NO_ACCESS("You don't have access to this command."), + MISC_NOT_FROM_CONSOLE("You can't use this command from the console."), + MISC_HELP("For a list of commands, type /ma help"), + MISC_MULTIPLE_MATCHES("Did you mean one of these commands?"), + MISC_NO_MATCHES("Command not found. Type /ma help"), MISC_NONE(""); private String msg, spoutMsg; diff --git a/src/com/garbagemule/MobArena/PlayerData.java b/src/com/garbagemule/MobArena/PlayerData.java new file mode 100644 index 0000000..439dcbb --- /dev/null +++ b/src/com/garbagemule/MobArena/PlayerData.java @@ -0,0 +1,108 @@ +package com.garbagemule.MobArena; + +import java.util.Collection; + +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; + +public class PlayerData +{ + private Player player; + + private int health, food, level; + private float exp; + private GameMode mode = null; + private Location entry = null; + private Collection potions; + + public PlayerData(Player player) { + this.player = player; + this.mode = player.getGameMode(); + this.entry = player.getLocation(); + this.potions = player.getActivePotionEffects(); + + update(); + } + + /** + * Updates the information that is restored, when a player + * dies in the arena, that is, health, food level, and + * experience. Used when a player re-joins an arena while + * already being a spectator. + */ + public void update() { + this.health = player.getHealth(); + this.food = player.getFoodLevel(); + this.level = player.getLevel(); + this.exp = player.getExp(); + } + + /** + * Restores health, food level, and experience as per the + * currently stored values of this object. Used when a + * player leaves the arena. + */ + public void restoreData() { + player.setFoodLevel(food); + player.setLevel(level); + player.setExp(exp); + } + + public Player getPlayer() { + return player; + } + + public int health() { + return health; + } + + public void setHealth(int health) { + this.health = health; + } + + public int food() { + return food; + } + + public void setFood(int food) { + this.food = food; + } + + public int level() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public float exp() { + return exp; + } + + public void setExp(int exp) { + this.exp = exp; + } + + public GameMode getMode() { + return mode; + } + + public Collection getPotionEffects() { + return potions; + } + + public void setMode(GameMode mode) { + this.mode = mode; + } + + public Location entry() { + return entry; + } + + public void setEntry(Location entry) { + this.entry = entry; + } +} diff --git a/src/com/garbagemule/MobArena/RewardManager.java b/src/com/garbagemule/MobArena/RewardManager.java new file mode 100644 index 0000000..3c186d6 --- /dev/null +++ b/src/com/garbagemule/MobArena/RewardManager.java @@ -0,0 +1,63 @@ +package com.garbagemule.MobArena; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import com.garbagemule.MobArena.framework.Arena; + +public class RewardManager +{ + private MobArena plugin; + @SuppressWarnings("unused") + private Arena arena; + private Map> players; + private Set rewarded; + + public RewardManager(Arena arena) { + this.plugin = arena.getPlugin(); + this.arena = arena; + this.players = new HashMap>(); + this.rewarded = new HashSet(); + } + + public void reset() { + players.clear(); + rewarded.clear(); + } + + public void addReward(Player p, ItemStack stack) { + if (!players.containsKey(p)) { + players.put(p, new ArrayList()); + } + players.get(p).add(stack); + } + + public void grantRewards(Player p) { + if (rewarded.contains(p)) return; + + List rewards = players.get(p); + if (rewards == null) return; + + for (ItemStack stack : rewards) { + if (stack == null) { + continue; + } + + if (stack.getTypeId() == MobArena.ECONOMY_MONEY_ID) { + plugin.giveMoney(p, stack.getAmount()); + continue; + } + + p.getInventory().addItem(stack); + } + + rewarded.add(p); + } +} diff --git a/src/com/garbagemule/MobArena/commands/Command.java b/src/com/garbagemule/MobArena/commands/Command.java new file mode 100644 index 0000000..9851e53 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/Command.java @@ -0,0 +1,20 @@ +package com.garbagemule.MobArena.commands; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.framework.ArenaMaster; + +public interface Command +{ + /** + * Execute the command using the given arguments. + * If any arguments are provided, the first argument is -NOT- the + * same as the command name, i.e. the CommandHandler must strip the + * array of this element. + * @param am an ArenaMaster instance + * @param sender the sender + * @param args array of arguments + * @return true, if the command was successful + */ + public boolean execute(ArenaMaster am, CommandSender sender, String... args); +} diff --git a/src/com/garbagemule/MobArena/commands/CommandHandler.java b/src/com/garbagemule/MobArena/commands/CommandHandler.java index c3c6362..2c2fa65 100644 --- a/src/com/garbagemule/MobArena/commands/CommandHandler.java +++ b/src/com/garbagemule/MobArena/commands/CommandHandler.java @@ -1,123 +1,217 @@ package com.garbagemule.MobArena.commands; -import java.io.File; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; -import org.bukkit.command.*; -import org.bukkit.entity.Player; +import org.bukkit.ChatColor; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; import com.garbagemule.MobArena.*; -import com.garbagemule.MobArena.util.classparsing.*; +import com.garbagemule.MobArena.commands.user.*; +import com.garbagemule.MobArena.commands.admin.*; +import com.garbagemule.MobArena.commands.setup.*; +import com.garbagemule.MobArena.framework.ArenaMaster; public class CommandHandler implements CommandExecutor { - /* COMMAND_PATH is an incomplete package-name for all commands in MobArena, - * hence the trailing dot, and the COMMAND_TYPES array contains all the - * different types of commands (the sub-folders). Both are used in the - * loadCommands() method. */ - private static final String COMMAND_PATH = "com.garbagemule.MobArena.commands."; - private static final String[] COMMAND_TYPES = new String[]{"user", "admin", "setup"}; + private MobArena plugin; + private ArenaMaster am; - private MobArenaPlugin plugin; - private Map commands; + private Map commands; - public CommandHandler(MobArenaPlugin plugin) { - this.plugin = plugin; - this.commands = new HashMap(); - loadCommands(); + public CommandHandler(MobArena plugin) { + this.plugin = plugin; + this.am = plugin.getArenaMaster(); + + registerCommands(); } - + @Override - public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { - if (args.length == 0) { - plugin.tell(sender, Msg.MISC_NONE); + public boolean onCommand(CommandSender sender, org.bukkit.command.Command bcmd, String label, String[] args) { + // Grab the base and arguments. + String base = (args.length > 0 ? args[0] : ""); + String last = (args.length > 0 ? args[args.length - 1] : ""); + + // If there's no base argument, show a helpful message. + if (base.equals("")) { + Messenger.tellPlayer(sender, Msg.MISC_HELP); return true; } - // Grab the command from the map, and if null, didn't work. - MACommand command = commands.get(args[0]); - if (command == null) { - System.out.println("Command '" + label + "' not recognized"); + // The help command is a little special + if (base.equals("?") || base.equals("help")) { + showHelp(sender); return true; } - // Cast if sender is a Player, null otherwise. - Player p = (sender instanceof Player) ? (Player) sender : null; + // Get all commands that match the base. + List matches = getMatchingCommands(base); - // If null, must be console. - if (p == null) { - if (!command.executeFromConsole(plugin, sender, args)) { - sender.sendMessage("Can't use that command from the console."); + // If there's more than one match, display them. + if (matches.size() > 1) { + Messenger.tellPlayer(sender, Msg.MISC_MULTIPLE_MATCHES); + for (Command cmd : matches) { + showUsage(cmd, sender); } return true; } - // Otherwise, check permissions - if (!p.hasPermission(command.getPermission())) { - sender.sendMessage("No permission"); + // If there are no matches at all, notify. + if (matches.size() == 0) { + Messenger.tellPlayer(sender, Msg.MISC_NO_MATCHES); return true; } - // Execute! - command.execute(plugin, p, trimFirstArg(args)); + // Grab the only match. + Command command = matches.get(0); + CommandInfo info = command.getClass().getAnnotation(CommandInfo.class); + + // First check if the sender has permission. + if (!plugin.has(sender, info.permission())) { + Messenger.tellPlayer(sender, Msg.MISC_NO_ACCESS); + return true; + } + + // Check if the last argument is a ?, in which case, display usage and description + if (last.equals("?") || last.equals("help")) { + showUsage(command, sender); + return true; + } + + // Otherwise, execute the command! + String[] params = trimFirstArg(args); + command.execute(am, sender, params); return true; } /** - * Since Java doesn't support pointer arithmetic, this method - * attempts to remove the first element of a String[] object - * by creating a new array of the same size -1 and copying all - * the elements over. - * @param args a String[] to trim - * @return a String[] with the same elements except for the very first + * Get all commands that match a given string. + * @param arg the given string + * @return a list of commands whose patterns match the given string */ - private String[] trimFirstArg(String[] args) { - String[] result = new String[args.length - 1]; - for (int i = 0; i < result.length; i++) { - result[i] = args[i+1]; + private List getMatchingCommands(String arg) { + List result = new ArrayList(); + + // Grab the commands that match the argument. + for (Entry entry : commands.entrySet()) { + if (arg.matches(entry.getKey())) { + result.add(entry.getValue()); + } } + return result; } /** - * Load all of the MobArena commands from either the jar or the bin - * folder into the commands-map. Each one of a commands' names/aliases - * is added to the map, such that both "/ma join" and "/ma j" work, for - * instance. + * Show the usage and description messages of a command to a player. + * The usage will only be shown, if the player has permission for the command. + * @param cmd a Command + * @param sender a CommandSender */ - private void loadCommands() { - // Prepare a strategy for the class parser. - ClassIterationStrategy strategy = null; - File f = new File("plugins" + File.separator + "MobArena.jar"); - - try { - // If jar exists, use it - otherwise, use bin. - strategy = (f.exists()) ? new JarClassIterationStrategy(f) : - new DirClassIterationStrategy(new File("bin")); + private void showUsage(Command cmd, CommandSender sender) { + CommandInfo info = cmd.getClass().getAnnotation(CommandInfo.class); + if (!plugin.has(sender, info.permission())) return; - // Create a new ClassParser with the given strategy. - ClassParser parser = new ClassParser(strategy); - - // Iterate through all three folders, user/admin/setup - for (String type : COMMAND_TYPES) { - Collection> classes = parser.getClasses(COMMAND_PATH + type); - - for (Class c : classes) { - // Make sure the class is indeed an instance of MACommand - Object obj = c.newInstance(); - if (!(obj instanceof MACommand)) - continue; - - // Then cast, and add for each command name/alias - MACommand command = (MACommand) obj; - for (String name : command.getNames()) { - commands.put(name, command); - } - } - } - } catch (Exception e) { + Messenger.tellPlayer(sender, info.usage() + " " + ChatColor.YELLOW + info.desc()); + } + + /** + * Remove the first argument of a string. This is because the very first + * element of the arguments array will be the command itself. + * @param args an array of length n + * @return the same array minus the first element, and thus of length n-1 + */ + private String[] trimFirstArg(String[] args) { + return Arrays.copyOfRange(args, 1, args.length); + } + + /** + * List all the available MobArena commands for the CommandSender. + * @param sender a player or the console + */ + private void showHelp(CommandSender sender) { + Messenger.tellPlayer(sender, "Available MobArena commands:"); + + for (Command cmd : commands.values()) { + showUsage(cmd, sender); + } + } + + /** + * Register all the commands directly. + * This could also be done with a somewhat dirty classloader/resource reader + * method, but this is neater, albeit more manual work. + */ + private void registerCommands() { + commands = new HashMap(); + + // mobarena.use + register(ArenaListCommand.class); + register(JoinCommand.class); + register(LeaveCommand.class); + register(NotReadyCommand.class); + register(SpecCommand.class); + register(PlayerListCommand.class); + + // mobarena.admin + register(DisableCommand.class); + register(EnableCommand.class); + register(ForceCommand.class); + register(KickCommand.class); + register(RestoreCommand.class); + + // mobarena.setup + register(AddArenaCommand.class); + register(AddClassPermCommand.class); + register(AddContainerCommand.class); + register(AddSpawnpointCommand.class); + register(ArenaCommand.class); + register(CheckDataCommand.class); + register(ConfigCommand.class); + register(ContainersCommand.class); + register(EditArenaCommand.class); + register(ExpandLobbyRegionCommand.class); + register(ExpandRegionCommand.class); + register(ListClassesCommand.class); + register(ListClassPermsCommand.class); + register(ProtectCommand.class); + register(RemoveArenaCommand.class); + register(RemoveClassCommand.class); + register(RemoveClassPermCommand.class); + register(RemoveContainerCommand.class); + register(RemoveSpawnpointCommand.class); + register(SetArenaCommand.class); + register(SetClassCommand.class); + register(SetLobbyRegionCommand.class); + register(SetRegionCommand.class); + register(SetWarpCommand.class); + register(ShowRegionCommand.class); + register(SpawnpointsCommand.class); + register(AutoGenerateCommand.class); + register(AutoDegenerateCommand.class); + } + + /** + * Register a single command. + * The Command's CommandInfo annotation is queried to find its pattern + * string, which is used to map the commands. + * @param c a Command + */ + private void register(Class c) { + CommandInfo info = c.getAnnotation(CommandInfo.class); + if (info == null) return; + + try { + commands.put(info.pattern(), c.newInstance()); + } + catch (Exception e) { e.printStackTrace(); } } -} \ No newline at end of file +} diff --git a/src/com/garbagemule/MobArena/commands/CommandInfo.java b/src/com/garbagemule/MobArena/commands/CommandInfo.java new file mode 100644 index 0000000..e19a850 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/CommandInfo.java @@ -0,0 +1,33 @@ +package com.garbagemule.MobArena.commands; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface CommandInfo +{ + /** + * The actual name of the command. Not really used anywhere. + */ + public String name(); + + /** + * A regex pattern that allows minor oddities and alternatives to the command name. + */ + public String pattern(); + + /** + * The usage message, i.e. how the command should be used. + */ + public String usage(); + + /** + * A description of what the command does. + */ + public String desc(); + + /** + * The permission required to execute this command. + */ + public String permission(); +} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/commands/Commands.java b/src/com/garbagemule/MobArena/commands/Commands.java new file mode 100644 index 0000000..cfbf6a5 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/Commands.java @@ -0,0 +1,31 @@ +package com.garbagemule.MobArena.commands; + +import java.util.List; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.garbagemule.MobArena.Messenger; +import com.garbagemule.MobArena.Msg; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +public class Commands +{ + public static boolean isPlayer(CommandSender sender) { + return (sender instanceof Player); + } + + public static boolean sanityChecks(Player p, ArenaMaster am, Arena arena, String arg1, List arenas) { + if (arenas.size() > 1 && arg1.isEmpty()) + Messenger.tellPlayer(p, Msg.JOIN_ARG_NEEDED); + else if (arena == null) + Messenger.tellPlayer(p, Msg.ARENA_DOES_NOT_EXIST); + else if (am.getArenaWithPlayer(p) != null && !arena.equals(am.getArenaWithPlayer(p))) + Messenger.tellPlayer(p, Msg.JOIN_IN_OTHER_ARENA); + else + return true; + + return false; + } +} diff --git a/src/com/garbagemule/MobArena/commands/MACommand.java b/src/com/garbagemule/MobArena/commands/MACommand.java deleted file mode 100644 index b8b3400..0000000 --- a/src/com/garbagemule/MobArena/commands/MACommand.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.garbagemule.MobArena.commands; - -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import com.garbagemule.MobArena.MobArenaPlugin; - -public interface MACommand -{ - /** - * Get an array of names/aliases for this command. - * Every command must have at least one name/alias to work. - * @return a String[] of names/aliases - */ - public String[] getNames(); - - /** - * Get the permission required to execute this command. - * If there is no permission required, the method returns - * the empty string. - * @return a permission or null - */ - public String getPermission(); - - /** - * Execute the implementing command with the input Player as the executor. - * @param sender The Player executing the command - * @param args A list of arguments - * @return true, if the command was executed successfully, false otherwise - */ - public boolean execute(MobArenaPlugin plugin, Player sender, String... args); - - /** - * Execute the implementing command with the console as the executor. - * @param sender The console executing the command - * @param args A list of arguments - * @return true, if the command was executed successfully, false otherwise - */ - public boolean executeFromConsole(MobArenaPlugin plugin, CommandSender sender, String... args); -} diff --git a/src/com/garbagemule/MobArena/commands/admin/DisableCommand.java b/src/com/garbagemule/MobArena/commands/admin/DisableCommand.java new file mode 100644 index 0000000..870a006 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/admin/DisableCommand.java @@ -0,0 +1,55 @@ +package com.garbagemule.MobArena.commands.admin; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "disable", + pattern = "disable|off", + usage = "/ma disable (|all)", + desc = "disable MobArena or individual arenas", + permission = "mobarena.admin.enable" +) +public class DisableCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + if (arg1.equals("all")) { + for (Arena arena : am.getArenas()) { + disable(arena, sender); + } + return true; + } + + if (!arg1.equals("")) { + Arena arena = am.getArenaWithName(arg1); + if (arena == null) { + Messenger.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); + return false; + } + + disable(arena, sender); + return true; + } + + am.setEnabled(true); + am.saveConfig(); + Messenger.tellPlayer(sender, "MobArena " + ChatColor.RED + "disabled"); + + return true; + } + + private void disable(Arena arena, CommandSender sender) { + arena.setEnabled(false); + arena.getSettings().getParent().save(); + Messenger.tellPlayer(sender, "Arena '" + arena.configName() + "' " + ChatColor.RED + "disabled"); + } +} diff --git a/src/com/garbagemule/MobArena/commands/admin/EnableCommand.java b/src/com/garbagemule/MobArena/commands/admin/EnableCommand.java index 2d83d6c..25246dc 100644 --- a/src/com/garbagemule/MobArena/commands/admin/EnableCommand.java +++ b/src/com/garbagemule/MobArena/commands/admin/EnableCommand.java @@ -1,30 +1,55 @@ package com.garbagemule.MobArena.commands.admin; +import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; import com.garbagemule.MobArena.*; import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; -public class EnableCommand implements MACommand +@CommandInfo( + name = "enable", + pattern = "enable|on", + usage = "/ma enable", + desc = "enable MobArena or individual arenas", + permission = "mobarena.admin.enable" +) +public class EnableCommand implements Command { @Override - public String[] getNames() { - return new String[] { "enable" }; - } + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + if (arg1.equals("all")) { + for (Arena arena : am.getArenas()) { + enable(arena, sender); + } + return true; + } + + if (!arg1.equals("")) { + Arena arena = am.getArenaWithName(arg1); + if (arena == null) { + Messenger.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); + return false; + } - @Override - public String getPermission() { - return "mobarena.admin.enable"; + enable(arena, sender); + return true; + } + + am.setEnabled(true); + am.saveConfig(); + Messenger.tellPlayer(sender, "MobArena " + ChatColor.GREEN + "enabled"); + + return true; } - @Override - public boolean execute(MobArenaPlugin plugin, Player sender, String... args) { - return false; - } - - @Override - public boolean executeFromConsole(MobArenaPlugin plugin, CommandSender sender, String... args) { - return false; + private void enable(Arena arena, CommandSender sender) { + arena.setEnabled(true); + arena.getSettings().getParent().save(); + Messenger.tellPlayer(sender, "Arena '" + arena.configName() + "' " + ChatColor.GREEN + "enabled"); } } diff --git a/src/com/garbagemule/MobArena/commands/admin/ForceCommand.java b/src/com/garbagemule/MobArena/commands/admin/ForceCommand.java new file mode 100644 index 0000000..e17a219 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/admin/ForceCommand.java @@ -0,0 +1,90 @@ +package com.garbagemule.MobArena.commands.admin; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "force", + pattern = "force", + usage = "/ma force start|end ()", + desc = "force start or end an arena", + permission = "mobarena.admin.force" +) +public class ForceCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + String arg2 = (args.length > 1 ? args[1] : ""); + + if (arg1.equals("end")) { + // With no arguments, end all. + if (arg2.equals("")) { + for (Arena arena : am.getArenas()) { + arena.forceEnd(); + } + + Messenger.tellPlayer(sender, Msg.FORCE_END_ENDED); + am.resetArenaMap(); + return true; + } + + // Otherwise, grab the arena in question. + Arena arena = am.getArenaWithName(arg2); + if (arena == null) { + Messenger.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); + return false; + } + + if (arena.getAllPlayers().isEmpty()) { + Messenger.tellPlayer(sender, Msg.FORCE_END_EMPTY); + return false; + } + + // And end it! + arena.forceEnd(); + Messenger.tellPlayer(sender, Msg.FORCE_END_ENDED); + + return true; + } + + if (arg1.equals("start")) { + // Require argument. + if (arg2.equals("")) { + Messenger.tellPlayer(sender, "Usage: /ma force start "); + return false; + } + + // Grab the arena. + Arena arena = am.getArenaWithName(arg2); + if (arena == null) { + Messenger.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); + return false; + } + + if (arena.isRunning()) { + Messenger.tellPlayer(sender, Msg.FORCE_START_RUNNING); + return false; + } + + if (arena.getReadyPlayersInLobby().isEmpty()) { + Messenger.tellPlayer(sender, Msg.FORCE_START_NOT_READY); + return false; + } + + // And start it! + arena.forceStart(); + Messenger.tellPlayer(sender, Msg.FORCE_START_STARTED); + + return true; + } + + Messenger.tellPlayer(sender, "Usage: /ma force start|end ()"); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/admin/KickCommand.java b/src/com/garbagemule/MobArena/commands/admin/KickCommand.java new file mode 100644 index 0000000..14b415d --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/admin/KickCommand.java @@ -0,0 +1,47 @@ +package com.garbagemule.MobArena.commands.admin; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "kick", + pattern = "kick|kcik", + usage = "/ma kick ", + desc = "kick a player from an arena", + permission = "mobarena.admin.kick" +) +public class KickCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Require an argument + if (arg1.equals("")) { + Messenger.tellPlayer(sender, "Usage: /ma kick "); + return false; + } + + Arena arena = am.getArenaWithPlayer(arg1); + if (arena == null) { + Messenger.tellPlayer(sender, "That player is not in an arena."); + return false; + } + + // Grab the Player object. + Player bp = am.getPlugin().getServer().getPlayer(arg1); + + // Force leave. + arena.playerLeave(bp); + + Messenger.tellPlayer(sender, "Player '" + arg1 + "' was kicked from arena '" + arena.configName() + "'."); + Messenger.tellPlayer(bp, "You were kicked by " + sender.getName() + "."); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/admin/RestoreCommand.java b/src/com/garbagemule/MobArena/commands/admin/RestoreCommand.java new file mode 100644 index 0000000..def673e --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/admin/RestoreCommand.java @@ -0,0 +1,43 @@ +package com.garbagemule.MobArena.commands.admin; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; +import com.garbagemule.MobArena.util.inventory.InventoryManager; + +@CommandInfo( + name = "restore", + pattern = "restore", + usage = "/ma restore ", + desc = "restore a player's inventory", + permission = "mobarena.admin.restore" +) +public class RestoreCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Require an argument + if (arg1.equals("")) { + Messenger.tellPlayer(sender, "Usage: /ma restore "); + return false; + } + + if (am.getArenaWithPlayer(arg1) != null) { + Messenger.tellPlayer(sender, "Player is currently in an arena."); + return false; + } + + if (InventoryManager.restoreFromFile(am.getPlugin(), am.getPlugin().getServer().getPlayer(arg1))) { + Messenger.tellPlayer(sender, "Restored " + arg1 + "'s inventory!"); + } else { + Messenger.tellPlayer(sender, "Failed to restore " + arg1 + "'s inventory."); + } + + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/AddArenaCommand.java b/src/com/garbagemule/MobArena/commands/setup/AddArenaCommand.java new file mode 100644 index 0000000..0743406 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/AddArenaCommand.java @@ -0,0 +1,51 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "addarena", + pattern = "(add|new)arena", + usage = "/ma addarena ", + desc = "add a new arena", + permission = "mobarena.setup.addarena" +) +public class AddArenaCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + if (!Commands.isPlayer(sender)) { + Messenger.tellPlayer(sender, Msg.MISC_NOT_FROM_CONSOLE); + return false; + } + + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Cast the sender. + Player p = (Player) sender; + + // Require an argument + if (arg1.equals("")) { + Messenger.tellPlayer(sender, "Usage: /ma addarena "); + return true; + } + + Arena arena = am.getArenaWithName(arg1); + if (arena != null) { + Messenger.tellPlayer(sender, "An arena with that name already exists."); + return true; + } + + arena = am.createArenaNode(arg1, p.getWorld()); + am.setSelectedArena(arena); + + Messenger.tellPlayer(sender, "New arena with name '" + arg1 + "' created!"); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/AddClassPermCommand.java b/src/com/garbagemule/MobArena/commands/setup/AddClassPermCommand.java new file mode 100644 index 0000000..f4ecd4e --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/AddClassPermCommand.java @@ -0,0 +1,47 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; +import com.garbagemule.MobArena.util.TextUtils; + +@CommandInfo( + name = "addclassperm", + pattern = "add(class)?perm(.*)", + usage = "/ma addclassperm ", + desc = "add a per-class permission", + permission = "mobarena.setup.classes" +) +public class AddClassPermCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + String arg2 = (args.length > 1 ? args[1] : ""); + + if (arg1.equals("") || arg2.equals("")) { + Messenger.tellPlayer(sender, "Usage: /ma addclassperm "); + return false; + } + + // Grab the arena class + ArenaClass arenaClass = am.getClasses().get(arg1); + if (arenaClass == null) { + Messenger.tellPlayer(sender, "The class '" + TextUtils.camelCase(arg1) + "' does not exist."); + return false; + } + + // Try to add the permission. + if (am.addClassPermission(arg1, arg2)) { + Messenger.tellPlayer(sender, "Added permission '" + arg2 + "' to class '" + TextUtils.camelCase(arg1) + "'."); + return true; + } + + // If it wasn't added, notify. + Messenger.tellPlayer(sender, "Permission '" + arg2 + "' was NOT added to class '" + TextUtils.camelCase(arg1) + "'."); + return false; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/AddContainerCommand.java b/src/com/garbagemule/MobArena/commands/setup/AddContainerCommand.java new file mode 100644 index 0000000..dd586fa --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/AddContainerCommand.java @@ -0,0 +1,47 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.block.ContainerBlock; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "addcontainer", + pattern = "add(chest|container)", + usage = "/ma addcontainer ", + desc = "add a new container for the selected arena", + permission = "mobarena.setup.containers" +) +public class AddContainerCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + if (!Commands.isPlayer(sender)) { + Messenger.tellPlayer(sender, Msg.MISC_NOT_FROM_CONSOLE); + return false; + } + + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Cast the sender. + Player p = (Player) sender; + + if (!arg1.matches("^[a-zA-Z][a-zA-Z0-9]*$")) { + Messenger.tellPlayer(sender, "Usage: /ma addcontainer "); + return false; + } + + if (!(p.getTargetBlock(null, 50).getState() instanceof ContainerBlock)) { + Messenger.tellPlayer(sender, "You must look at container."); + return false; + } + + am.getSelectedArena().getRegion().addChest(arg1, p.getTargetBlock(null, 50).getLocation()); + Messenger.tellPlayer(sender, "Container '" + arg1 + "' added for arena \"" + am.getSelectedArena().configName() + "\""); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/AddSpawnpointCommand.java b/src/com/garbagemule/MobArena/commands/setup/AddSpawnpointCommand.java new file mode 100644 index 0000000..d771207 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/AddSpawnpointCommand.java @@ -0,0 +1,41 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "addspawn", + pattern = "addspawn(point)?", + usage = "/ma addspawn ", + desc = "add a new spawnpoint for the selected arena", + permission = "mobarena.setup.spawnpoints" +) +public class AddSpawnpointCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + if (!Commands.isPlayer(sender)) { + Messenger.tellPlayer(sender, Msg.MISC_NOT_FROM_CONSOLE); + return false; + } + + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Cast the sender. + Player p = (Player) sender; + + if (!arg1.matches("^[a-zA-Z][a-zA-Z0-9]*$")) { + Messenger.tellPlayer(sender, "Usage: /ma addspawn "); + return true; + } + + am.getSelectedArena().getRegion().addSpawn(arg1, p.getLocation()); + Messenger.tellPlayer(sender, "Spawnpoint " + arg1 + " added for arena \"" + am.getSelectedArena().configName() + "\""); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/ArenaCommand.java b/src/com/garbagemule/MobArena/commands/setup/ArenaCommand.java new file mode 100644 index 0000000..c7c5d41 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/ArenaCommand.java @@ -0,0 +1,37 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "arena", + pattern = "arena", + usage = "/ma arena", + desc = "list the currently selected arena", + permission = "mobarena.setup.arena" +) +public class ArenaCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + Messenger.tellPlayer(sender, "Currently selected arena: " + ChatColor.GREEN + am.getSelectedArena().configName()); + + StringBuffer buffy = new StringBuffer(); + if (am.getArenas().size() > 1) { + for (Arena arena : am.getArenas()) { + if (!arena.equals(am.getSelectedArena())) { + buffy.append(arena.configName() + " "); + } + } + } + else buffy.append(Msg.MISC_NONE); + + Messenger.tellPlayer(sender, "Other arenas: " + buffy.toString()); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/AutoDegenerateCommand.java b/src/com/garbagemule/MobArena/commands/setup/AutoDegenerateCommand.java new file mode 100644 index 0000000..dcb5f68 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/AutoDegenerateCommand.java @@ -0,0 +1,50 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "autodegenerate", + pattern = "auto(\\-)?degenerate", + usage = "/ma autodegenerate ", + desc = "autodegenerate an existing arena", + permission = "mobarena.setup.autodegenerate" +) +public class AutoDegenerateCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the arguments, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Require an argument + if (arg1.equals("")) { + Messenger.tellPlayer(sender, "Usage: /ma autodegenerate "); + return true; + } + + if (am.getArenas().size() < 2) { + Messenger.tellPlayer(sender, "At least one arena must exist!"); + return true; + } + + // Check if arena exists. + Arena arena = am.getArenaWithName(arg1); + if (arena == null) { + Messenger.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); + return true; + } + + if (!MAUtils.undoItHippieMonster(arg1, am.getPlugin(), true)) { + Messenger.tellPlayer(sender, "Could not degenerate arena."); + return true; + } + + Messenger.tellPlayer(sender, "Arena with name '" + arg1 + "' degenerated."); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/AutoGenerateCommand.java b/src/com/garbagemule/MobArena/commands/setup/AutoGenerateCommand.java new file mode 100644 index 0000000..0f4347f --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/AutoGenerateCommand.java @@ -0,0 +1,54 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "autogenerate", + pattern = "auto(\\-)?generate", + usage = "/ma autogenerate ", + desc = "autogenerate a new arena", + permission = "mobarena.setup.autogenerate" +) +public class AutoGenerateCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + if (!Commands.isPlayer(sender)) { + Messenger.tellPlayer(sender, Msg.MISC_NOT_FROM_CONSOLE); + return false; + } + + // Grab the arguments, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Cast the sender. + Player p = (Player) sender; + + // Require an argument + if (arg1.equals("")) { + Messenger.tellPlayer(sender, "Usage: /ma autogenerate "); + return true; + } + + // Check if arena already exists. + Arena arena = am.getArenaWithName(arg1); + if (arena != null) { + Messenger.tellPlayer(sender, "An arena with that name already exists."); + return true; + } + + if (!MAUtils.doooooItHippieMonster(p.getLocation(), 13, arg1, am.getPlugin())) { + Messenger.tellPlayer(sender, "Could not auto-generate arena."); + return true; + } + + Messenger.tellPlayer(sender, "Arena with name '" + arg1 + "' generated."); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/CheckDataCommand.java b/src/com/garbagemule/MobArena/commands/setup/CheckDataCommand.java new file mode 100644 index 0000000..14bab08 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/CheckDataCommand.java @@ -0,0 +1,33 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "checkdata", + pattern = "checkdata", + usage = "/ma checkdata", + desc = "check if all required points are set up", + permission = "mobarena.setup.checkdata" +) +public class CheckDataCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + Arena arena = arg1.equals("") ? am.getSelectedArena() : am.getArenaWithName(arg1); + if (arena == null) { + Messenger.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); + return false; + } + + arena.getRegion().checkData(am.getPlugin(), sender); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/ConfigCommand.java b/src/com/garbagemule/MobArena/commands/setup/ConfigCommand.java new file mode 100644 index 0000000..a604b35 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/ConfigCommand.java @@ -0,0 +1,39 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "config", + pattern = "config|cfg", + usage = "/ma config reload|save", + desc = "reload or save the config-file", + permission = "mobarena.setup.config" +) +public class ConfigCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + if (arg1.equals("reload")) { + am.reloadConfig(); + Messenger.tellPlayer(sender, "Config reloaded."); + return true; + } + + if (arg1.equals("save")) { + am.saveConfig(); + Messenger.tellPlayer(sender, "Config saved."); + return true; + } + + // Requires an argument. + Messenger.tellPlayer(sender, "Usage: /ma config reload|save"); + return false; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/ContainersCommand.java b/src/com/garbagemule/MobArena/commands/setup/ContainersCommand.java new file mode 100644 index 0000000..c5f4fba --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/ContainersCommand.java @@ -0,0 +1,38 @@ +package com.garbagemule.MobArena.commands.setup; + +import java.util.Set; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "containers", + pattern = "(containers|chests)", + usage = "/ma containers", + desc = "list containers for the selected arena", + permission = "mobarena.setup.containers" +) +public class ContainersCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + StringBuffer buffy = new StringBuffer(); + Set containers = am.getPlugin().getMAConfig().getKeys("arenas." + am.getSelectedArena().configName() + ".coords.containers"); + + if (containers != null) { + for (String c : containers) { + buffy.append(c); + buffy.append(" "); + } + } + else { + buffy.append(Msg.MISC_NONE); + } + + Messenger.tellPlayer(sender, "Containers for arena '" + am.getSelectedArena().configName() + "': " + buffy.toString()); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/EditArenaCommand.java b/src/com/garbagemule/MobArena/commands/setup/EditArenaCommand.java new file mode 100644 index 0000000..3c3c109 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/EditArenaCommand.java @@ -0,0 +1,75 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "editarena", + pattern = "edit(arena)?", + usage = "/ma editarena () (true|false)", + desc = "set edit mode of an arena", + permission = "mobarena.setup.editarena" +) +public class EditArenaCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + String arg2 = (args.length > 1 ? args[1] : ""); + + Arena arena; + + // No arguments. + if (arg1.equals("")) { + arena = am.getSelectedArena(); + arena.setEditMode(!arena.inEditMode()); + } + + // One argument. + else if (arg2.equals("")) { + // Argument is [true|false] + if (arg1.matches("true|on") || arg1.matches("false|off")) { + arena = am.getSelectedArena(); + arena.setEditMode(arg1.equals("true")); + } + // Argument is + else { + arena = am.getArenaWithName(arg1); + if (arena == null) { + Messenger.tellPlayer(sender, "There is no arena with that name."); + Messenger.tellPlayer(sender, "Usage: /ma editarena (true|false)"); + Messenger.tellPlayer(sender, " or /ma editarena (true|false)"); + return true; + } + arena.setEditMode(!arena.inEditMode()); + } + } + + // Two arguments + else { + if (!(arg2.matches("true|on") || arg2.matches("false|off"))) { + Messenger.tellPlayer(sender, "Usage: /ma editarena (true|false)"); + Messenger.tellPlayer(sender, " or /ma editarena (true|false)"); + return true; + } + arena = am.getArenaWithName(arg1); + if (arena == null) { + Messenger.tellPlayer(sender, "There is no arena with that name."); + Messenger.tellPlayer(sender, "Usage: /ma editarena (true|false)"); + Messenger.tellPlayer(sender, " or /ma editarena (true|false)"); + return true; + } + arena.setEditMode(arg2.equals("true")); + } + + Messenger.tellPlayer(sender, "Edit mode for arena '" + arena.configName() + "': " + ((arena.inEditMode()) ? ChatColor.GREEN + "true" : ChatColor.RED + "false")); + if (arena.inEditMode()) Messenger.tellPlayer(sender, "Remember to turn it back off after editing!"); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/ExpandLobbyRegionCommand.java b/src/com/garbagemule/MobArena/commands/setup/ExpandLobbyRegionCommand.java new file mode 100644 index 0000000..24804dd --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/ExpandLobbyRegionCommand.java @@ -0,0 +1,56 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "expandlobbyregion", + pattern = "expandlobby(region)?", + usage = "/ma expandlobbyregion up|down|out", + desc = "expand the arena lobby region", + permission = "mobarena.setup.expandlobbyregion" +) +public class ExpandLobbyRegionCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + String arg2 = (args.length > 1 ? args[1] : ""); + + if (args.length != 2 || !arg1.matches("(-)?[0-9]+")) { + Messenger.tellPlayer(sender, "Usage: /ma expandlobbyregion up|down|out"); + return false; + } + + if (!am.getSelectedArena().getRegion().isLobbyDefined()) { + Messenger.tellPlayer(sender, "You must first define l1 and l2"); + return true; + } + + if (arg2.equals("up")) { + am.getSelectedArena().getRegion().expandLobbyUp(Integer.parseInt(arg1)); + } + else if (arg2.equals("down")) { + am.getSelectedArena().getRegion().expandLobbyDown(Integer.parseInt(arg1)); + } + else if (arg2.equals("out")) { + am.getSelectedArena().getRegion().expandLobbyOut(Integer.parseInt(arg1)); + } + else { + Messenger.tellPlayer(sender, "Usage: /ma expandlobbyregion up|down|out"); + return true; + } + + // In case of a "negative" region, fix it! + am.getSelectedArena().getRegion().fixRegion(); + + Messenger.tellPlayer(sender, "Lobby region for '" + am.getSelectedArena().configName() + "' expanded " + arg2 + " by " + arg1 + " blocks."); + am.getSelectedArena().getRegion().save(); + + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/ExpandRegionCommand.java b/src/com/garbagemule/MobArena/commands/setup/ExpandRegionCommand.java new file mode 100644 index 0000000..2a17c6a --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/ExpandRegionCommand.java @@ -0,0 +1,56 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "expandregion", + pattern = "expand(region)?", + usage = "/ma expandregion up|down|out", + desc = "expand the arena region", + permission = "mobarena.setup.expandregion" +) +public class ExpandRegionCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + String arg2 = (args.length > 1 ? args[1] : ""); + + if (args.length != 2 || !arg1.matches("(-)?[0-9]+")) { + Messenger.tellPlayer(sender, "Usage: /ma expandregion up|down|out"); + return false; + } + + if (!am.getSelectedArena().getRegion().isDefined()) { + Messenger.tellPlayer(sender, "You must first define p1 and p2"); + return true; + } + + if (arg2.equals("up")) { + am.getSelectedArena().getRegion().expandUp(Integer.parseInt(arg1)); + } + else if (arg2.equals("down")) { + am.getSelectedArena().getRegion().expandDown(Integer.parseInt(arg1)); + } + else if (arg2.equals("out")) { + am.getSelectedArena().getRegion().expandOut(Integer.parseInt(arg1)); + } + else { + Messenger.tellPlayer(sender, "Usage: /ma expandregion up|down|out"); + return true; + } + + // In case of a "negative" region, fix it! + am.getSelectedArena().getRegion().fixRegion(); + + Messenger.tellPlayer(sender, "Region for '" + am.getSelectedArena().configName() + "' expanded " + arg2 + " by " + arg1 + " blocks."); + am.getSelectedArena().getRegion().save(); + + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/ListClassPermsCommand.java b/src/com/garbagemule/MobArena/commands/setup/ListClassPermsCommand.java new file mode 100644 index 0000000..466a043 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/ListClassPermsCommand.java @@ -0,0 +1,57 @@ +package com.garbagemule.MobArena.commands.setup; + +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; +import com.garbagemule.MobArena.util.TextUtils; + +@CommandInfo( + name = "listclassperms", + pattern = "(list)?classperm(.*)s", + usage = "/ma listclassperms ", + desc = "list per-class permissions", + permission = "mobarena.setup.classes" +) +public class ListClassPermsCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Require an argument. + if (arg1.equals("")) { + Messenger.tellPlayer(sender, "Usage: /ma listclassperms "); + return true; + } + + ArenaClass arenaClass = am.getClasses().get(arg1); + String className = TextUtils.camelCase(arg1); + + if (arenaClass == null) { + Messenger.tellPlayer(sender, "The class '" + className + "' does not exist."); + return true; + } + + Messenger.tellPlayer(sender, "Permissions for '" + className + "':"); + Map perms = arenaClass.getPermissions(); + if (perms.isEmpty()) { + Messenger.tellPlayer(sender, ""); + return true; + } + + for (Entry entry : arenaClass.getPermissions().entrySet()) { + String perm = entry.getKey(); + if (!entry.getValue()) { + perm = "^" + perm; + } + Messenger.tellPlayer(sender, "- " + perm); + } + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/ListClassesCommand.java b/src/com/garbagemule/MobArena/commands/setup/ListClassesCommand.java new file mode 100644 index 0000000..fc08fc0 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/ListClassesCommand.java @@ -0,0 +1,34 @@ +package com.garbagemule.MobArena.commands.setup; + +import java.util.Set; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "listclasses", + pattern = "(list)?class(.)*", + usage = "/ma listclasses", + desc = "list all current classes", + permission = "mobarena.setup.classes" +) +public class ListClassesCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + Messenger.tellPlayer(sender, "Current classes:"); + Set classes = am.getClasses().keySet(); + if (classes == null || classes.isEmpty()) { + Messenger.tellPlayer(sender, ""); + return true; + } + + for (String c : classes) { + Messenger.tellPlayer(sender, "- " + c); + } + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/ProtectCommand.java b/src/com/garbagemule/MobArena/commands/setup/ProtectCommand.java new file mode 100644 index 0000000..4770e59 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/ProtectCommand.java @@ -0,0 +1,75 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.ChatColor; +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "protect", + pattern = "protect", + usage = "/ma protect () (true|false)", + desc = "set the protection of an arena", + permission = "mobarena.setup.protect" +) +public class ProtectCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + String arg2 = (args.length > 1 ? args[1] : ""); + + Arena arena; + + // No arguments + if (arg1.equals("")) { + arena = am.getSelectedArena(); + arena.setProtected(!arena.isProtected()); + } + + // One argument + else if (arg2.equals("")) { + // true/false + if (arg1.matches("true|on") || arg1.matches("false|off")) { + arena = am.getSelectedArena(); + arena.setProtected(arg1.matches("true|on")); + } + // Arena name + else { + arena = am.getArenaWithName(arg1); + if (arena == null) { + Messenger.tellPlayer(sender, "There is no arena with that name."); + Messenger.tellPlayer(sender, "Usage: /ma protect (true|false)"); + Messenger.tellPlayer(sender, " or /ma protect (true|false)"); + return true; + } + arena.setProtected(!arena.isProtected()); + } + } + + // Two arguments + else { + if (!(arg2.matches("true|on") || arg2.matches("false|off"))) { + Messenger.tellPlayer(sender, "Usage: /ma protect (true|false)"); + Messenger.tellPlayer(sender, " or /ma protect (true|false)"); + return true; + } + arena = am.getArenaWithName(arg1); + if (arena == null) { + Messenger.tellPlayer(sender, "There is no arena with that name."); + Messenger.tellPlayer(sender, "Usage: /ma protect (true|false)"); + Messenger.tellPlayer(sender, " or /ma protect (true|false)"); + return true; + } + arena.setProtected(arg2.equals("true")); + } + + arena.getSettings().getParent().save(); + Messenger.tellPlayer(sender, "Protection for arena '" + arena.configName() + "': " + ((arena.isProtected()) ? ChatColor.GREEN + "on" : ChatColor.RED + "off")); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/RemoveArenaCommand.java b/src/com/garbagemule/MobArena/commands/setup/RemoveArenaCommand.java new file mode 100644 index 0000000..532459f --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/RemoveArenaCommand.java @@ -0,0 +1,50 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "removearena", + pattern = "(del(.)*|r(e)?m(ove)?)arena", + usage = "/ma removearena ", + desc = "remove an arena", + permission = "mobarena.setup.removearena" +) +public class RemoveArenaCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Require an argument + if (arg1.equals("")) { + Messenger.tellPlayer(sender, "Usage: /ma removearena "); + return false; + } + + if (am.getArenas().size() == 1) { + Messenger.tellPlayer(sender, "At least one arena must exist."); + return false; + } + + Arena arena = am.getArenaWithName(arg1); + if (arena == null) { + Messenger.tellPlayer(sender, "There is no arena with that name."); + return false; + } + + am.removeArenaNode(arena); + + if (am.getSelectedArena().equals(arena)) { + am.setSelectedArena(am.getArenas().get(0)); + } + + Messenger.tellPlayer(sender, "Arena '" + arena.configName() + "' deleted."); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/RemoveClassCommand.java b/src/com/garbagemule/MobArena/commands/setup/RemoveClassCommand.java new file mode 100644 index 0000000..0a42a1d --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/RemoveClassCommand.java @@ -0,0 +1,42 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; +import com.garbagemule.MobArena.util.TextUtils; + +@CommandInfo( + name = "removeclass", + pattern = "(del(.)*|r(e)?m(ove)?)class", + usage = "/ma removeclass ", + desc = "remove the given class", + permission = "mobarena.setup.classes" +) +public class RemoveClassCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Require an argument. + if (arg1.equals("")) { + Messenger.tellPlayer(sender, "Usage: /ma removeclass "); + return false; + } + + // Find the class + ArenaClass arenaClass = am.getClasses().get(arg1); + String className = TextUtils.camelCase(arg1); + if (arenaClass == null) { + Messenger.tellPlayer(sender, "The class '" + className + "' does not exist."); + return false; + } + + am.removeClassNode(className); + Messenger.tellPlayer(sender, "Removed class '" + className + "'."); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/RemoveClassPermCommand.java b/src/com/garbagemule/MobArena/commands/setup/RemoveClassPermCommand.java new file mode 100644 index 0000000..2e046c6 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/RemoveClassPermCommand.java @@ -0,0 +1,47 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; +import com.garbagemule.MobArena.util.TextUtils; + +@CommandInfo( + name = "removeclassperm", + pattern = "(del(.)*|r(e)?m(ove)?)(class)?perm(.*)", + usage = "/ma removeclassperm ", + desc = "remove a per-class permission", + permission = "mobarena.setup.classes" +) +public class RemoveClassPermCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + String arg2 = (args.length > 1 ? args[1] : ""); + + if (arg1.equals("") || arg2.equals("")) { + Messenger.tellPlayer(sender, "Usage: /ma removeclassperm "); + return false; + } + + // Grab the arena class + ArenaClass arenaClass = am.getClasses().get(arg1); + if (arenaClass == null) { + Messenger.tellPlayer(sender, "The class '" + TextUtils.camelCase(arg1) + "' does not exist."); + return false; + } + + // Remove the permission. + if (am.removeClassPermission(arg1, arg2)) { + Messenger.tellPlayer(sender, "Removed permission '" + arg2 + "' from class '" + TextUtils.camelCase(arg1) + "'."); + return true; + } + + // If it wasn't removed, notify. + Messenger.tellPlayer(sender, "Permission '" + arg2 + "' was NOT removed from class '" + TextUtils.camelCase(arg1) + "'."); + return false; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/RemoveContainerCommand.java b/src/com/garbagemule/MobArena/commands/setup/RemoveContainerCommand.java new file mode 100644 index 0000000..f5508b2 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/RemoveContainerCommand.java @@ -0,0 +1,35 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "removecontainer", + pattern = "(del(.)*|r(e)?m(ove)?)(container|chest)", + usage = "/ma removecontainer ", + desc = "remove a container from the selected arena", + permission = "mobarena.setup.containers" +) +public class RemoveContainerCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Require an argument + if (!arg1.matches("^[a-zA-Z][a-zA-Z0-9]*$")) { + Messenger.tellPlayer(sender, "Usage: /ma removecontainer "); + return false; + } + + if (am.getSelectedArena().getRegion().removeSpawn(arg1)) + Messenger.tellPlayer(sender, "Container " + arg1 + " removed for arena '" + am.getSelectedArena().configName() + "'"); + else + Messenger.tellPlayer(sender, "Could not find the container " + arg1 + "for the arena '" + am.getSelectedArena().configName() + "'"); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/RemoveSpawnpointCommand.java b/src/com/garbagemule/MobArena/commands/setup/RemoveSpawnpointCommand.java new file mode 100644 index 0000000..6ad5261 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/RemoveSpawnpointCommand.java @@ -0,0 +1,35 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "delspawn", + pattern = "(del(.)*|r(e)?m(ove)?)spawn(point)?", + usage = "/ma delspawn ", + desc = "add a new arena", + permission = "mobarena.setup.spawnpoints" +) +public class RemoveSpawnpointCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Require an argument + if (!arg1.matches("^[a-zA-Z][a-zA-Z0-9]*$")) { + Messenger.tellPlayer(sender, "Usage: /ma removespawn "); + return true; + } + + if (am.getSelectedArena().getRegion().removeSpawn(arg1)) + Messenger.tellPlayer(sender, "Spawnpoint " + arg1 + " removed for arena '" + am.getSelectedArena().configName() + "'"); + else + Messenger.tellPlayer(sender, "Could not find the spawnpoint " + arg1 + "for the arena '" + am.getSelectedArena().configName() + "'"); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/SetArenaCommand.java b/src/com/garbagemule/MobArena/commands/setup/SetArenaCommand.java new file mode 100644 index 0000000..2f131e3 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/SetArenaCommand.java @@ -0,0 +1,41 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "setarena", + pattern = "(set|select)arena", + usage = "/ma setarena ", + desc = "set an arena as the selected arena", + permission = "mobarena.setup.setarena" +) +public class SetArenaCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Require an argument + if (arg1.equals("")) { + Messenger.tellPlayer(sender, "Usage: /ma setarena "); + return false; + } + + Arena arena = am.getArenaWithName(arg1); + if (arena != null) { + am.setSelectedArena(arena); + Messenger.tellPlayer(sender, "Currently selected arena: " + arena.configName()); + } + else { + Messenger.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); + } + + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/SetClassCommand.java b/src/com/garbagemule/MobArena/commands/setup/SetClassCommand.java new file mode 100644 index 0000000..fe54050 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/SetClassCommand.java @@ -0,0 +1,65 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; +import com.garbagemule.MobArena.util.TextUtils; + +@CommandInfo( + name = "setclass", + pattern = "setclass|saveclass", + usage = "/ma setclass (safe) ", + desc = "save your inventory as a class", + permission = "mobarena.setup.classes" +) +public class SetClassCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + if (!Commands.isPlayer(sender)) { + Messenger.tellPlayer(sender, Msg.MISC_NOT_FROM_CONSOLE); + return false; + } + + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + String arg2 = (args.length > 1 ? args[1] : ""); + + // Cast the sender. + Player p = (Player) sender; + + // Require an argument. + if (arg1.equals("")) { + Messenger.tellPlayer(p, "Usage: /ma setclass (safe) "); + return true; + } + + // Check if we're overwriting. + boolean safe = arg1.equals("safe"); + + if (safe && arg2.equals("")) { + Messenger.tellPlayer(p, "Usage: /ma setclass (safe) "); + return true; + } + + // If so, use arg2, otherwise, use arg1 + String className = TextUtils.camelCase(safe ? arg2 : arg1); + + // Create the class. + ArenaClass arenaClass = am.createClassNode(className, p.getInventory(), safe); + + // If the class is null, it was not created. + if (arenaClass == null) { + Messenger.tellPlayer(p, "That class already exists!"); + Messenger.tellPlayer(p, "To overwrite, omit the 'safe' parameter."); + return true; + } + + // Otherwise, yay! + Messenger.tellPlayer(p, "Class '" + className + "' set with your current inventory."); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/SetLobbyRegionCommand.java b/src/com/garbagemule/MobArena/commands/setup/SetLobbyRegionCommand.java new file mode 100644 index 0000000..a7880be --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/SetLobbyRegionCommand.java @@ -0,0 +1,41 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "setlobbyregion", + pattern = "set(lobbyregion|l)", + usage = "/ma setlobbyregion l1|l2", + desc = "set the lobby region points of an arena", + permission = "mobarena.setup.setlobbyregion" +) +public class SetLobbyRegionCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + if (!Commands.isPlayer(sender)) { + Messenger.tellPlayer(sender, Msg.MISC_NOT_FROM_CONSOLE); + return false; + } + + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Cast the sender. + Player p = (Player) sender; + + if (!(arg1.equals("l1") || arg1.equals("l2"))) { + Messenger.tellPlayer(sender, "Usage: /ma setlobbyregion l1|l2"); + return true; + } + + am.getSelectedArena().getRegion().set(arg1, p.getLocation()); + Messenger.tellPlayer(sender, "Lobby region point " + arg1 + " for arena '" + am.getSelectedArena().configName() + "' set."); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/SetRegionCommand.java b/src/com/garbagemule/MobArena/commands/setup/SetRegionCommand.java index 32e77e6..8ab70cb 100644 --- a/src/com/garbagemule/MobArena/commands/setup/SetRegionCommand.java +++ b/src/com/garbagemule/MobArena/commands/setup/SetRegionCommand.java @@ -2,28 +2,40 @@ package com.garbagemule.MobArena.commands.setup; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import com.garbagemule.MobArena.commands.*; -import com.garbagemule.MobArena.*; -public class SetRegionCommand implements MACommand +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "setregion", + pattern = "set(region|p)", + usage = "/ma setregion p1|p2", + desc = "set the region points of an arena", + permission = "mobarena.setup.setregion" +) +public class SetRegionCommand implements Command { @Override - public String[] getNames() { - return new String[] { "setregion" }; - } - - @Override - public String getPermission() { - return "mobarena.setup.setregion"; - } - - @Override - public boolean execute(MobArenaPlugin plugin, Player sender, String... args) { - return false; - } - - @Override - public boolean executeFromConsole(MobArenaPlugin plugin, CommandSender sender, String... args) { - return false; + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + if (!Commands.isPlayer(sender)) { + Messenger.tellPlayer(sender, Msg.MISC_NOT_FROM_CONSOLE); + return false; + } + + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Cast the sender. + Player p = (Player) sender; + + if (!(arg1.equals("p1") || arg1.equals("p2"))) { + Messenger.tellPlayer(sender, "Usage: /ma setregion p1|p2"); + return true; + } + + am.getSelectedArena().getRegion().set(arg1, p.getLocation()); + Messenger.tellPlayer(sender, "Region point " + arg1 + " for arena '" + am.getSelectedArena().configName() + "' set."); + return true; } } diff --git a/src/com/garbagemule/MobArena/commands/setup/SetWarpCommand.java b/src/com/garbagemule/MobArena/commands/setup/SetWarpCommand.java new file mode 100644 index 0000000..49933bd --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/SetWarpCommand.java @@ -0,0 +1,42 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "setwarp", + pattern = "set(warp|point)", + usage = "/ma setwarp arena|lobby|spectator", + desc = "set a warp point for an arena", + permission = "mobarena.setup.setwarp" +) +public class SetWarpCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + if (!Commands.isPlayer(sender)) { + Messenger.tellPlayer(sender, Msg.MISC_NOT_FROM_CONSOLE); + return false; + } + + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Cast the sender. + Player p = (Player) sender; + + if (!(arg1.equals("arena") || arg1.equals("lobby") || arg1.equals("spectator"))) { + Messenger.tellPlayer(sender, "Usage: /ma setwarp arena|lobby|spectator"); + return true; + } + + am.getSelectedArena().getRegion().set(arg1, p.getLocation()); + Messenger.tellPlayer(sender, "Warp point " + arg1 + " was set for arena '" + am.getSelectedArena().configName() + "'"); + Messenger.tellPlayer(sender, "Type /ma checkdata to see if you're missing anything..."); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/ShowRegionCommand.java b/src/com/garbagemule/MobArena/commands/setup/ShowRegionCommand.java new file mode 100644 index 0000000..74c2fb0 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/ShowRegionCommand.java @@ -0,0 +1,59 @@ +package com.garbagemule.MobArena.commands.setup; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "showregion", + pattern = "show(region)?", + usage = "/ma showregion ()", + desc = "show an arena region", + permission = "mobarena.setup.showregion" +) +public class ShowRegionCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + if (!Commands.isPlayer(sender)) { + Messenger.tellPlayer(sender, Msg.MISC_NOT_FROM_CONSOLE); + return false; + } + + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Cast the sender. + Player p = (Player) sender; + + Arena arena; + + if (arg1.equals("")) { + arena = am.getArenaAtLocation(p.getLocation()); + if (arena == null) { + arena = am.getSelectedArena(); + } + + if (!arena.getRegion().isDefined()) { + Messenger.tellPlayer(sender, "The region is not defined for the selected arena."); + return false; + } + } + else { + arena = am.getArenaWithName(arg1); + + if (arena == null) { + Messenger.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); + return false; + } + } + + arena.getRegion().showRegion(p); + + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/setup/SpawnpointsCommand.java b/src/com/garbagemule/MobArena/commands/setup/SpawnpointsCommand.java new file mode 100644 index 0000000..fc5e5c6 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/setup/SpawnpointsCommand.java @@ -0,0 +1,38 @@ +package com.garbagemule.MobArena.commands.setup; + +import java.util.Set; + +import org.bukkit.command.CommandSender; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "spawnpoints", + pattern = "spawn(point)?s", + usage = "/ma spawnpoints", + desc = "list spawnpoints for the selected arena", + permission = "mobarena.setup.spawnpoints" +) +public class SpawnpointsCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + StringBuffer buffy = new StringBuffer(); + Set spawnpoints = am.getPlugin().getMAConfig().getKeys("arenas." + am.getSelectedArena().configName() + ".coords.spawnpoints"); + + if (spawnpoints != null) { + for (String s : spawnpoints) { + buffy.append(s); + buffy.append(" "); + } + } + else { + buffy.append(Msg.MISC_NONE); + } + + Messenger.tellPlayer(sender, "Spawnpoints for arena '" + am.getSelectedArena().configName() + "': " + buffy.toString()); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/commands/user/ArenaListCommand.java b/src/com/garbagemule/MobArena/commands/user/ArenaListCommand.java index 7d27ad8..d8f98e6 100644 --- a/src/com/garbagemule/MobArena/commands/user/ArenaListCommand.java +++ b/src/com/garbagemule/MobArena/commands/user/ArenaListCommand.java @@ -4,51 +4,34 @@ import java.util.List; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import com.garbagemule.MobArena.commands.*; -import com.garbagemule.MobArena.*; -public class ArenaListCommand implements MACommand +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "arenalist", + pattern = "arenas|arenal.*|lista.*", + usage = "/ma arenas", + desc = "lists all available arenas", + permission = "mobarena.use.arenalist" +) +public class ArenaListCommand implements Command { @Override - public String[] getNames() { - return new String[] { "arenas" , "list" }; - } - - @Override - public String getPermission() { - return "mobarena.use.arenalist"; - } - - @Override - public boolean execute(MobArenaPlugin plugin, Player sender, String... args) { - // Grab the arena master and the args. - ArenaMaster am = plugin.getArenaMaster(); + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + List arenas; - // Get the arenas. - List arenas = am.getEnabledAndPermittedArenas(sender); - - // Turn the list into a string. - String msg = Msg.MISC_LIST_ARENAS.toString(listToString(arenas)); - - plugin.tell(sender, msg); - return true; - } - - @Override - public boolean executeFromConsole(MobArenaPlugin plugin, CommandSender sender, String... args) { - return false; - } - - private String listToString(List list) { - String result = ""; - - for (E e : list) { - result += e + ", "; + if (Commands.isPlayer(sender)) { + Player p = (Player) sender; + arenas = am.getPermittedArenas(p); + } else { + arenas = am.getArenas(); } - if (result.equals("")) - return Msg.MISC_NONE.toString(); - - return result.substring(0, result.length() - 2); + String list = MAUtils.listToString(arenas, am.getPlugin()); + Messenger.tellPlayer(sender, Msg.MISC_LIST_ARENAS.toString(list)); + return true; } } diff --git a/src/com/garbagemule/MobArena/commands/user/JoinCommand.java b/src/com/garbagemule/MobArena/commands/user/JoinCommand.java index 7ef7bda..b587464 100644 --- a/src/com/garbagemule/MobArena/commands/user/JoinCommand.java +++ b/src/com/garbagemule/MobArena/commands/user/JoinCommand.java @@ -1,71 +1,71 @@ package com.garbagemule.MobArena.commands.user; -import java.util.*; +import java.util.List; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import com.garbagemule.MobArena.commands.*; -import com.garbagemule.MobArena.*; -public class JoinCommand implements MACommand +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "join", + pattern = "j|jo.*|j.*n", + usage = "/ma join ()", + desc = "join an arena", + permission = "mobarena.use.join" +) +public class JoinCommand implements Command { @Override - public String[] getNames() { - return new String[] { "join" , "j" }; - } - - @Override - public String getPermission() { - return "mobarena.use.join"; - } - - @Override - public boolean execute(MobArenaPlugin plugin, Player sender, String... args) { - // Grab the arena master and get the argument. - ArenaMaster am = plugin.getArenaMaster(); - String arenaName = (args.length == 1) ? args[0] : null; - - // Get all arenas this player is eligible for. - List arenas = am.getEnabledAndPermittedArenas(sender); - - // If no arenas found, just tell the player it's not enabled. - if (arenas.size() == 0) { - plugin.tell(sender, Msg.JOIN_ARENA_NOT_ENABLED); + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + if (!Commands.isPlayer(sender)) { + Messenger.tellPlayer(sender, Msg.MISC_NOT_FROM_CONSOLE); return false; } - // Require an argument in case of multiple arenas. - if (arenaName == null && arenas.size() > 1) { - plugin.tell(sender, Msg.JOIN_ARG_NEEDED); + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Cast the sender. + Player p = (Player) sender; + + List arenas = am.getEnabledArenas(); + if (!am.isEnabled() || arenas.size() < 1) { + Messenger.tellPlayer(p, Msg.JOIN_NOT_ENABLED); + return true; + } + + // Grab the arena to join + Arena arena = arenas.size() == 1 ? arenas.get(0) : am.getArenaWithName(arg1); + + // Run a couple of basic sanity checks + if (!Commands.sanityChecks(p, am, arena, arg1, arenas)) { + return true; + } + + // Run a bunch of per-arena sanity checks + if (!arena.canJoin(p)) { return false; } - /* At this point in time, if there was no argument, there must be only - * a single arena in the list. If there was an argument, we can safely - * get the arena with that name, because canJoin() will do the rest of - * the sanity checks. */ - Arena a = (arenaName == null) ? arenas.get(0) : am.getArenaWithName(arenaName); + // If player is in a boat/minecart, eject! + if (p.isInsideVehicle()) + p.leaveVehicle(); - // If the arena is null, it doesn't exist. - if (a == null) { - plugin.tell(sender, Msg.ARENA_DOES_NOT_EXIST); + // If player is in a bed, unbed! + if (p.isSleeping()) { + p.kickPlayer("Banned for life... Nah, just don't join from a bed ;)"); return false; } - // Let the arena itself do the rest of the sanity checking. - if (!a.canJoin(sender)) { + // Join the arena! + if (!arena.playerJoin(p, p.getLocation())) { return false; } - // If no problems, let the guy join and notify. - a.playerJoin(sender, sender.getLocation()); - plugin.tell(sender, Msg.JOIN_PLAYER_JOINED); - return true; } - - @Override - public boolean executeFromConsole(MobArenaPlugin plugin, CommandSender sender, String... args) { - return false; - } } diff --git a/src/com/garbagemule/MobArena/commands/user/LeaveCommand.java b/src/com/garbagemule/MobArena/commands/user/LeaveCommand.java index 5e015d8..6b4f59a 100644 --- a/src/com/garbagemule/MobArena/commands/user/LeaveCommand.java +++ b/src/com/garbagemule/MobArena/commands/user/LeaveCommand.java @@ -2,28 +2,43 @@ package com.garbagemule.MobArena.commands.user; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import com.garbagemule.MobArena.commands.*; -import com.garbagemule.MobArena.*; -public class LeaveCommand implements MACommand +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "leave", + pattern = "l|le((.*))?", + usage = "/ma leave", + desc = "leave the arena", + permission = "mobarena.use.leave" +) +public class LeaveCommand implements Command { @Override - public String[] getNames() { - return new String[] { "leave" , "l" }; - } + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + if (!Commands.isPlayer(sender)) { + Messenger.tellPlayer(sender, Msg.MISC_NOT_FROM_CONSOLE); + return false; + } + + // Cast the sender. + Player p = (Player) sender; - @Override - public String getPermission() { - return "mobarena.use.leave"; - } - - @Override - public boolean execute(MobArenaPlugin plugin, Player sender, String... args) { + Arena arena = am.getArenaWithPlayer(p); + if (arena == null) { + arena = am.getArenaWithSpectator(p); + if (arena == null) { + Messenger.tellPlayer(p, Msg.LEAVE_NOT_PLAYING); + return false; + } + } + + if (arena.playerLeave(p)) { + Messenger.tellPlayer(p, Msg.LEAVE_PLAYER_LEFT); + } return true; } - - @Override - public boolean executeFromConsole(MobArenaPlugin plugin, CommandSender sender, String... args) { - return false; - } } diff --git a/src/com/garbagemule/MobArena/commands/user/NotReadyCommand.java b/src/com/garbagemule/MobArena/commands/user/NotReadyCommand.java index f08a272..549d0df 100644 --- a/src/com/garbagemule/MobArena/commands/user/NotReadyCommand.java +++ b/src/com/garbagemule/MobArena/commands/user/NotReadyCommand.java @@ -2,28 +2,52 @@ package com.garbagemule.MobArena.commands.user; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import com.garbagemule.MobArena.commands.*; -import com.garbagemule.MobArena.*; -public class NotReadyCommand implements MACommand +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "notready", + pattern = "notr.*|ready", + usage = "/ma notready ()", + desc = "lists all available arenas", + permission = "mobarena.use.arenalist" +) +public class NotReadyCommand implements Command { @Override - public String[] getNames() { - return new String[] { "notready" , "check" }; - } - - @Override - public String getPermission() { - return "mobarena.use.notready"; - } - - @Override - public boolean execute(MobArenaPlugin plugin, Player sender, String... args) { + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any + String arg1 = (args.length > 0 ? args[0] : ""); + + // The arena to query. + Arena arena = null; + + if (!arg1.equals("")) { + arena = am.getArenaWithName(arg1); + if (arena == null) { + Messenger.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); + return false; + } + } + else if (Commands.isPlayer(sender)) { + Player p = (Player) sender; + arena = am.getArenaWithPlayer(p); + + if (arena == null) { + Messenger.tellPlayer(sender, Msg.LEAVE_NOT_PLAYING); + return false; + } + } + else { + Messenger.tellPlayer(sender, "Usage: /ma notready "); + return false; + } + + String list = MAUtils.listToString(arena.getNonreadyPlayers(), am.getPlugin()); + Messenger.tellPlayer(sender, Msg.MISC_LIST_PLAYERS.toString(list)); return true; } - - @Override - public boolean executeFromConsole(MobArenaPlugin plugin, CommandSender sender, String... args) { - return false; - } } diff --git a/src/com/garbagemule/MobArena/commands/user/PlayerListCommand.java b/src/com/garbagemule/MobArena/commands/user/PlayerListCommand.java index ac656c8..c63a618 100644 --- a/src/com/garbagemule/MobArena/commands/user/PlayerListCommand.java +++ b/src/com/garbagemule/MobArena/commands/user/PlayerListCommand.java @@ -1,29 +1,54 @@ package com.garbagemule.MobArena.commands.user; +import java.util.LinkedList; +import java.util.List; + import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import com.garbagemule.MobArena.commands.*; -import com.garbagemule.MobArena.*; -public class PlayerListCommand implements MACommand +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "playerlist", + pattern = "player.*|listp.*", + usage = "/ma players ()", + desc = "lists players in an arena", + permission = "mobarena.use.playerlist" +) +public class PlayerListCommand implements Command { @Override - public String[] getNames() { - return new String[] { "who" , "players" }; - } - - @Override - public String getPermission() { - return "mobarena.use.playerlist"; - } - - @Override - public boolean execute(MobArenaPlugin plugin, Player sender, String... args) { + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + String list = null; + if (!arg1.equals("")) { + Arena arena = am.getArenaWithName(arg1); + + if (arena == null) { + Messenger.tellPlayer(sender, Msg.ARENA_DOES_NOT_EXIST); + return false; + } + + list = MAUtils.listToString(arena.getPlayersInArena(), am.getPlugin()); + } + else { + StringBuffer buffy = new StringBuffer(); + List players = new LinkedList(); + + for (Arena arena : am.getArenas()) { + players.addAll(arena.getPlayersInArena()); + } + + buffy.append(MAUtils.listToString(players, am.getPlugin())); + list = buffy.toString(); + } + + Messenger.tellPlayer(sender, Msg.MISC_LIST_PLAYERS.toString(list)); return true; } - - @Override - public boolean executeFromConsole(MobArenaPlugin plugin, CommandSender sender, String... args) { - return false; - } } diff --git a/src/com/garbagemule/MobArena/commands/user/SpecCommand.java b/src/com/garbagemule/MobArena/commands/user/SpecCommand.java new file mode 100644 index 0000000..1aeae73 --- /dev/null +++ b/src/com/garbagemule/MobArena/commands/user/SpecCommand.java @@ -0,0 +1,70 @@ +package com.garbagemule.MobArena.commands.user; + +import java.util.List; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.garbagemule.MobArena.*; +import com.garbagemule.MobArena.commands.*; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; + +@CommandInfo( + name = "spec", + pattern = "s|spec.*", + usage = "/ma spec ()", + desc = "spec an arena", + permission = "mobarena.use.spec" +) +public class SpecCommand implements Command +{ + @Override + public boolean execute(ArenaMaster am, CommandSender sender, String... args) { + if (!Commands.isPlayer(sender)) { + Messenger.tellPlayer(sender, Msg.MISC_NOT_FROM_CONSOLE); + return false; + } + + // Grab the argument, if any. + String arg1 = (args.length > 0 ? args[0] : ""); + + // Cast the sender. + Player p = (Player) sender; + + List arenas = am.getEnabledArenas(); + if (!am.isEnabled() || arenas.size() < 1) { + Messenger.tellPlayer(p, Msg.JOIN_NOT_ENABLED); + return true; + } + + // Grab the arena to join + Arena arena = arenas.size() == 1 ? arenas.get(0) : am.getArenaWithName(arg1); + + // Run a couple of basic sanity checks + if (!Commands.sanityChecks(p, am, arena, arg1, arenas)) { + return false; + } + + // Run a bunch of arena-specific sanity-checks + if (!arena.canSpec(p)) { + return false; + } + + // If player is in a boat/minecart, eject! + if (p.isInsideVehicle()) + p.leaveVehicle(); + + // If player is in a bed, unbed! + if (p.isSleeping()) { + p.kickPlayer("Banned for life... Nah, just don't join from a bed ;)"); + return false; + } + + // Spectate the arena! + arena.playerSpec(p, p.getLocation()); + + Messenger.tellPlayer(p, Msg.SPEC_PLAYER_SPECTATE); + return true; + } +} diff --git a/src/com/garbagemule/MobArena/events/ArenaEndEvent.java b/src/com/garbagemule/MobArena/events/ArenaEndEvent.java new file mode 100644 index 0000000..12f8218 --- /dev/null +++ b/src/com/garbagemule/MobArena/events/ArenaEndEvent.java @@ -0,0 +1,43 @@ +package com.garbagemule.MobArena.events; + +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import com.garbagemule.MobArena.framework.Arena; + +public class ArenaEndEvent extends Event implements Cancellable +{ + private static final long serialVersionUID = -492437066028367597L; + + private static final HandlerList handlers = new HandlerList(); + private Arena arena; + private boolean cancelled; + + public ArenaEndEvent(Arena arena) { + this.arena = arena; + this.cancelled = false; + } + + public Arena getArena() { + return arena; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/events/ArenaPlayerDeathEvent.java b/src/com/garbagemule/MobArena/events/ArenaPlayerDeathEvent.java new file mode 100644 index 0000000..a26ce70 --- /dev/null +++ b/src/com/garbagemule/MobArena/events/ArenaPlayerDeathEvent.java @@ -0,0 +1,37 @@ +package com.garbagemule.MobArena.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import com.garbagemule.MobArena.framework.Arena; + +public class ArenaPlayerDeathEvent extends Event +{ + private static final long serialVersionUID = 8945689670354700831L; + + private static final HandlerList handlers = new HandlerList(); + private Player player; + private Arena arena; + + public ArenaPlayerDeathEvent(Player player, Arena arena) { + this.player = player; + this.arena = arena; + } + + public Player getPlayer() { + return player; + } + + public Arena getArena() { + return arena; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/events/ArenaPlayerJoinEvent.java b/src/com/garbagemule/MobArena/events/ArenaPlayerJoinEvent.java new file mode 100644 index 0000000..c83c2c2 --- /dev/null +++ b/src/com/garbagemule/MobArena/events/ArenaPlayerJoinEvent.java @@ -0,0 +1,50 @@ +package com.garbagemule.MobArena.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import com.garbagemule.MobArena.framework.Arena; + +public class ArenaPlayerJoinEvent extends Event implements Cancellable +{ + private static final long serialVersionUID = -1205905192685201064L; + + private static final HandlerList handlers = new HandlerList(); + private Player player; + private Arena arena; + private boolean cancelled; + + public ArenaPlayerJoinEvent(Player player, Arena arena) { + this.player = player; + this.arena = arena; + this.cancelled = false; + } + + public Player getPlayer() { + return player; + } + + public Arena getArena() { + return arena; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/events/ArenaPlayerLeaveEvent.java b/src/com/garbagemule/MobArena/events/ArenaPlayerLeaveEvent.java new file mode 100644 index 0000000..a27c33f --- /dev/null +++ b/src/com/garbagemule/MobArena/events/ArenaPlayerLeaveEvent.java @@ -0,0 +1,50 @@ +package com.garbagemule.MobArena.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import com.garbagemule.MobArena.framework.Arena; + +public class ArenaPlayerLeaveEvent extends Event implements Cancellable +{ + private static final long serialVersionUID = -8942511403871825734L; + + private static final HandlerList handlers = new HandlerList(); + private Player player; + private Arena arena; + private boolean cancelled; + + public ArenaPlayerLeaveEvent(Player player, Arena arena) { + this.player = player; + this.arena = arena; + this.cancelled = false; + } + + public Player getPlayer() { + return player; + } + + public Arena getArena() { + return arena; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/events/ArenaStartEvent.java b/src/com/garbagemule/MobArena/events/ArenaStartEvent.java new file mode 100644 index 0000000..0e5d566 --- /dev/null +++ b/src/com/garbagemule/MobArena/events/ArenaStartEvent.java @@ -0,0 +1,43 @@ +package com.garbagemule.MobArena.events; + +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import com.garbagemule.MobArena.framework.Arena; + +public class ArenaStartEvent extends Event implements Cancellable +{ + private static final long serialVersionUID = 4414065978731456440L; + + private static final HandlerList handlers = new HandlerList(); + private Arena arena; + private boolean cancelled; + + public ArenaStartEvent(Arena arena) { + this.arena = arena; + this.cancelled = false; + } + + public Arena getArena() { + return arena; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/events/NewWaveEvent.java b/src/com/garbagemule/MobArena/events/NewWaveEvent.java new file mode 100644 index 0000000..46b7593 --- /dev/null +++ b/src/com/garbagemule/MobArena/events/NewWaveEvent.java @@ -0,0 +1,55 @@ +package com.garbagemule.MobArena.events; + +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.waves.Wave; + +public class NewWaveEvent extends Event implements Cancellable +{ + private static final long serialVersionUID = -8743818273565357180L; + + private static final HandlerList handlers = new HandlerList(); + private Arena arena; + private boolean cancelled; + + private Wave wave; + private int waveNo; + + public NewWaveEvent(Arena arena, Wave wave, int waveNo) { + this.wave = wave; + this.waveNo = waveNo; + } + + public Wave getWave() { + return wave; + } + + public int getWaveNumber() { + return waveNo; + } + + public Arena getArena() { + return arena; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/com/garbagemule/MobArena/framework/Arena.java b/src/com/garbagemule/MobArena/framework/Arena.java new file mode 100644 index 0000000..a7de49c --- /dev/null +++ b/src/com/garbagemule/MobArena/framework/Arena.java @@ -0,0 +1,231 @@ +package com.garbagemule.MobArena.framework; + +import java.util.*; + +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import com.garbagemule.MobArena.ArenaClass; +import com.garbagemule.MobArena.ArenaListenerImpl; +import com.garbagemule.MobArena.ArenaPlayer; +import com.garbagemule.MobArena.MASpawnThread; +import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.MonsterManager; +import com.garbagemule.MobArena.RewardManager; +import com.garbagemule.MobArena.leaderboards.Leaderboard; +import com.garbagemule.MobArena.region.ArenaRegion; +import com.garbagemule.MobArena.repairable.Repairable; +import com.garbagemule.MobArena.util.config.ConfigSection; +import com.garbagemule.MobArena.util.inventory.InventoryManager; +import com.garbagemule.MobArena.waves.Wave; +import com.garbagemule.MobArena.waves.WaveManager; + +public interface Arena +{ + /*///////////////////////////////////////////////////////////////////////// + // + // NEW METHODS IN REFACTORING + // + /////////////////////////////////////////////////////////////////////////*/ + + public ConfigSection getSettings(); + + public World getWorld(); + + public void setWorld(World world); + + public boolean isEnabled(); + + public void setEnabled(boolean value); + + public boolean isProtected(); + + public void setProtected(boolean value); + + public boolean isRunning(); + + public boolean inEditMode(); + + public void setEditMode(boolean value); + + public Material getClassLogo(String classname); + + public List getEntryFee(); + + public Set>> getEveryWaveEntrySet(); + + public List getAfterWaveReward(int wave); + + public Set getPlayersInArena(); + + public Set getPlayersInLobby(); + + public Set getReadyPlayersInLobby(); + + public Set getSpectators(); + + public MASpawnThread getSpawnThread(); + + public WaveManager getWaveManager(); + + public Location getPlayerEntry(Player p); + + public ArenaListenerImpl getEventListener(); + + public void setLeaderboard(Leaderboard leaderboard); + + public ArenaPlayer getArenaPlayer(Player p); + + public Set getBlocks(); + + public void addBlock(Block b); + + public boolean removeBlock(Block b); + + public boolean hasPet(Entity e); + + public void addRepairable(Repairable r); + + public ArenaRegion getRegion(); + + public InventoryManager getInventoryManager(); + + public RewardManager getRewardManager(); + + public MonsterManager getMonsterManager(); + + public void revivePlayer(Player p); + + + + + + + public void scheduleTask(Runnable r, int delay); + + + + + + + + + + + + + public boolean startArena(); + + public boolean endArena(); + + public void forceStart(); + + public void forceEnd(); + + public boolean playerJoin(Player p, Location loc); + + public void playerReady(Player p); + + public boolean playerLeave(Player p); + + public void playerDeath(Player p); + + public void playerRespawn(Player p); + + public Location getRespawnLocation(Player p); + + public void playerSpec(Player p, Location loc); + + public void storePlayerData(Player p, Location loc); + + public void storeContainerContents(); + + public void restoreContainerContents(); + + public void movePlayerToLobby(Player p); + + public void movePlayerToSpec(Player p); + + public void movePlayerToEntry(Player p); + + public void discardPlayer(Player p); + + public void repairBlocks(); + + public void queueRepairable(Repairable r); + + + + /*//////////////////////////////////////////////////////////////////// + // + // Items & Cleanup + // + ////////////////////////////////////////////////////////////////////*/ + + public void assignClass(Player p, String className); + + public void assignRandomClass(Player p); + + public void assignClassPermissions(Player p); + + public void removeClassPermissions(Player p); + + + + /*//////////////////////////////////////////////////////////////////// + // + // Initialization & Checks + // + ////////////////////////////////////////////////////////////////////*/ + + public void restoreRegion(); + + + + /*//////////////////////////////////////////////////////////////////// + // + // Getters & Misc + // + ////////////////////////////////////////////////////////////////////*/ + + public boolean inArena(Player p); + + public boolean inLobby(Player p); + + public boolean inSpec(Player p); + + public boolean isDead(Player p); + + public String configName(); + + public String arenaName(); + + public MobArena getPlugin(); + + public Wave getWave(); + + public Map getClasses(); + + public int getPlayerCount(); + + public List getAllPlayers(); + + public Collection getArenaPlayerSet(); + + public List getNonreadyPlayers(); + + public boolean canAfford(Player p); + + public boolean takeFee(Player p); + + public boolean refund(Player p); + + public boolean canJoin(Player p); + + public boolean canSpec(Player p); +} diff --git a/src/com/garbagemule/MobArena/ArenaListener.java b/src/com/garbagemule/MobArena/framework/ArenaListener.java similarity index 90% rename from src/com/garbagemule/MobArena/ArenaListener.java rename to src/com/garbagemule/MobArena/framework/ArenaListener.java index e55211c..7b75661 100644 --- a/src/com/garbagemule/MobArena/ArenaListener.java +++ b/src/com/garbagemule/MobArena/framework/ArenaListener.java @@ -1,4 +1,4 @@ -package com.garbagemule.MobArena; +package com.garbagemule.MobArena.framework; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockIgniteEvent; @@ -19,7 +19,11 @@ import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerTeleportEvent; public interface ArenaListener -{ +{ + public enum TeleportResponse { + ALLOW, REJECT, IDGAF + } + public void onBlockBreak(BlockBreakEvent event); public void onBlockPlace(BlockPlaceEvent event); public void onBlockIgnite(BlockIgniteEvent event); @@ -35,6 +39,6 @@ public interface ArenaListener public void onPlayerInteract(PlayerInteractEvent event); public void onPlayerQuit(PlayerQuitEvent event); public void onPlayerKick(PlayerKickEvent event); - public void onPlayerTeleport(PlayerTeleportEvent event); + public TeleportResponse onPlayerTeleport(PlayerTeleportEvent event); public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event); } diff --git a/src/com/garbagemule/MobArena/framework/ArenaMaster.java b/src/com/garbagemule/MobArena/framework/ArenaMaster.java new file mode 100644 index 0000000..f16ffc7 --- /dev/null +++ b/src/com/garbagemule/MobArena/framework/ArenaMaster.java @@ -0,0 +1,136 @@ +package com.garbagemule.MobArena.framework; + +import java.util.List; +import java.util.Map; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.PlayerInventory; + +import com.garbagemule.MobArena.ArenaClass; +import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.framework.Arena; + +public interface ArenaMaster +{ + /*///////////////////////////////////////////////////////////////////////// + // + // NEW METHODS IN REFACTORING + // + /////////////////////////////////////////////////////////////////////////*/ + + + public MobArena getPlugin(); + + public boolean isEnabled(); + + public void setEnabled(boolean value); + + public boolean notifyOnUpdates(); + + public Arena getSelectedArena(); + + public void setSelectedArena(Arena arena); + + public List getArenas(); + + public Map getClasses(); + + public void addPlayer(Player p, Arena arena); + + public Arena removePlayer(Player p); + + public void resetArenaMap(); + + + + /*///////////////////////////////////////////////////////////////////////// + // + // Getters + // + /////////////////////////////////////////////////////////////////////////*/ + + + public List getEnabledArenas(); + + public List getPermittedArenas(Player p); + + public List getEnabledAndPermittedArenas(Player p); + + public Arena getArenaAtLocation(Location loc); + + public List getArenasInWorld(World world); + + public List getAllPlayers(); + + public List getAllPlayersInArena(String arenaName); + + public List getAllLivingPlayers(); + + public List getLivingPlayersInArena(String arenaName); + + public Arena getArenaWithPlayer(Player p); + + public Arena getArenaWithPlayer(String playerName); + + public Arena getArenaWithSpectator(Player p); + + public Arena getArenaWithMonster(Entity e); + + public Arena getArenaWithPet(Entity e); + + public Arena getArenaWithName(String configName); + + public boolean isAllowed(String command); + + + + /*///////////////////////////////////////////////////////////////////////// + // + // Initialization + // + /////////////////////////////////////////////////////////////////////////*/ + + public void initialize(); + + /** + * Load the global settings. + */ + public void loadSettings(); + + /** + * Load all class-related stuff. + */ + public void loadClasses(); + + public ArenaClass createClassNode(String className, PlayerInventory inv, boolean safe); + + public void removeClassNode(String className); + + public boolean addClassPermission(String className, String perm); + + public boolean removeClassPermission(String className, String perm); + + /** + * Load all arena-related stuff. + */ + public void loadArenas(); + + public Arena createArenaNode(String configName, World world); + + public void removeArenaNode(Arena arena); + + + + /*///////////////////////////////////////////////////////////////////////// + // + // Update and serialization methods + // + /////////////////////////////////////////////////////////////////////////*/ + + public void reloadConfig(); + + public void saveConfig(); +} diff --git a/src/com/garbagemule/MobArena/health/HealthStrategy.java b/src/com/garbagemule/MobArena/health/HealthStrategy.java new file mode 100644 index 0000000..ea5bc12 --- /dev/null +++ b/src/com/garbagemule/MobArena/health/HealthStrategy.java @@ -0,0 +1,13 @@ +package com.garbagemule.MobArena.health; + +import org.bukkit.entity.Player; + +public interface HealthStrategy +{ + /** + * Set the health of a player. + * @param p a player + * @param health amount of health + */ + public void setHealth(Player p, int health); +} diff --git a/src/com/garbagemule/MobArena/health/HealthStrategyHeroes.java b/src/com/garbagemule/MobArena/health/HealthStrategyHeroes.java new file mode 100644 index 0000000..e8a62fb --- /dev/null +++ b/src/com/garbagemule/MobArena/health/HealthStrategyHeroes.java @@ -0,0 +1,21 @@ +package com.garbagemule.MobArena.health; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.entity.EntityRegainHealthEvent; +import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; + +public class HealthStrategyHeroes implements HealthStrategy +{ + @Override + public void setHealth(Player p, int health) { + int current = p.getHealth(); + int regain = health == 20 ? 20 : health - current; + + try { + EntityRegainHealthEvent event = new EntityRegainHealthEvent(p, regain, RegainReason.CUSTOM); + Bukkit.getPluginManager().callEvent(event); + } + catch (Exception e) {} // Because Bukkit is retarded. + } +} diff --git a/src/com/garbagemule/MobArena/health/HealthStrategyStandard.java b/src/com/garbagemule/MobArena/health/HealthStrategyStandard.java new file mode 100644 index 0000000..7f8aece --- /dev/null +++ b/src/com/garbagemule/MobArena/health/HealthStrategyStandard.java @@ -0,0 +1,11 @@ +package com.garbagemule.MobArena.health; + +import org.bukkit.entity.Player; + +public class HealthStrategyStandard implements HealthStrategy +{ + @Override + public void setHealth(Player p, int health) { + p.setHealth(health); + } +} diff --git a/src/com/garbagemule/MobArena/leaderboards/AbstractLeaderboardColumn.java b/src/com/garbagemule/MobArena/leaderboards/AbstractLeaderboardColumn.java new file mode 100644 index 0000000..fe07abc --- /dev/null +++ b/src/com/garbagemule/MobArena/leaderboards/AbstractLeaderboardColumn.java @@ -0,0 +1,57 @@ +package com.garbagemule.MobArena.leaderboards; + +import java.util.List; + +import org.bukkit.block.Sign; + +import com.garbagemule.MobArena.ArenaPlayerStatistics; + +public abstract class AbstractLeaderboardColumn implements LeaderboardColumn +{ + protected String statname; + private Sign header; + private List signs; + + public AbstractLeaderboardColumn(String statname, Sign header, List signs) { + this.statname = statname; + this.header = header; + this.signs = signs; + } + + public void update(List stats) { + // Make sure the stats will fit on the signs. + int range = Math.min(stats.size(), signs.size()*4); + + for (int i = 0; i < range; i++) { + // Grab the right sign. + Sign s = signs.get(i/4); + + // Call the template method. + String value = getLine(stats.get(i)); + + // And set the line + s.setLine(i % 4, value); + s.update(); + } + } + + public abstract String getLine(ArenaPlayerStatistics stats); + + public void clear() { + for (Sign s : signs) { + s.setLine(0, ""); + s.setLine(1, ""); + s.setLine(2, ""); + s.setLine(3, ""); + s.update(); + } + } + + public Sign getHeader() { + return header; + } + + public List getSigns() { + return signs; + } +} diff --git a/src/com/garbagemule/MobArena/leaderboards/ClassLeaderboardColumn.java b/src/com/garbagemule/MobArena/leaderboards/ClassLeaderboardColumn.java new file mode 100644 index 0000000..83583ee --- /dev/null +++ b/src/com/garbagemule/MobArena/leaderboards/ClassLeaderboardColumn.java @@ -0,0 +1,19 @@ +package com.garbagemule.MobArena.leaderboards; + +import java.util.List; + +import org.bukkit.block.Sign; + +import com.garbagemule.MobArena.ArenaPlayerStatistics; + +public class ClassLeaderboardColumn extends AbstractLeaderboardColumn +{ + public ClassLeaderboardColumn(String statname, Sign header, List signs) { + super(statname, header, signs); + } + + @Override + public String getLine(ArenaPlayerStatistics stats) { + return stats.getClassName(); + } +} diff --git a/src/com/garbagemule/MobArena/leaderboards/IntLeaderboardColumn.java b/src/com/garbagemule/MobArena/leaderboards/IntLeaderboardColumn.java new file mode 100644 index 0000000..0a48d03 --- /dev/null +++ b/src/com/garbagemule/MobArena/leaderboards/IntLeaderboardColumn.java @@ -0,0 +1,19 @@ +package com.garbagemule.MobArena.leaderboards; + +import java.util.List; + +import org.bukkit.block.Sign; + +import com.garbagemule.MobArena.ArenaPlayerStatistics; + +public class IntLeaderboardColumn extends AbstractLeaderboardColumn +{ + public IntLeaderboardColumn(String statname, Sign header, List signs) { + super(statname, header, signs); + } + + @Override + public String getLine(ArenaPlayerStatistics stats) { + return "" + stats.getInt(statname); + } +} diff --git a/src/com/garbagemule/MobArena/leaderboards/Leaderboard.java b/src/com/garbagemule/MobArena/leaderboards/Leaderboard.java index d5eacba..7b286f8 100644 --- a/src/com/garbagemule/MobArena/leaderboards/Leaderboard.java +++ b/src/com/garbagemule/MobArena/leaderboards/Leaderboard.java @@ -4,19 +4,16 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.block.BlockFace; import org.bukkit.block.BlockState; import org.bukkit.block.Sign; -//import org.bukkit.util.config.Configuration; -import com.garbagemule.MobArena.Arena; import com.garbagemule.MobArena.ArenaPlayer; import com.garbagemule.MobArena.ArenaPlayerStatistics; import com.garbagemule.MobArena.MobArena; -import com.garbagemule.MobArena.util.Config; +import com.garbagemule.MobArena.framework.Arena; public class Leaderboard { @@ -34,12 +31,12 @@ public class Leaderboard private boolean isValid; /** - * Default constructor. + * Private constructor. * Creates a new leaderboard with no signs or locations or anything. * @param plugin MobArena instance. * @param arena The arena to which this leaderboard belongs. */ - public Leaderboard(MobArena plugin, Arena arena) + private Leaderboard(MobArena plugin, Arena arena) { this.plugin = plugin; this.arena = arena; @@ -47,31 +44,6 @@ public class Leaderboard this.stats = new ArrayList(); } - /** - * Config constructor. - * Used to create a leaderboard from the location persisted in the config-file. - * @param plugin MobArena instance. - * @param arena The arena to which this leaderboard belongs. - * @param config The config-file in which the location is specified. - */ - public Leaderboard(MobArena plugin, Arena arena, Config config) - { - this(plugin, arena); - - // Grab the coords from the config-file. - String coords = config.getString("arenas." + arena.configName() + ".coords.leaderboard", null); - - if (coords != null) - { - // Grab the top left sign. - topLeft = Config.parseLocation(arena.getWorld(), coords); - - // If it is a sign, validate. - if (topLeft.getBlock().getState() instanceof Sign) - isValid = isGridWellFormed(); - } - } - /** * Location constructor. * Used to create a leaderboard on-the-fly from the location from the SignChangeEvent. @@ -83,6 +55,10 @@ public class Leaderboard { this(plugin, arena); + if (topLeft == null) { + return; + } + if (!(topLeft.getBlock().getState() instanceof Sign)) throw new IllegalArgumentException("Block must be a sign!"); @@ -118,7 +94,7 @@ public class Leaderboard public void startTracking() { - trackingId = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, + trackingId = plugin.getServer().getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() { public void run() @@ -130,7 +106,7 @@ public class Leaderboard public void stopTracking() { - Bukkit.getServer().getScheduler().cancelTask(trackingId); + plugin.getServer().getScheduler().cancelTask(trackingId); } /** @@ -146,7 +122,7 @@ public class Leaderboard if (!(state instanceof Sign)) { - MobArena.error("Leaderboards for '" + arena.configName() + "' could not be established!"); + plugin.error("Leaderboards for '" + arena.configName() + "' could not be established!"); return false; } @@ -212,8 +188,21 @@ public class Leaderboard } // Create the column. - LeaderboardColumn column = LeaderboardColumn.create(stat.getShortName(), header, signs); - if (column == null) continue; + LeaderboardColumn column = null; + + // Switch on the type of stat + switch (stat) { + case PLAYER_NAME: + column = new PlayerLeaderboardColumn(stat.getShortName(), header, signs); + break; + case CLASS_NAME: + column = new ClassLeaderboardColumn(stat.getShortName(), header, signs); + break; + default: + column = new IntLeaderboardColumn(stat.getShortName(), header, signs); + break; + } + this.boards.add(column); } while ((header = getAdjacentSign(header, direction)) != null); diff --git a/src/com/garbagemule/MobArena/leaderboards/LeaderboardColumn.java b/src/com/garbagemule/MobArena/leaderboards/LeaderboardColumn.java index 756a410..9d0a1e0 100644 --- a/src/com/garbagemule/MobArena/leaderboards/LeaderboardColumn.java +++ b/src/com/garbagemule/MobArena/leaderboards/LeaderboardColumn.java @@ -1,116 +1,43 @@ package com.garbagemule.MobArena.leaderboards; -import java.lang.reflect.Field; import java.util.List; -import org.bukkit.ChatColor; import org.bukkit.block.Sign; import com.garbagemule.MobArena.ArenaPlayerStatistics; -import com.garbagemule.MobArena.util.TextUtils; -public class LeaderboardColumn +public interface LeaderboardColumn { - private Field field; - private boolean isPlayerName; - private Sign header; - private List signs; - - private LeaderboardColumn(String statname, Sign header, List signs) throws Exception - { - this.field = ArenaPlayerStatistics.class.getDeclaredField(statname); - this.isPlayerName = statname.equals("playerName"); - this.header = header; - this.signs = signs; - } + /** + * Update all the signs in this column to the current values + * of the player stat associated with this column. + */ + public void update(List stats); /** - * Safely create a new LeaderboardColumn. - * Avoid the try-catch blocks by creating columns with this method. - * @param statname The name of the stat to track - * @param header The header sign - * @param signs A list of signs - * @return A new LeaderboardColumn, or null + * Get the String representation of the stat in question. + * The line is calculated by simply calling the appropriate + * getter on the ArenaPlayerStatistics object. + * @param stats an ArenaPlayerStatistics object + * @return the String representation of the stat in question */ - public static LeaderboardColumn create(String statname, Sign header, List signs) - { - try - { - return new LeaderboardColumn(statname, header, signs); - } - catch (Exception e) - { - e.printStackTrace(); - return null; - } - } + public String getLine(ArenaPlayerStatistics stats); - public void update(List stats) - { - // Make sure the stats will fit on the signs. - int range = Math.min(stats.size(), signs.size()*4); - - try - { - if (isPlayerName) - { - for (int i = 0; i < range; i++) - { - // Grab the right sign. - Sign s = signs.get(i/4); - - // Get the stat value. - field.setAccessible(true); - ArenaPlayerStatistics aps = stats.get(i); - Object o = field.get(aps); - field.setAccessible(false); - String name = aps.getArenaPlayer().isDead() ? o.toString() : ChatColor.GREEN + o.toString(); - - // Set the value on the right line. - s.setLine(i % 4, TextUtils.truncate(name)); - s.update(); - } - } - else - { - for (int i = 0; i < range; i++) - { - // Grab the right sign. - Sign s = signs.get(i/4); - - // Get the stat value. - field.setAccessible(true); - Object o = field.get(stats.get(i)); - field.setAccessible(false); - - // Set the value on the right line. - s.setLine(i % 4, o.toString()); - s.update(); - } - } - } - catch (Exception e) { e.printStackTrace(); } - } + /** + * Clear the text on all the signs in the column. + */ + public void clear(); - public void clear() - { - for (Sign s : signs) - { - s.setLine(0, ""); - s.setLine(1, ""); - s.setLine(2, ""); - s.setLine(3, ""); - s.update(); - } - } + /** + * Get the top sign of the column. + * The top sign displays the stat name. + * @return the top sign of the column + */ + public Sign getHeader(); - public Sign getHeader() - { - return header; - } - - public List getSigns() - { - return signs; - } + /** + * Get all signs in the column (minus the header). + * @return all signs in the column (minus the header) + */ + public List getSigns(); } diff --git a/src/com/garbagemule/MobArena/leaderboards/PlayerLeaderboardColumn.java b/src/com/garbagemule/MobArena/leaderboards/PlayerLeaderboardColumn.java new file mode 100644 index 0000000..7d7bb59 --- /dev/null +++ b/src/com/garbagemule/MobArena/leaderboards/PlayerLeaderboardColumn.java @@ -0,0 +1,19 @@ +package com.garbagemule.MobArena.leaderboards; + +import java.util.List; + +import org.bukkit.block.Sign; + +import com.garbagemule.MobArena.ArenaPlayerStatistics; + +public class PlayerLeaderboardColumn extends AbstractLeaderboardColumn +{ + public PlayerLeaderboardColumn(String statname, Sign header, List signs) { + super(statname, header, signs); + } + + @Override + public String getLine(ArenaPlayerStatistics stats) { + return stats.getPlayerName(); + } +} diff --git a/src/com/garbagemule/MobArena/leaderboards/Stats.java b/src/com/garbagemule/MobArena/leaderboards/Stats.java index 71c1786..b84f35b 100644 --- a/src/com/garbagemule/MobArena/leaderboards/Stats.java +++ b/src/com/garbagemule/MobArena/leaderboards/Stats.java @@ -1,49 +1,44 @@ package com.garbagemule.MobArena.leaderboards; -import com.garbagemule.MobArena.util.WaveUtils; - public enum Stats { - players("Players", "playerName"), - className("Class", "className"), - kills("Kills", "kills"), - dmgDone("Damage Done", "dmgDone"), - dmgTaken("Damage Taken", "dmgTaken"), - swings("Swings", "swings"), - hits("Hits", "hits"), - lastWave("Last Wave", "lastWave"); + PLAYER_NAME("Players", "playerName"), + CLASS_NAME("Class", "class"), + KILLS("Kills", "kills"), + DAMAGE_DONE("Damage Done", "dmgDone"), + DAMAGE_TAKEN("Damage Taken", "dmgTaken"), + SWINGS("Swings", "swings"), + HITS("Hits", "hits"), + LAST_WAVE("Last Wave", "lastWave"); private String name, shortName; - private Stats(String name, String shortName) - { + private Stats(String name, String shortName) { this.name = name; this.shortName = shortName; } - public String getShortName() - { + public String getShortName() { return shortName; } - public String getFullName() - { + public String getFullName() { return name; } - public static Stats fromString(String name) - { - if (name.equals("class")) - return Stats.className; - return WaveUtils.getEnumFromStringCaseSensitive(Stats.class, name); - } - - public static Stats getByFullName(String name) - { - + public static Stats getByFullName(String name) { for (Stats s : Stats.values()) if (s.name.equals(name)) return s; return null; } + + public static Stats getByShortName(String name) { + for (Stats s : Stats.values()) { + if (s.shortName.equalsIgnoreCase(name)) { + return s; + } + } + return null; + } } diff --git a/src/com/garbagemule/MobArena/listeners/MAGlobalListener.java b/src/com/garbagemule/MobArena/listeners/MAGlobalListener.java new file mode 100644 index 0000000..fd6347c --- /dev/null +++ b/src/com/garbagemule/MobArena/listeners/MAGlobalListener.java @@ -0,0 +1,278 @@ +package com.garbagemule.MobArena.listeners; + +import org.bukkit.ChatColor; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.*; +import org.bukkit.event.entity.*; +import org.bukkit.event.player.*; + +import com.garbagemule.MobArena.Messenger; +import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.framework.ArenaMaster; +import com.garbagemule.MobArena.framework.ArenaListener.TeleportResponse; +import com.garbagemule.MobArena.leaderboards.Stats; +import com.garbagemule.MobArena.util.VersionChecker; + +/** + * The point of this class is to simply redirect all events to each arena's + * own listener(s). + * This means only one actual listener need be registered in Bukkit, and thus + * less overhead. Of course, this requires a little bit of "hackery" here + * and there. + */ +public class MAGlobalListener implements Listener +{ + private MobArena plugin; + private ArenaMaster am; + + public MAGlobalListener(MobArena plugin, ArenaMaster am) { + this.plugin = plugin; + this.am = am; + } + + + /////////////////////////////////////////////////////////////////////////// + // // + // BLOCK EVENTS // + // // + /////////////////////////////////////////////////////////////////////////// + + + @EventHandler(priority = EventPriority.HIGHEST) + public void blockBreak(BlockBreakEvent event) { + for (Arena arena : am.getArenas()) + arena.getEventListener().onBlockBreak(event); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void blockBurn(BlockBurnEvent event) { + for (Arena arena : am.getArenas()) + arena.getEventListener().onBlockBurn(event); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void blockForm(BlockFormEvent event) { + for (Arena arena : am.getArenas()) + arena.getEventListener().onBlockForm(event); + } + + @EventHandler(priority = EventPriority.HIGH) + public void blockIgnite(BlockIgniteEvent event) { + for (Arena arena : am.getArenas()) + arena.getEventListener().onBlockIgnite(event); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void blockPlace(BlockPlaceEvent event) { + for (Arena arena : am.getArenas()) + arena.getEventListener().onBlockPlace(event); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void signChange(SignChangeEvent event) { + if (!event.getPlayer().hasPermission("mobarena.setup.leaderboards")) { + return; + } + + if (!event.getLine(0).startsWith("[MA]")) { + return; + } + + String text = event.getLine(0).substring((4)); + Arena arena; + Stats stat; + + if ((arena = am.getArenaWithName(text)) != null) { + arena.getEventListener().onSignChange(event); + setSignLines(event, ChatColor.GREEN + "MobArena", ChatColor.YELLOW + arena.arenaName(), ChatColor.AQUA + "Players", "---------------"); + } + else if ((stat = Stats.getByShortName(text)) != null) { + setSignLines(event, ChatColor.GREEN + "", "", ChatColor.AQUA + stat.getFullName(), "---------------"); + Messenger.tellPlayer(event.getPlayer(), "Stat sign created."); + } + } + + private void setSignLines(SignChangeEvent event, String s1, String s2, String s3, String s4) { + event.setLine(0, s1); + event.setLine(1, s2); + event.setLine(2, s3); + event.setLine(3, s4); + } + + + + /////////////////////////////////////////////////////////////////////////// + // // + // ENTITY EVENTS // + // // + /////////////////////////////////////////////////////////////////////////// + + + @EventHandler(priority = EventPriority.HIGHEST) + public void creatureSpawn(CreatureSpawnEvent event) { + for (Arena arena : am.getArenas()) + arena.getEventListener().onCreatureSpawn(event); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onEntityChangeBlock(EntityChangeBlockEvent event) { + for (Arena arena : am.getArenas()) + arena.getEventListener().onEntityChangeBlock(event); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void entityCombust(EntityCombustEvent event) { + for (Arena arena : am.getArenas()) + arena.getEventListener().onEntityCombust(event); + } + + @EventHandler(priority = EventPriority.LOW) + public void entityDamage(EntityDamageEvent event) { + for (Arena arena : am.getArenas()) + arena.getEventListener().onEntityDamage(event); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void entityDeath(EntityDeathEvent event) { + for (Arena arena : am.getArenas()) + arena.getEventListener().onEntityDeath(event); + } + + @EventHandler(priority = EventPriority.HIGHEST) + public void entityExplode(EntityExplodeEvent event) { + for (Arena arena : am.getArenas()) + arena.getEventListener().onEntityExplode(event); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void entityRegainHealth(EntityRegainHealthEvent event) { + for (Arena arena : am.getArenas()) + arena.getEventListener().onEntityRegainHealth(event); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void entityFoodLevelChange(FoodLevelChangeEvent event) { + for (Arena arena : am.getArenas()) + arena.getEventListener().onFoodLevelChange(event); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void entityTarget(EntityTargetEvent event) { + for (Arena arena : am.getArenas()) + arena.getEventListener().onEntityTarget(event); + } + + + + /////////////////////////////////////////////////////////////////////////// + // // + // PLAYER EVENTS // + // // + /////////////////////////////////////////////////////////////////////////// + + + @EventHandler(priority = EventPriority.NORMAL) + public void playerAnimation(PlayerAnimationEvent event) { + if (!am.isEnabled()) return; + for (Arena arena : am.getArenas()) + arena.getEventListener().onPlayerAnimation(event); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void playerBucketEmpty(PlayerBucketEmptyEvent event) { + if (!am.isEnabled()) return; + for (Arena arena : am.getArenas()) + arena.getEventListener().onPlayerBucketEmpty(event); + } + + @EventHandler(priority = EventPriority.LOWEST) + public void playerCommandPreprocess(PlayerCommandPreprocessEvent event) { + if (!am.isEnabled()) return; + for (Arena arena : am.getArenas()) + arena.getEventListener().onPlayerCommandPreprocess(event); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void playerDropItem(PlayerDropItemEvent event) { + if (!am.isEnabled()) return; + for (Arena arena : am.getArenas()) + arena.getEventListener().onPlayerDropItem(event); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void playerInteract(PlayerInteractEvent event) { + if (!am.isEnabled()) return; + for (Arena arena : am.getArenas()) + arena.getEventListener().onPlayerInteract(event); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void playerJoin(PlayerJoinEvent event) { + if (!am.notifyOnUpdates() || !event.getPlayer().isOp()) return; + + final Player p = event.getPlayer(); + plugin.getServer().getScheduler().scheduleAsyncDelayedTask(plugin, + new Runnable() + { + public void run() + { + if (plugin.getMAConfig().getBoolean("global-settings.update-notification", false) + && !VersionChecker.isLatest(plugin)) { + Messenger.tellPlayer(p, "There is a new version of MobArena available!"); + } + } + }, 60); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void playerKick(PlayerKickEvent event) { + for (Arena arena : am.getArenas()) + arena.getEventListener().onPlayerKick(event); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void playerQuit(PlayerQuitEvent event) { + for (Arena arena : am.getArenas()) + arena.getEventListener().onPlayerQuit(event); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void playerRespawn(PlayerRespawnEvent event) { + for (Arena arena : am.getArenas()) { + if (arena.getEventListener().onPlayerRespawn(event)) { + return; + } + } + + plugin.restoreInventory(event.getPlayer()); + } + + @EventHandler(priority = EventPriority.NORMAL) + public void playerTeleport(PlayerTeleportEvent event) { + if (!am.isEnabled()) return; + + boolean allow = true; + for (Arena arena : am.getArenas()) { + TeleportResponse r = arena.getEventListener().onPlayerTeleport(event); + + // If just one arena allows, uncancel and stop. + switch (r) { + case ALLOW: + event.setCancelled(false); + return; + case REJECT: + allow = false; + break; + } + } + + // Only cancel if at least one arena has rejected the teleport. + if (!allow) { + event.setCancelled(true); + } + } +} diff --git a/src/com/garbagemule/MobArena/listeners/MagicSpellsListener.java b/src/com/garbagemule/MobArena/listeners/MagicSpellsListener.java index 8adfc88..659eb2e 100644 --- a/src/com/garbagemule/MobArena/listeners/MagicSpellsListener.java +++ b/src/com/garbagemule/MobArena/listeners/MagicSpellsListener.java @@ -4,16 +4,18 @@ import java.io.File; import java.util.LinkedList; import java.util.List; -import org.bukkit.util.config.Configuration; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; -import com.garbagemule.MobArena.Arena; -import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.framework.Arena; import com.garbagemule.MobArena.util.FileUtils; -import com.garbagemule.MobArena.waves.Wave.WaveType; +import com.garbagemule.MobArena.util.config.Config; +import com.garbagemule.MobArena.waves.enums.*; +import com.garbagemule.MobArena.MobArena; import com.nisovin.magicspells.events.SpellCastEvent; -import com.nisovin.magicspells.events.SpellListener; -public class MagicSpellsListener extends SpellListener +public class MagicSpellsListener implements Listener { private MobArena plugin; private List disabled, disabledOnBoss, disabledOnSwarm; @@ -23,40 +25,32 @@ public class MagicSpellsListener extends SpellListener this.plugin = plugin; // Set up the MagicSpells config-file. - File spellFile = FileUtils.extractFile(plugin.getDataFolder(), "magicspells.yml"); - Configuration spellConfig = new Configuration(spellFile); + File spellFile = FileUtils.extractFile(plugin, plugin.getDataFolder(), "magicspells.yml"); + Config spellConfig = new Config(spellFile); spellConfig.load(); setupSpells(spellConfig); } + @EventHandler(priority = EventPriority.NORMAL) public void onSpellCast(SpellCastEvent event) { - Arena arena = plugin.getAM().getArenaWithPlayer(event.getCaster()); + Arena arena = plugin.getArenaMaster().getArenaWithPlayer(event.getCaster()); if (arena == null || !arena.isRunning()) return; String spell = event.getSpell().getName(); WaveType type = (arena.getWave() != null) ? arena.getWave().getType() : null; if (disabled.contains(spell) || - (type == WaveType.BOSS && disabledOnBoss.contains(spell)) || - (type == WaveType.SWARM && disabledOnSwarm.contains(spell))) + (type == WaveType.BOSS && disabledOnBoss.contains(spell)) || + (type == WaveType.SWARM && disabledOnSwarm.contains(spell))) { event.setCancelled(true); + } } - private void setupSpells(Configuration config) + private void setupSpells(Config config) { this.disabled = config.getStringList("disabled-spells", new LinkedList()); - this.disabledOnBoss = config.getStringList("disabled-only-on-bosses", new LinkedList()); - this.disabledOnSwarm = config.getStringList("disabled-only-on-swarms", new LinkedList()); - } - - public void disableSpell(String spell) - { - disabled.add(spell); - } - - public void disableSpellOnBoss(String spell) - { - disabledOnBoss.add(spell); + this.disabledOnBoss = config.getStringList("disabled-on-bosses", new LinkedList()); + this.disabledOnSwarm = config.getStringList("disabled-on-swarms", new LinkedList()); } } diff --git a/src/com/garbagemule/MobArena/listeners/MagicSpellsOldListener.java b/src/com/garbagemule/MobArena/listeners/MagicSpellsOldListener.java deleted file mode 100644 index 1ee7944..0000000 --- a/src/com/garbagemule/MobArena/listeners/MagicSpellsOldListener.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.garbagemule.MobArena.listeners; - -import java.io.File; -import java.util.LinkedList; -import java.util.List; - -import org.bukkit.util.config.Configuration; - -import com.garbagemule.MobArena.Arena; -import com.garbagemule.MobArena.MobArena; -import com.garbagemule.MobArena.util.FileUtils; -import com.garbagemule.MobArena.waves.Wave.WaveType; -import com.nisovin.MagicSpells.Events.SpellCastEvent; -import com.nisovin.MagicSpells.Events.SpellListener; - -public class MagicSpellsOldListener extends SpellListener -{ - private MobArena plugin; - private List disabled, disabledOnBoss, disabledOnSwarm; - - public MagicSpellsOldListener(MobArena plugin) - { - this.plugin = plugin; - - // Set up the MagicSpells config-file. - File spellFile = FileUtils.extractFile(plugin.getDataFolder(), "magicspells.yml"); - Configuration spellConfig = new Configuration(spellFile); - spellConfig.load(); - setupSpells(spellConfig); - } - - public void onSpellCast(SpellCastEvent event) - { - Arena arena = plugin.getAM().getArenaWithPlayer(event.getCaster()); - if (arena == null || !arena.isRunning()) return; - - String spell = event.getSpell().getName(); - WaveType type = (arena.getWave() != null) ? arena.getWave().getType() : null; - - if (disabled.contains(spell) || - (type == WaveType.BOSS && disabledOnBoss.contains(spell)) || - (type == WaveType.SWARM && disabledOnSwarm.contains(spell))) - event.setCancelled(true); - } - - private void setupSpells(Configuration config) - { - this.disabled = config.getStringList("disabled-spells", new LinkedList()); - this.disabledOnBoss = config.getStringList("disabled-only-on-bosses", new LinkedList()); - this.disabledOnSwarm = config.getStringList("disabled-only-on-swarms", new LinkedList()); - } - - public void disableSpell(String spell) - { - disabled.add(spell); - } - - public void disableSpellOnBoss(String spell) - { - disabledOnBoss.add(spell); - } -} diff --git a/src/com/garbagemule/MobArena/listeners/MASpoutScreenListener.java b/src/com/garbagemule/MobArena/listeners/SpoutScreenListener.java similarity index 64% rename from src/com/garbagemule/MobArena/listeners/MASpoutScreenListener.java rename to src/com/garbagemule/MobArena/listeners/SpoutScreenListener.java index 84d1818..458d596 100644 --- a/src/com/garbagemule/MobArena/listeners/MASpoutScreenListener.java +++ b/src/com/garbagemule/MobArena/listeners/SpoutScreenListener.java @@ -1,30 +1,33 @@ package com.garbagemule.MobArena.listeners; import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; import org.getspout.spoutapi.event.screen.ButtonClickEvent; -import org.getspout.spoutapi.event.screen.ScreenListener; import org.getspout.spoutapi.gui.Button; -import com.garbagemule.MobArena.Arena; -import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.framework.Arena; import com.garbagemule.MobArena.spout.ClassButton; +import com.garbagemule.MobArena.MobArena; -public class MASpoutScreenListener extends ScreenListener +public class SpoutScreenListener implements Listener { private MobArena plugin; - public MASpoutScreenListener(MobArena plugin) + public SpoutScreenListener(MobArena plugin) { this.plugin = plugin; } + @EventHandler(priority = EventPriority.NORMAL) public void onButtonClick(ButtonClickEvent event) { Button b = event.getButton(); if (!(b instanceof ClassButton)) return; Player p = event.getPlayer(); - Arena arena = plugin.getAM().getArenaWithPlayer(p); + Arena arena = plugin.getArenaMaster().getArenaWithPlayer(p); if (arena == null) return; arena.assignClass(p, b.getText()); diff --git a/src/com/garbagemule/MobArena/region/ArenaRegion.java b/src/com/garbagemule/MobArena/region/ArenaRegion.java new file mode 100644 index 0000000..d437976 --- /dev/null +++ b/src/com/garbagemule/MobArena/region/ArenaRegion.java @@ -0,0 +1,517 @@ +package com.garbagemule.MobArena.region; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.block.BlockState; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import com.garbagemule.MobArena.Messenger; +import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.util.config.ConfigSection; + +public class ArenaRegion +{ + private Arena arena; + private World world; + + private Location p1, p2, l1, l2, arenaWarp, lobbyWarp, specWarp, leaderboard; + private Map spawnpoints, containers; + + private boolean setup, lobbySetup; + + private ConfigSection coords; + private ConfigSection spawns; + private ConfigSection chests; + + public ArenaRegion(ConfigSection coords, Arena arena) { + this.arena = arena; + this.world = arena.getWorld(); + + this.coords = coords; + this.spawns = coords.getConfigSection("spawnpoints"); + this.chests = coords.getConfigSection("containers"); + + reloadAll(); + adjustRegion(); + } + + public void reloadAll() { + reloadRegion(); + reloadWarps(); + reloadLeaderboards(); + reloadSpawnpoints(); + reloadChests(); + + verifyData(); + } + + public void reloadRegion() { + p1 = coords.getLocation("p1", world); + p2 = coords.getLocation("p2", world); + + l1 = coords.getLocation("l1", world); + l2 = coords.getLocation("l2", world); + } + + public void reloadWarps() { + arenaWarp = coords.getLocation("arena", world); + lobbyWarp = coords.getLocation("lobby", world); + specWarp = coords.getLocation("spectator", world); + + leaderboard = coords.getLocation("leaderboard", world); + } + + public void reloadLeaderboards() { + leaderboard = coords.getLocation("leaderboard", world); + } + + public void reloadSpawnpoints() { + spawnpoints = new HashMap(); + Set keys = spawns.getKeys(); + if (keys != null) { + for (String spwn : keys) { + spawnpoints.put(spwn, spawns.getLocation(spwn, world)); + } + } + } + + public void reloadChests() { + containers = new HashMap(); + Set keys = chests.getKeys(); + if (keys != null) { + for (String chst : keys) { + containers.put(chst, chests.getLocation(chst, world)); + } + } + } + + public void verifyData() { + setup = (p1 != null && + p2 != null && + arenaWarp != null && + lobbyWarp != null && + specWarp != null && + !spawnpoints.isEmpty()); + + lobbySetup = (l1 != null && + l2 != null); + } + + public void checkData(MobArena plugin, CommandSender s) { + if (arenaWarp == null) + Messenger.tellPlayer(s, "Missing warp: arena"); + if (lobbyWarp == null) + Messenger.tellPlayer(s, "Missing warp: lobby"); + if (specWarp == null) + Messenger.tellPlayer(s, "Missing warp: spectator"); + if (p1 == null) + Messenger.tellPlayer(s, "Missing region point: p1"); + if (p2 == null) + Messenger.tellPlayer(s, "Missing region point: p2"); + if (spawnpoints.isEmpty()) + Messenger.tellPlayer(s, "Missing spawnpoints"); + if (setup) + Messenger.tellPlayer(s, "Arena is ready to be used!"); + } + + public boolean isDefined() { + return (p1 != null && p2 != null); + } + + public boolean isLobbyDefined() { + return (l1 != null && l2 != null); + } + + public boolean isSetup() { + return setup; + } + + public boolean isLobbySetup() { + return lobbySetup; + } + + public boolean isWarp(Location l) { + return (l.equals(arenaWarp) || + l.equals(lobbyWarp) || + l.equals(specWarp)); + } + + public boolean contains(Location l) { + if (!l.getWorld().getName().equals(world.getName()) || !setup) { + return false; + } + + int x = l.getBlockX(); + int y = l.getBlockY(); + int z = l.getBlockZ(); + + // Check the lobby first. + if (lobbySetup) { + if ((x >= l1.getBlockX() && x <= l2.getBlockX()) && + (z >= l1.getBlockZ() && z <= l2.getBlockZ()) && + (y >= l1.getBlockY() && y <= l2.getBlockY())) + return true; + } + + // Returns false if the location is outside of the region. + return ((x >= p1.getBlockX() && x <= p2.getBlockX()) && + (z >= p1.getBlockZ() && z <= p2.getBlockZ()) && + (y >= p1.getBlockY() && y <= p2.getBlockY())); + } + + public boolean contains(Location l, int radius) { + if (!l.getWorld().getName().equals(world.getName()) || !setup) { + return false; + } + + int x = l.getBlockX(); + int y = l.getBlockY(); + int z = l.getBlockZ(); + + if (lobbySetup) { + if ((x + radius >= l1.getBlockX() && x - radius <= l2.getBlockX()) && + (z + radius >= l1.getBlockZ() && z - radius <= l2.getBlockZ()) && + (y + radius >= l1.getBlockY() && y - radius <= l2.getBlockY())) + return true; + } + + return ((x + radius >= p1.getBlockX() && x - radius <= p2.getBlockX()) && + (z + radius >= p1.getBlockZ() && z - radius <= p2.getBlockZ()) && + (y + radius >= p1.getBlockY() && y - radius <= p2.getBlockY())); + } + + // Region expand + public void expandUp(int amount) { + p2.setY(Math.min(127D, p2.getY() + amount)); + set(RegionPoint.P2, p2); + } + + public void expandDown(int amount) { + p1.setY(Math.max(0D, p1.getY() - amount)); + set(RegionPoint.P1, p1); + } + + public void expandP1(int x, int z) { + p1.setX(p1.getX() - x); + p1.setZ(p1.getZ() - z); + set(RegionPoint.P1, p1); + } + + public void expandP2(int x, int z) { + p2.setX(p2.getX() + x); + p2.setZ(p2.getZ() + z); + set(RegionPoint.P2, p2); + } + + public void expandOut(int amount) { + expandP1(amount, amount); + expandP2(amount, amount); + } + + // Lobby expand + public void expandLobbyUp(int amount) { + l2.setY(Math.min(127D, l2.getY() + amount)); + set(RegionPoint.L2, l2); + } + + public void expandLobbyDown(int amount) { + l1.setY(Math.max(0D, l1.getY() + amount)); + set(RegionPoint.L1, l1); + } + + public void expandL1(int x, int z) { + l1.setX(l1.getX() - x); + l1.setZ(l1.getZ() - z); + set(RegionPoint.L1, l1); + } + + public void expandL2(int x, int z) { + l2.setX(l2.getX() + x); + l2.setZ(l2.getZ() + z); + set(RegionPoint.L2, l2); + } + + public void expandLobbyOut(int amount) { + expandL1(amount, amount); + expandL2(amount, amount); + } + + public void fixRegion() { + fix("p1", "p2"); + } + + public void fixLobbyRegion() { + fix("l1", "l2"); + } + + private void fix(String location1, String location2) { + Location loc1 = coords.getLocation(location1, world); + Location loc2 = coords.getLocation(location2, world); + + if (loc1 == null || loc2 == null) { + return; + } + + if (loc1.getX() > loc2.getX()) { + double tmp = loc1.getX(); + loc1.setX(loc2.getX()); + loc2.setX(tmp); + } + + if (loc1.getZ() > loc2.getZ()) { + double tmp = loc1.getZ(); + loc1.setZ(loc2.getZ()); + loc2.setZ(tmp); + } + + if (loc1.getY() > loc2.getY()) { + double tmp = loc1.getY(); + loc1.setY(loc2.getY()); + loc2.setY(tmp); + } + + if (!arena.getWorld().getName().equals(world.getName())) + arena.setWorld(world); + + coords.set(location1, loc1); + coords.set(location2, loc2); + } + + private void adjustRegion() { + if (!setup) { + return; + } + + // Make sure the arena warp is inside the region. + readjustRegion(arenaWarp); + + // Re-adjust for all spawnpoints and containers. + for (Location spawnpoint : spawnpoints.values()) { + readjustRegion(spawnpoint); + } + + for (Location chest : containers.values()) { + readjustRegion(chest); + } + } + + private void readjustRegion(Location l) { + if (p1 == null || p2 == null) { + return; + } + + int x = l.getBlockX(); + int y = l.getBlockY(); + int z = l.getBlockZ(); + + int p1x = p1.getBlockX(); + int p1y = p1.getBlockY(); + int p1z = p1.getBlockZ(); + + int p2x = p2.getBlockX(); + int p2y = p2.getBlockY(); + int p2z = p2.getBlockZ(); + + if (x <= p1x) { + expandP1(p1x - x + 2, 0); + } + else if (x >= p2x) { + expandP2(x - p2x + 2, 0); + } + + if (y <= p1y) { + expandDown((int) (p1y - y + 2)); + } + else if (y >= p2y) { + expandUp((int) (y - p2y + 2)); + } + + if (z <= p1z) { + expandP1(0, p1z - z + 2); + } + else if (z >= p2z) { + expandP2(0, z - p2z + 2); + } + } + + public List getChunks() { + List result = new ArrayList(); + + if (p1 == null || p2 == null) { + return result; + } + + Chunk c1 = world.getChunkAt(p1); + Chunk c2 = world.getChunkAt(p2); + + for (int i = c1.getX(); i <= c2.getX(); i++) { + for (int j = c1.getZ(); j <= c2.getZ(); j++) { + result.add(world.getChunkAt(i,j)); + } + } + + return result; + } + + public Location getArenaWarp() { + return arenaWarp; + } + + public Location getLobbyWarp() { + return lobbyWarp; + } + + public Location getSpecWarp() { + return specWarp; + } + + public Location getSpawnpoint(String name) { + return spawnpoints.get(name); + } + + public Collection getSpawnpoints() { + return spawnpoints.values(); + } + + public List getSpawnpointList() { + return new ArrayList(spawnpoints.values()); + } + + public Collection getContainers() { + return containers.values(); + } + + public Location getLeaderboard() { + return leaderboard; + } + + public void set(String point, Location loc) { + coords.set(point, loc); + + // Adjust the region to accomodate any bounding box breaking. + if (point.equals("arena") || point.equals("lobby") || point.equals("spectator")) { + readjustRegion(loc); + } + + fixRegion(); + fixLobbyRegion(); + reloadRegion(); + reloadWarps(); + reloadLeaderboards(); + verifyData(); + save(); + } + + public void addSpawn(String name, Location loc) { + spawns.set(name, loc); + readjustRegion(loc); + reloadSpawnpoints(); + verifyData(); + save(); + } + + public boolean removeSpawn(String name) { + if (spawns.getString(name) == null) { + return false; + } + + spawns.set(name, null); + reloadSpawnpoints(); + verifyData(); + save(); + return true; + } + + public void addChest(String name, Location loc) { + chests.set(name, loc); + reloadChests(); + save(); + } + + public boolean removeChest(String name) { + if (chests.getString(name) == null) { + return false; + } + + chests.set(name, null); + reloadChests(); + save(); + return true; + } + + public void save() { + spawns.getParent().save(); + } + + public void showRegion(final Player p) { + if (!isDefined()) { + return; + } + + // Grab all the blocks, and send block change events. + final Map blocks = new HashMap(); + for (Location l : getFramePoints()) { + Block b = l.getBlock(); + blocks.put(l, b.getState()); + p.sendBlockChange(l, 35, (byte) 14); + } + + arena.scheduleTask(new Runnable() { + public void run() { + // If the player isn't online, just forget it. + if (!p.isOnline()) { + return; + } + + // Send block "restore" events. + for (Map.Entry entry : blocks.entrySet()) { + Location l = entry.getKey(); + BlockState b = entry.getValue(); + int id = b.getTypeId(); + byte data = b.getRawData(); + + p.sendBlockChange(l, id, data); + } + } + }, 100); + } + + private List getFramePoints() { + List result = new ArrayList(); + int x1 = p1.getBlockX(); int y1 = p1.getBlockY(); int z1 = p1.getBlockZ(); + int x2 = p2.getBlockX(); int y2 = p2.getBlockY(); int z2 = p2.getBlockZ(); + + for (int i = x1; i <= x2; i++) { + result.add(world.getBlockAt(i, y1, z1).getLocation()); + result.add(world.getBlockAt(i, y1, z2).getLocation()); + result.add(world.getBlockAt(i, y2, z1).getLocation()); + result.add(world.getBlockAt(i, y2, z2).getLocation()); + } + + for (int j = y1; j <= y2; j++) { + result.add(world.getBlockAt(x1, j, z1).getLocation()); + result.add(world.getBlockAt(x1, j, z2).getLocation()); + result.add(world.getBlockAt(x2, j, z1).getLocation()); + result.add(world.getBlockAt(x2, j, z2).getLocation()); + } + + for (int k = z1; k <= z2; k++) { + result.add(world.getBlockAt(x1, y1, k).getLocation()); + result.add(world.getBlockAt(x1, y2, k).getLocation()); + result.add(world.getBlockAt(x2, y1, k).getLocation()); + result.add(world.getBlockAt(x2, y2, k).getLocation()); + } + return result; + } +} diff --git a/src/com/garbagemule/MobArena/region/RegionPoint.java b/src/com/garbagemule/MobArena/region/RegionPoint.java new file mode 100644 index 0000000..f1bdb03 --- /dev/null +++ b/src/com/garbagemule/MobArena/region/RegionPoint.java @@ -0,0 +1,13 @@ +package com.garbagemule.MobArena.region; + +public class RegionPoint +{ + public static final String P1 = "p1"; + public static final String P2 = "p2"; + public static final String L1 = "l1"; + public static final String L2 = "l2"; + public static final String ARENA = "arena"; + public static final String LOBBY = "lobby"; + public static final String SPEC = "spectator"; + public static final String LEADERBOARD = "leaderboard"; +} diff --git a/src/com/garbagemule/MobArena/region/RegionSerializer.java b/src/com/garbagemule/MobArena/region/RegionSerializer.java new file mode 100644 index 0000000..3ad5473 --- /dev/null +++ b/src/com/garbagemule/MobArena/region/RegionSerializer.java @@ -0,0 +1,143 @@ +package com.garbagemule.MobArena.region; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.block.Block; + +import com.garbagemule.MobArena.framework.Arena; + +public class RegionSerializer +{ + //private UUID worldUID; + private int x1, y1, z1, x2, y2, z2; + private long width, height, length; + + private int[][][] blocks; + private byte[][][] data; + + //private transient World world; + + public RegionSerializer(World world, Location p1, Location p2) { + //this.worldUID = world.getUID(); + + this.x1 = p1.getBlockX(); + this.y1 = p1.getBlockY(); + this.z1 = p1.getBlockZ(); + + this.x2 = p2.getBlockX(); + this.y2 = p2.getBlockY(); + this.z2 = p2.getBlockZ(); + + this.width = (x2 - x1) + 1; + this.height = (y2 - y1) + 1; + this.length = (z2 - z1) + 1; + + int w = (int) width; + int h = (int) height; + int l = (int) length; + + this.blocks = new int[w][h][l]; + this.data = new byte[w][h][l]; + } + + public void serialize(Arena arena) { + Serializer s = new Serializer(arena); + s.start(); + } + + public void deserialize(Arena arena) { + Deserializer d = new Deserializer(arena); + d.start(); + } + + private class Serializer implements Runnable + { + private Arena arena; + private long total; + + public Serializer(Arena arena) { + this.arena = arena; + } + + public void start() { + // Disable the arena while serializing. + arena.setEnabled(false); + + // Start serializing! + total = 0; + arena.scheduleTask(this, 1); + } + + @Override + public void run() { + int y = (int) (total / (width*length)); + int z = (int) ((total % (width*length)) / width); + int x = (int) ((total % (width*length)) % width); + + long max = width*height*length; + int amount = (int) Math.min(20, (max - total)); + + for (int i = 0; i < amount; i++) { + Block b = arena.getWorld().getBlockAt(x,y,z); + blocks[x][y][z] = b.getTypeId(); + data[x][y][z] = b.getData(); + + x = (int) ((x+1) % width); + y = (int) ((y+1) % height); + z = (int) ((z+1) % length); + } + + total += amount; + + if (total == max) { + arena.setEnabled(true); + return; + } + + arena.scheduleTask(this, 1); + } + } + + private class Deserializer implements Runnable + { + private Arena arena; + private long total; + + public Deserializer(Arena arena) { + this.arena = arena; + } + + public void start() { + // Disable the arena while serializing. + arena.setEnabled(false); + + // Start serializing! + total = 0; + arena.scheduleTask(this, 1); + } + + @Override + public void run() { + int y = (int) (total / (width*length)); + int z = (int) ((total % (width*length)) / width); + int x = (int) ((total % (width*length)) % width); + + long max = width*height*length; + int amount = (int) Math.min(20, (max - total)); + + for (int i = 0; i < 20; i++) { + Block b = arena.getWorld().getBlockAt(x,y,z); + b.setTypeIdAndData(blocks[x][y][z], data[x][y][z], false); + } + + total += amount; + + if (total == max) { + arena.setEnabled(true); + return; + } + + arena.scheduleTask(this, 1); + } + } +} diff --git a/src/com/garbagemule/MobArena/repairable/RepairableContainer.java b/src/com/garbagemule/MobArena/repairable/RepairableContainer.java index f4b8245..94c5932 100644 --- a/src/com/garbagemule/MobArena/repairable/RepairableContainer.java +++ b/src/com/garbagemule/MobArena/repairable/RepairableContainer.java @@ -3,54 +3,40 @@ package com.garbagemule.MobArena.repairable; import org.bukkit.block.BlockState; import org.bukkit.block.ContainerBlock; import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import com.garbagemule.MobArena.util.InventoryItem; +import com.garbagemule.MobArena.util.inventory.SerializableInventory; public class RepairableContainer extends RepairableBlock { - private InventoryItem[] items; + private SerializableInventory inv; - public RepairableContainer(BlockState state, boolean clear) - { + public RepairableContainer(BlockState state, boolean clear) { super(state); - // Grab the inventory and its contents + // Grab the inventory of the block Inventory inv = ((ContainerBlock) state).getInventory(); - ItemStack[] contents = inv.getContents(); - // Initialize the items array - items = new InventoryItem[contents.length]; - - // Turn every ItemStack into an InventoryItem - for (int i = 0; i < items.length; i++) - items[i] = InventoryItem.parseItemStack(contents[i]); + // Make a SerializableInventory + this.inv = new SerializableInventory(inv); // Clear the inventory if prompted if (clear) inv.clear(); } - public RepairableContainer(BlockState state) - { + public RepairableContainer(BlockState state) { this(state, true); } /** * Repairs the container block by adding all the contents back in. */ - public void repair() - { + public void repair() { super.repair(); // Grab the inventory ContainerBlock cb = (ContainerBlock) getWorld().getBlockAt(getX(),getY(),getZ()).getState(); - Inventory inv = cb.getInventory(); + Inventory chestInv = cb.getInventory(); - // Turn every InventoryItem into an ItemStack - for (int i = 0; i < items.length; i++) - { - InventoryItem item = items[i]; - inv.setItem(i, item != null ? item.toItemStack() : null); - } + SerializableInventory.loadContents(chestInv, this.inv); } } diff --git a/src/com/garbagemule/MobArena/spout/ClassPopup.java b/src/com/garbagemule/MobArena/spout/ClassPopup.java index 08b8d55..6397ece 100644 --- a/src/com/garbagemule/MobArena/spout/ClassPopup.java +++ b/src/com/garbagemule/MobArena/spout/ClassPopup.java @@ -23,6 +23,10 @@ public class ClassPopup extends GenericPopup int buttonsX = (screenWidth - 100) / 2; int buttonsY = (screenHeight - buttonsHeight) / 2 + 20; + // Apparently Spout complains if these aren't set + arenaTitle.setWidth(30); + arenaTitle.setHeight(10); + arenaTitle.setText("Choose your class!"); arenaTitle.setAlign(WidgetAnchor.CENTER_CENTER); arenaTitle.setX((screenWidth - arenaTitle.getWidth()) / 2).setY(buttonsY - 20); diff --git a/src/com/garbagemule/MobArena/spout/Spouty.java b/src/com/garbagemule/MobArena/spout/Spouty.java index 1f5c1f7..7d12bc2 100644 --- a/src/com/garbagemule/MobArena/spout/Spouty.java +++ b/src/com/garbagemule/MobArena/spout/Spouty.java @@ -3,33 +3,22 @@ package com.garbagemule.MobArena.spout; import java.util.LinkedList; import java.util.List; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.Event.Priority; -import org.bukkit.plugin.PluginManager; import org.getspout.spoutapi.SpoutManager; import org.getspout.spoutapi.player.SpoutPlayer; -import com.garbagemule.MobArena.Arena; import com.garbagemule.MobArena.MobArena; -import com.garbagemule.MobArena.listeners.MASpoutScreenListener; +import com.garbagemule.MobArena.framework.Arena; public class Spouty { - public static void registerEvents(MobArena plugin) - { - PluginManager pm = Bukkit.getServer().getPluginManager(); - pm.registerEvent(Event.Type.CUSTOM_EVENT, new MASpoutScreenListener(plugin), Priority.Normal, plugin); - } - public static void classSelectionScreen(MobArena plugin, Arena arena, Player p) { SpoutPlayer sp = SpoutManager.getPlayer(p); if (sp == null) return; List buttons = new LinkedList(); - for (String s : arena.getClasses()) + for (String s : arena.getClasses().keySet()) buttons.add(new ClassButton(s)); ClassPopup popup = new ClassPopup(plugin, sp, buttons); diff --git a/src/com/garbagemule/MobArena/time/Time.java b/src/com/garbagemule/MobArena/time/Time.java new file mode 100644 index 0000000..06f653b --- /dev/null +++ b/src/com/garbagemule/MobArena/time/Time.java @@ -0,0 +1,27 @@ +package com.garbagemule.MobArena.time; + +public enum Time +{ + DAWN(23000), + SUNRISE(23500), + MORNING(23900), + MIDDAY(6000), + NOON(6000), + DAY(8000), + AFTERNOON(11000), + EVENING(12000), + SUNSET(12600), + DUSK(13300), + NIGHT(14000), + MIDNIGHT(18000); + + private int time; + + private Time(int time) { + this.time = time; + } + + public int getTime() { + return time; + } +} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/time/TimeStrategy.java b/src/com/garbagemule/MobArena/time/TimeStrategy.java new file mode 100644 index 0000000..9a5c77d --- /dev/null +++ b/src/com/garbagemule/MobArena/time/TimeStrategy.java @@ -0,0 +1,24 @@ +package com.garbagemule.MobArena.time; + +import org.bukkit.entity.Player; + +public interface TimeStrategy +{ + /** + * Set the time enum used by setPlayerTime() + * @param time a Time enum + */ + public void setTime(Time time); + + /** + * Set the local client time for the player. + * @param p a player + */ + public void setPlayerTime(Player p); + + /** + * Reset the local client time for the player to the server time + * @param p a player + */ + public void resetPlayerTime(Player p); +} diff --git a/src/com/garbagemule/MobArena/time/TimeStrategyLocked.java b/src/com/garbagemule/MobArena/time/TimeStrategyLocked.java new file mode 100644 index 0000000..3bdce23 --- /dev/null +++ b/src/com/garbagemule/MobArena/time/TimeStrategyLocked.java @@ -0,0 +1,27 @@ +package com.garbagemule.MobArena.time; + +import org.bukkit.entity.Player; + +public class TimeStrategyLocked implements TimeStrategy +{ + private Time time; + + public TimeStrategyLocked(Time time) { + setTime(time); + } + + @Override + public void setTime(Time time) { + this.time = time; + } + + @Override + public void setPlayerTime(Player p) { + p.setPlayerTime(time.getTime(), false); + } + + @Override + public void resetPlayerTime(Player p) { + p.resetPlayerTime(); + } +} diff --git a/src/com/garbagemule/MobArena/time/TimeStrategyNull.java b/src/com/garbagemule/MobArena/time/TimeStrategyNull.java new file mode 100644 index 0000000..7fe0dc0 --- /dev/null +++ b/src/com/garbagemule/MobArena/time/TimeStrategyNull.java @@ -0,0 +1,15 @@ +package com.garbagemule.MobArena.time; + +import org.bukkit.entity.Player; + +public class TimeStrategyNull implements TimeStrategy +{ + @Override + public void setTime(Time time) {} + + @Override + public void setPlayerTime(Player p) {} + + @Override + public void resetPlayerTime(Player p) {} +} diff --git a/src/com/garbagemule/MobArena/util/Config.java b/src/com/garbagemule/MobArena/util/Config.java deleted file mode 100644 index c1275c6..0000000 --- a/src/com/garbagemule/MobArena/util/Config.java +++ /dev/null @@ -1,177 +0,0 @@ -package com.garbagemule.MobArena.util; - -import java.io.File; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.YamlConfiguration; - -public class Config -{ - private YamlConfiguration config; - private File configFile; - - public Config(File configFile) { - this.config = new YamlConfiguration(); - this.configFile = configFile; - - config.options().indent(4); - } - - public boolean load() { - try { - config.load(configFile); - return true; - } - catch (Exception e) { - e.printStackTrace(); - return false; - } - } - - public boolean save() { - try { - config.save(configFile); - return true; - } - catch (Exception e) { - e.printStackTrace(); - return false; - } - } - - public void setHeader(String header) { - config.options().header(header); - } - - - - /////////////////////////////////////////////////////////////////////////// - // // - // GETTERS // - // // - /////////////////////////////////////////////////////////////////////////// - - public Object getProperty(String path) { - return config.get(path); - } - - public boolean getBoolean(String path) { - return config.getBoolean(path); - } - - public boolean getBoolean(String path, boolean def) { - return config.getBoolean(path, def); - } - - public int getInt(String path) { - return config.getInt(path); - } - - public int getInt(String path, int def) { - return config.getInt(path, def); - } - - public String getString(String path) { - String result = config.getString(path); - return result != null ? result : null; - } - - public String getString(String path, String def) { - return config.getString(path, def); - } - - public Set getKeys(String path) { - if (config.get(path) == null) - return null; - - ConfigurationSection section = config.getConfigurationSection(path); - return section.getKeys(false); - } - - @SuppressWarnings("unchecked") - public List getStringList(String path, List def) { - if (config.get(path) == null) - return def != null ? def : new LinkedList(); - - List list = config.getStringList(path); - return (List) list; - } - - - - /////////////////////////////////////////////////////////////////////////// - // // - // MUTATORS // - // // - /////////////////////////////////////////////////////////////////////////// - - public void set(String path, Object value) { - config.set(path, value); - } - - public void setProperty(String path, Object value) { - this.set(path, value); - } - - public void remove(String path) { - this.set(path, null); - } - - public void removeProperty(String path) { - this.remove(path); - } - - - - /////////////////////////////////////////////////////////////////////////// - // // - // UTILITY METHODS // - // // - /////////////////////////////////////////////////////////////////////////// - - public static Location parseLocation(World world, String coords) - { - String[] parts = coords.split(","); - if (parts.length != 5) - throw new IllegalArgumentException("Input string must contain x, y, z, yaw and pitch"); - - Integer x = getInteger(parts[0]); - Integer y = getInteger(parts[1]); - Integer z = getInteger(parts[2]); - Float yaw = getFloat(parts[3]); - Float pitch = getFloat(parts[4]); - - if (x == null || y == null || z == null || yaw == null || pitch == null) - throw new NullPointerException("Some of the parsed values are null!"); - - return new Location(world, x, y, z, yaw, pitch); - } - - private static Integer getInteger(String s) - { - try - { - return Integer.parseInt(s.trim()); - } - catch (Exception e) {} - - return null; - } - - private static Float getFloat(String s) - { - try - { - return Float.parseFloat(s.trim()); - } - catch (Exception e) {} - - return null; - } - -} diff --git a/src/com/garbagemule/MobArena/util/ConfigUtils.java b/src/com/garbagemule/MobArena/util/ConfigUtils.java deleted file mode 100644 index 469ebc7..0000000 --- a/src/com/garbagemule/MobArena/util/ConfigUtils.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.garbagemule.MobArena.util; - -import org.bukkit.Location; -import org.bukkit.World; - -public class ConfigUtils -{ - public static Location parseLocation(World world, String coords) - { - String[] parts = coords.split(","); - if (parts.length != 5) - throw new IllegalArgumentException("Input string must contain x, y, z, yaw and pitch"); - - Integer x = getInt(parts[0]); - Integer y = getInt(parts[1]); - Integer z = getInt(parts[2]); - Float yaw = getFloat(parts[3]); - Float pitch = getFloat(parts[4]); - - if (x == null || y == null || z == null || yaw == null || pitch == null) - throw new NullPointerException("Some of the parsed values are null!"); - - return new Location(world, x, y, z, yaw, pitch); - } - - private static Integer getInt(String s) - { - try - { - return Integer.parseInt(s.trim()); - } - catch (Exception e) {} - - return null; - } - - private static Float getFloat(String s) - { - try - { - return Float.parseFloat(s.trim()); - } - catch (Exception e) {} - - return null; - } -} diff --git a/src/com/garbagemule/MobArena/util/Delays.java b/src/com/garbagemule/MobArena/util/Delays.java index 68fab16..faf9590 100644 --- a/src/com/garbagemule/MobArena/util/Delays.java +++ b/src/com/garbagemule/MobArena/util/Delays.java @@ -1,20 +1,29 @@ package com.garbagemule.MobArena.util; -import org.bukkit.Bukkit; import org.bukkit.entity.Player; import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.framework.Arena; public class Delays { - public static void douse(MobArena plugin, final Player p, long delay) - { - Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() - { - public void run() - { - p.setFireTicks(0); + public static void douse(MobArena plugin, final Player p, long delay) { + plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { + public void run() { + if (p.isOnline()) { + p.setFireTicks(0); + } } }, delay); } + + public static void revivePlayer(MobArena plugin, final Arena arena, final Player p) { + plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { + public void run() { + if (p.isOnline()) { + arena.revivePlayer(p); + } + } + }); + } } diff --git a/src/com/garbagemule/MobArena/util/Enums.java b/src/com/garbagemule/MobArena/util/Enums.java index 63e7051..d3904c9 100644 --- a/src/com/garbagemule/MobArena/util/Enums.java +++ b/src/com/garbagemule/MobArena/util/Enums.java @@ -5,15 +5,12 @@ public class Enums /** * Get the enum value of a string, null if it doesn't exist. */ - public static > T getEnumFromString(Class c, String string) - { - if(c != null && string != null) - { - try - { + public static > T getEnumFromString(Class c, String string) { + if (c != null && string != null) { + try { return Enum.valueOf(c, string.trim().toUpperCase()); } - catch(IllegalArgumentException ex) { } + catch(IllegalArgumentException ex) {} } return null; } @@ -21,15 +18,12 @@ public class Enums /** * Get the enum value of a string, null if it doesn't exist. */ - public static > T getEnumFromStringCaseSensitive(Class c, String string) - { - if(c != null && string != null) - { - try - { + public static > T getEnumFromStringCaseSensitive(Class c, String string) { + if (c != null && string != null) { + try { return Enum.valueOf(c, string); } - catch(IllegalArgumentException ex) { } + catch(IllegalArgumentException ex) {} } return null; } diff --git a/src/com/garbagemule/MobArena/util/FileUtils.java b/src/com/garbagemule/MobArena/util/FileUtils.java index 6205495..25da42f 100644 --- a/src/com/garbagemule/MobArena/util/FileUtils.java +++ b/src/com/garbagemule/MobArena/util/FileUtils.java @@ -11,9 +11,14 @@ import java.net.URLConnection; import java.util.HashSet; import java.util.Set; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.java.JavaPlugin; + //import org.bukkit.util.config.Configuration; import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.util.config.Config; +import com.garbagemule.MobArena.waves.WaveUtils; public class FileUtils { @@ -40,7 +45,7 @@ public class FileUtils * Download all necessary libraries. * @param config The MobArena config-file */ - public static void fetchLibs(Config config) + public static void fetchLibs(MobArena plugin, Config config) { // Get all arenas Set arenas = config.getKeys("arenas"); @@ -59,17 +64,17 @@ public class FileUtils // Download all libraries for (Library lib : libs) - if (!libraryExists(lib)) - fetchLib(lib); + if (!libraryExists(plugin, lib)) + fetchLib(plugin, lib); } /** * Download a given library. * @param lib The Library to download */ - private static synchronized void fetchLib(Library lib) + private static synchronized void fetchLib(MobArena plugin, Library lib) { - MobArena.info("Downloading library '" + lib.filename + "' for log-method '" + lib.name().toLowerCase() + "'..."); + plugin.info("Downloading library '" + lib.filename + "' for log-method '" + lib.name().toLowerCase() + "'..."); URLConnection con = null; InputStream in = null; @@ -87,7 +92,7 @@ public class FileUtils if (lib.backup == null) { e.printStackTrace(); - System.out.println("Connection issues"); + plugin.warning("Connection issues"); return; } @@ -100,14 +105,14 @@ public class FileUtils catch (Exception e2) { e2.printStackTrace(); - System.out.println("Connection issues"); + plugin.warning("Connection issues"); return; } } try { - File libdir = new File(MobArena.dir, "lib"); + File libdir = new File(plugin.getDataFolder(), "lib"); libdir.mkdir(); File file = new File(libdir, lib.filename); @@ -126,14 +131,14 @@ public class FileUtils out.write(buffer, 0, length); // Announce successful download - MobArena.info(lib.filename + " downloaded in " + ((System.currentTimeMillis()-startTime)/1000.0) + " seconds."); + plugin.info(lib.filename + " downloaded in " + ((System.currentTimeMillis()-startTime)/1000.0) + " seconds."); addLibraryToClassLoader(file); } catch (Exception e) { e.printStackTrace(); - MobArena.warning("Couldn't download library: " + lib.filename); + plugin.warning("Couldn't download library: " + lib.filename); } finally { @@ -149,15 +154,12 @@ public class FileUtils } } - private static boolean libraryExists(Library lib) - { - return new File(MobArena.dir + File.separator + "lib", lib.filename).exists(); + private static boolean libraryExists(JavaPlugin plugin, Library lib) { + return new File(plugin.getDataFolder() + File.separator + "lib", lib.filename).exists(); } - private static void addLibraryToClassLoader(File file) - { - try - { + private static void addLibraryToClassLoader(File file) { + try { // Grab the class loader and its addURL method URLClassLoader cl = (URLClassLoader) ClassLoader.getSystemClassLoader(); Method addURL = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{ URL.class }); @@ -166,8 +168,7 @@ public class FileUtils // Add the library addURL.invoke(cl, new Object[]{file.toURI().toURL()}); } - catch (Exception e) - { + catch (Exception e) { e.printStackTrace(); } } @@ -176,14 +177,15 @@ public class FileUtils * Create default files from the res/ directory, if they exist. * @param filenames Files to be created. */ - public static void extractDefaults(String... filenames) - { + public static void extractDefaults(MobArena plugin, String... filenames) { + File dir = plugin.getDataFolder(); + if (!dir.exists()) dir.mkdir(); + for (String filename : filenames) - extractFile(MobArena.dir, filename); + extractFile(plugin, dir, filename); } - public static File extractFile(File dir, String filename) - { + public static File extractFile(MobArena plugin, File dir, String filename) { // Skip if file exists File file = new File(dir, filename); if (file.exists()) return file; @@ -192,8 +194,7 @@ public class FileUtils InputStream in = MobArena.class.getResourceAsStream("/res/" + filename); if (in == null) return null; - try - { + try { // Set up an output stream FileOutputStream out = new FileOutputStream(file); byte[] buffer = new byte[8192]; @@ -208,10 +209,30 @@ public class FileUtils return file; } - catch (Exception e) - { + catch (Exception e) { e.printStackTrace(); - MobArena.warning("Problem creating file '" + filename + "'!"); + plugin.warning("Problem creating file '" + filename + "'!"); + } + + return null; + } + + public static YamlConfiguration getConfig(MobArena plugin, String filename) { + InputStream in = MobArena.class.getResourceAsStream("/res/" + filename); + if (in == null) { + plugin.error("Failed to load '" + filename + "', the server must be restarted!"); + return null; + } + + try { + YamlConfiguration result = new YamlConfiguration(); + result.load(in); + + return result; + } + catch (Exception e) { + e.printStackTrace(); + plugin.warning("Couldn't load '" + filename + "' as stream!"); } return null; diff --git a/src/com/garbagemule/MobArena/util/InventoryItem.java b/src/com/garbagemule/MobArena/util/InventoryItem.java deleted file mode 100644 index 38f2757..0000000 --- a/src/com/garbagemule/MobArena/util/InventoryItem.java +++ /dev/null @@ -1,269 +0,0 @@ -package com.garbagemule.MobArena.util; - -import java.io.Serializable; -import java.util.LinkedList; -import java.util.List; - -import org.bukkit.inventory.ItemStack; -import org.bukkit.material.MaterialData; - -public class InventoryItem implements Serializable -{ - private static final long serialVersionUID = 739709220350581510L; - private int id; - private int amount; - private Byte data; - private short durability; - - /** - * Default constructor. - * @param id The data value/type id of the ItemStack - * @param amount The amount of the stack - * @param data The MaterialData (possibly null) of the stack - * @param durability The durability of the stack - */ - public InventoryItem(int id, int amount, Byte data, short durability) - { - this.id = id; - this.amount = amount; - this.data = data; - this.durability = durability; - } - - /** - * ItemStack constructor. - * @param stack The ItemStack to base the InventoryItem off of. - */ - public InventoryItem(ItemStack stack) - { - if (stack == null) - id = -1; - - id = stack.getTypeId(); - amount = stack.getAmount(); - - // In case of "odd" items, don't attempt to get data and durability - if (id < 0) return; - - data = stack.getData() == null ? null : stack.getData().getData(); - durability = stack.getDurability(); - } - - /** - * Static method for turning a (possibly null) InventoryItem into an ItemStack. - * The method is useful if it is unknown whether an InventoryItem object is - * null or not. - * @param item The Inventory item to convert - * @return An ItemStack representation of the InventoryItem, or null - */ - public static ItemStack toItemStack(InventoryItem item) - { - if (item == null) - return null; - - return item.toItemStack(); - } - - public static ItemStack[] toItemStacks(InventoryItem[] items) - { - ItemStack[] result = new ItemStack[items.length]; - - for (int i = 0; i < items.length; i++) - result[i] = items[i].toItemStack(); - - return result; - } - - /** - * Static method for converting an ItemStack to an InventoryItems. - * @param stack The ItemStack to convert - * @return An InventoryItem representation of the ItemStack, or null - */ - public static InventoryItem parseItemStack(ItemStack stack) - { - if (stack == null) - return new InventoryItem(-1, -1, null, (short) 0); - - return new InventoryItem(stack); - } - - /** - * Static method for converting an ItemStack array to an InventoryItem array. - * @param stacks The ItemStack array - * @return An InventoryItem array - */ - public static InventoryItem[] parseItemStacks(ItemStack[] stacks) - { - InventoryItem[] items = new InventoryItem[stacks.length]; - - for (int i = 0; i < items.length; i++) - items[i] = parseItemStack(stacks[i]); - - return items; - } - - /** - * Convert a list of ItemStacks into an array of InventoryItems - * @param stacks List of ItemStacks to convert - * @return An InventoryItem array - */ - public static InventoryItem[] parseItemStacks(List stacks) - { - InventoryItem[] items = new InventoryItem[stacks.size()]; - - for (int i = 0; i < items.length; i++) - items[i] = parseItemStack(stacks.get(i)); - - return items; - } - - /** - * Static method for extracting all InventoryItems from an InventoryItem array. - * @param id The type id of the items to extract - * @param items The InventoryItem array - * @return A list of all InventoryItems removed - */ - public static List extractAllFromArray(int id, InventoryItem[] items) - { - List list = new LinkedList(); - - for (int i = 0; i < items.length; i++) - { - if (items[i].getTypeId() == id) - { - list.add(items[i]); - items[i].setTypeId(-1); - } - } - - return list; - } - - /** - * Static method for removing an InventoryItem from an InventoryItem array. - * @param item The InventoryItem to remove - * @param items The InventoryItem array to remove from - * @return true, if the item was removed successfully, false otherwise - */ - public static boolean removeItemFromArray(InventoryItem item, InventoryItem[] items) - { - // Grab the total amount to remove - int leftToRemove = item.getAmount(); - - for (int i = 0; i < items.length; i++) - { - if (items[i].getTypeId() != item.getTypeId()) - continue; - - // Grab the amount - int amount = items[i].getAmount(); - - // Reduce amount/nullify item - if (amount > leftToRemove) - { - items[i].setAmount(amount - leftToRemove); - leftToRemove = 0; - } - else - { - items[i].setTypeId(-1); - leftToRemove -= amount; - } - - // If nothing left to remove, return true. - if (leftToRemove == 0) - return true; - } - - return false; - } - - /** - * Get the data value/type id of the item - * @return A type id - */ - public int getTypeId() - { - return id; - } - - /** - * Set the data value/type id of the item - * @param id A type id - */ - public void setTypeId(int id) - { - this.id = id; - } - - /** - * Get the amount of the item - * @return An amount - */ - public int getAmount() - { - return amount; - } - - /** - * Set the amount of the item - * @param amount An amount - */ - public void setAmount(int amount) - { - this.amount = amount; - } - - /** - * Get the MaterialData of the item - * @return A MaterialData - */ - public MaterialData getData() - { - return new MaterialData(id, data == null ? (byte) 0 : data); - } - - /** - * Set the MaterialData of the item - * @param data A MaterialData - */ - public void setData(MaterialData data) - { - this.data = data.getData(); - } - - /** - * Get the durability of the item - * @return The item durability - */ - public short getDurability() - { - return durability; - } - - /** - * Set the durability of the item - * @param durability An item durability - */ - public void setDurability(short durability) - { - this.durability = durability; - } - - /** - * Convert this InventoryItem to an ItemStack representation - * @return An ItemStack representation of this InventoryItem, or null if the type id is -1 - */ - public ItemStack toItemStack() - { - if (id == -1) - return null; - - ItemStack stack = new ItemStack(id, amount, durability); - - if (data != null) - stack.setData(getData()); - - return stack; - } -} diff --git a/src/com/garbagemule/MobArena/util/ItemParser.java b/src/com/garbagemule/MobArena/util/ItemParser.java index 979f6af..0dff503 100644 --- a/src/com/garbagemule/MobArena/util/ItemParser.java +++ b/src/com/garbagemule/MobArena/util/ItemParser.java @@ -1,102 +1,223 @@ package com.garbagemule.MobArena.util; -import java.util.LinkedList; +import java.util.ArrayList; import java.util.List; +import java.util.Map.Entry; import org.bukkit.DyeColor; import org.bukkit.Material; +import org.bukkit.enchantments.Enchantment; import org.bukkit.inventory.ItemStack; +import org.bukkit.material.MaterialData; + +import com.garbagemule.MobArena.MobArena; public class ItemParser { - public static List parseItems(String s) - { - List result = new LinkedList(); + public static String parseString(ItemStack... stacks) { + String result = ""; - String[] items = s.split(","); - for (String item : items) - { - ItemStack stack = parseItem(item.trim()); - if (stack != null) - result.add(stack); + // Parse each stack + for (ItemStack stack : stacks) { + if (stack == null || stack.getTypeId() == 0) continue; + + result += ", " + parseString(stack); + } + + // Trim off the leading ', ' if it is there + if (!result.equals("")) { + result = result.substring(2); } return result; } - public static ItemStack parseItem(String item) - { + public static String parseString(ItemStack stack) { + if (stack.getTypeId() == 0) return null; + + // part + String type = stack.getType().toString().toLowerCase(); + + // part + MaterialData md = stack.getData(); + byte data = (md != null ? md.getData() : 0); + + // Take wool into account + if (stack.getType() == Material.WOOL) { + data = (byte) (15 - data); + } + + // part + int amount = stack.getAmount(); + + // Enchantments + String enchantments = ""; + for (Entry entry : stack.getEnchantments().entrySet()) { + int id = entry.getKey().getId(); + int lvl = entry.getValue(); + + // :; + enchantments += "; " + id + ":" + lvl; + } + + // Trim off the leading ';' if it is there + if (!enchantments.equals("")) { + enchantments = enchantments.substring(2); + } + + // + String result = type; + + // (:) + if (data != 0) { + result += ":" + data; + } + + // ((:):) - force if there is data + if (amount > 1 || data != 0) { + result += ":" + amount; + } + + // ((:):) (:(;:(; ... ))) + if (!enchantments.equals("")) { + result += " " + enchantments; + } + + return result; + } + + public static List parseItems(String s) { + if (s == null) { + return new ArrayList(1); + } + + String[] items = s.split(","); + List result = new ArrayList(items.length); + + for (String item : items) { + ItemStack stack = parseItem(item.trim()); + if (stack != null) { + result.add(stack); + } + } + + return result; + } + + public static ItemStack parseItem(String item) { if (item == null || item.equals("")) return null; - String[] parts = item.split(":"); - if (parts.length == 1) - return singleItem(parts[0]); - if (parts.length == 2) - return withAmount(parts[0], parts[1]); - if (parts.length == 3) - return withDataAndAmount(parts[0], parts[1], parts[2]); + // Check if the item has enchantments. + String[] space = item.split(" "); + String[] parts = (space.length == 2 ? space[0].split(":") : item.split(":")); - return null; + ItemStack result = null; + + switch (parts.length) { + case 1: + result = singleItem(parts[0]); + break; + case 2: + result = withAmount(parts[0], parts[1]); + break; + case 3: + result = withDataAndAmount(parts[0], parts[1], parts[2]); + break; + } + + if (space.length == 2) { + addEnchantments(result, space[1]); + } + + return result; } - private static ItemStack singleItem(String item) - { + private static ItemStack singleItem(String item) { + if (item.matches("\\$[1-9][0-9]*")) { + int amount = Integer.parseInt(item.substring(1)); + return new ItemStack(MobArena.ECONOMY_MONEY_ID, amount); + } Material m = getMaterial(item); - return m == null ? null : new ItemStack(m); + return m == null ? null : new ItemStack(m,1); } - private static ItemStack withAmount(String item, String amount) - { + private static ItemStack withAmount(String item, String amount) { Material m = getMaterial(item); int a = getAmount(amount); return m == null ? null : new ItemStack(m,a); } - private static ItemStack withDataAndAmount(String item, String data, String amount) - { + private static ItemStack withDataAndAmount(String item, String data, String amount) { Material m = getMaterial(item.toUpperCase()); - byte d = getData(data); + short d = getData(data, m); int a = getAmount(amount); - if (m == null) + if (m == null) { return null; + } - if (m.getId() == 35) + if (m.getId() == 35) { d = (byte) (15-d); + } - return new ItemStack(m,a,(short)0,d); + return new ItemStack(m,a,d); } - private static Material getMaterial(String item) - { - if (item.matches("[0-9]*")) + private static Material getMaterial(String item) { + if (item.matches("[0-9]*")) { return Material.getMaterial(Integer.parseInt(item)); + } return Material.getMaterial(item.toUpperCase()); } - private static int getAmount(String amount) - { - if (amount.matches("[1-9][0-9]*")) + private static int getAmount(String amount) { + if (amount.matches("[1-9][0-9]*")) { return Integer.parseInt(amount); + } return 1; } - private static byte getData(String data) - { - DyeColor dye = null; - - if (data.matches("[0-9]+")) - { - dye = DyeColor.getByData(Byte.parseByte(data)); - return dye == null ? 0 : dye.getData(); + private static short getData(String data, Material m) { + // If ink sack or wool, parse wisely. + if (m == Material.INK_SACK || m == Material.WOOL) { + // Ink sacks must be offset. + byte offset = (m == Material.INK_SACK ? (byte) 15 : (byte) 0); + + DyeColor dye = (data.matches("[0-9]+")) ? + DyeColor.getByData((byte) Math.abs(offset - Integer.parseInt(data))) : + DyeColor.valueOf(data.toUpperCase()); + + return (short) Math.abs(offset - dye.getData()); } - else - { - dye = Enums.getEnumFromString(DyeColor.class, data); - return dye == null ? 0 : (byte) (15-dye.getData()); + + return Short.parseShort(data); + } + + private static void addEnchantments(ItemStack stack, String list) { + String[] parts = list.split(";"); + + for (String ench : parts) { + addEnchantment(stack, ench.trim()); } } + + private static void addEnchantment(ItemStack stack, String ench) { + String[] parts = ench.split(":"); + if (parts.length != 2 || !(parts[0].matches("[0-9]*") && parts[1].matches("[0-9]*"))) { + return; + } + + int id = Integer.parseInt(parts[0]); + int lvl = Integer.parseInt(parts[1]); + + Enchantment e = Enchantment.getById(id); + if (e == null) {// || !e.canEnchantItem(stack) || lvl > e.getMaxLevel() || lvl < e.getStartLevel()) { + return; + } + //stack.addEnchantment(e, lvl); + stack.addUnsafeEnchantment(e, lvl); + } } diff --git a/src/com/garbagemule/MobArena/util/MutableInt.java b/src/com/garbagemule/MobArena/util/MutableInt.java new file mode 100644 index 0000000..e321403 --- /dev/null +++ b/src/com/garbagemule/MobArena/util/MutableInt.java @@ -0,0 +1,31 @@ +package com.garbagemule.MobArena.util; + +public class MutableInt +{ + private int value; + + public MutableInt(int value) { + this.value = value; + } + + public MutableInt() { + this(0); + } + + public void add(int amount) { + this.value += amount; + } + + public void inc() { + this.value++; + } + + public int value() { + return value; + } + + @Override + public String toString() { + return "" + value; + } +} diff --git a/src/com/garbagemule/MobArena/util/TextUtils.java b/src/com/garbagemule/MobArena/util/TextUtils.java index 8b3dcb2..9e14f2b 100644 --- a/src/com/garbagemule/MobArena/util/TextUtils.java +++ b/src/com/garbagemule/MobArena/util/TextUtils.java @@ -53,4 +53,12 @@ public class TextUtils return s.substring(0, length); } public static String truncate(String s) { return truncate(s, 15); } + + public static String camelCase(String s) { + if (s == null || s.length() < 2) + return null; + + String firstLetter = s.substring(0,1).toUpperCase(); + return firstLetter + s.substring(1).toLowerCase(); + } } diff --git a/src/com/garbagemule/MobArena/util/VersionChecker.java b/src/com/garbagemule/MobArena/util/VersionChecker.java new file mode 100644 index 0000000..b0ee7e9 --- /dev/null +++ b/src/com/garbagemule/MobArena/util/VersionChecker.java @@ -0,0 +1,90 @@ +package com.garbagemule.MobArena.util; + +import java.net.HttpURLConnection; +import java.net.URI; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.garbagemule.MobArena.MobArena; + +public class VersionChecker +{ + public static String site = "http://forums.bukkit.org/threads/19144/"; + + /** + * Check if the current plugin version is the latest version. + * @param plugin a MobArena instance + * @return false, if the version is not the latest, true otherwise + */ + public static boolean isLatest(MobArena plugin) { + if (!plugin.getMAConfig().getBoolean("global-settings.update-notification", false)) { + return true; + } + + try { + // Make a URI of the site address + URI baseURI = new URI(site); + + // Open the connection and don't redirect. + HttpURLConnection con = (HttpURLConnection) baseURI.toURL().openConnection(); + con.setConnectTimeout(5000); + con.setInstanceFollowRedirects(false); + + String header = con.getHeaderField("Location"); + + // If something's wrong with the connection... + if (header == null) { + return true; + } + + // Otherwise, grab the location header to get the real URI. + String url = new URI(con.getHeaderField("Location")).toString(); + + // Set up the regex and matcher + Pattern regex = Pattern.compile("v([0-9]+-)*[0-9]+"); + Matcher matcher = regex.matcher(url); + if (!matcher.find()) { + return true; + } + + String thisVersion = plugin.getDescription().getVersion(); + String forumVersion = matcher.group().substring(1).replace("-", "."); + + return isLatest(thisVersion, forumVersion); + } + catch (Exception e) { + e.printStackTrace(); + } + + return true; + } + + /** + * Check if thisVersion is newer than or equal to forumVersion + * @param thisVersion a version string + * @param forumVersion a version string + * @return true, if thisVersion is newer than or equal to forumVersion, false otherwise + */ + public static boolean isLatest(String thisVersion, String forumVersion) { + String[] forumParts = forumVersion.split("\\."); + String[] thisParts = thisVersion.split("\\."); + + int current, forum; + boolean thisIsNewer = false; + + for (int i = 0; i < Math.max(forumParts.length, thisParts.length); i++) { + forum = forumParts.length <= i ? 0 : Integer.parseInt(forumParts[i]); + current = thisParts.length <= i ? 0 : Integer.parseInt(thisParts[i]); + + if (forum < current) { + thisIsNewer = true; + } + + if (forum > current && !thisIsNewer) { + return false; + } + } + + return true; + } +} diff --git a/src/com/garbagemule/MobArena/util/classparsing/ClassIterationStrategy.java b/src/com/garbagemule/MobArena/util/classparsing/ClassIterationStrategy.java deleted file mode 100644 index b0baded..0000000 --- a/src/com/garbagemule/MobArena/util/classparsing/ClassIterationStrategy.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.garbagemule.MobArena.util.classparsing; - -import java.util.Collection; - -public interface ClassIterationStrategy -{ - /** - * Given a package, e.g. com.garbagemule.MobArena.commands.user, the - * concrete strategy will return a collection of qualified class names - * either from a directory or a jar file. - * @param packagePath path from which to extract classes - * @return a list of qualified class names or null - */ - public Collection getClassesFromPackage(String packagePath); -} diff --git a/src/com/garbagemule/MobArena/util/classparsing/ClassParser.java b/src/com/garbagemule/MobArena/util/classparsing/ClassParser.java deleted file mode 100644 index e194614..0000000 --- a/src/com/garbagemule/MobArena/util/classparsing/ClassParser.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.garbagemule.MobArena.util.classparsing; - -import java.util.*; - -public class ClassParser -{ - private ClassIterationStrategy strategy; - - public ClassParser(ClassIterationStrategy strategy) { - this.strategy = strategy; - } - - /** - * Using an iteration strategy provided in the constructor, this method tries - * to iterate through all classes within a given "package". - * @param packagePath a package path, e.g. com.garbagemule.MobArena.commands.user - * @return a list of Class objects - */ - public Collection> getClasses(String packagePath) { - Collection> result = new LinkedList>(); - - for (String classname : strategy.getClassesFromPackage(packagePath)) { - Class c = makeClass(classname); - - if (c != null) { - result.add(c); - } - } - - return result; - } - - /** - * Get a class using its qualified (full package) name. - * @param qualifiedName qualified name of a class - * @return a Class object, or null if the class could not be made. - */ - private static Class makeClass(String qualifiedName) { - try { - return Class.forName(qualifiedName); - } - catch (Exception e) { - return null; - } - } -} diff --git a/src/com/garbagemule/MobArena/util/classparsing/DirClassIterationStrategy.java b/src/com/garbagemule/MobArena/util/classparsing/DirClassIterationStrategy.java deleted file mode 100644 index 177ac31..0000000 --- a/src/com/garbagemule/MobArena/util/classparsing/DirClassIterationStrategy.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.garbagemule.MobArena.util.classparsing; - -import java.io.*; -import java.util.*; - -public class DirClassIterationStrategy implements ClassIterationStrategy -{ - private File baseDir; - - /** - * Dir iterator. The input file must be a directory, whose - * contents are iterated over upon calling the implemented - * method. This dir could be bin/ or build/. - * @param file a directory - * @throws Exception - */ - public DirClassIterationStrategy(File baseDir) throws Exception { - this.baseDir = baseDir; - } - - @Override - public Collection getClassesFromPackage(String packagePath) { - // The resulting list. - Collection result = new LinkedList(); - - // Convert to an actual path. - String path = packageToPath(packagePath); - - // Make a new dir from it. - File dir = new File(baseDir, path); - - for (File f : dir.listFiles()) { - String name = f.getName(); - String absolutePath = f.getAbsolutePath(); - - if (absolutePath.contains(path) && name.endsWith(".class")) { - result.add( packagePath + "." + stripExtension(name) ); - } - } - - return result; - } - - private String stripExtension(String file) { - int dot = file.lastIndexOf("."); - return file.substring(0, dot); - } - - private String packageToPath(String path) { - return path.replace(".", File.separator); - } -} diff --git a/src/com/garbagemule/MobArena/util/classparsing/JarClassIterationStrategy.java b/src/com/garbagemule/MobArena/util/classparsing/JarClassIterationStrategy.java deleted file mode 100644 index f7713b9..0000000 --- a/src/com/garbagemule/MobArena/util/classparsing/JarClassIterationStrategy.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.garbagemule.MobArena.util.classparsing; - -import java.io.*; -import java.util.*; -import java.util.jar.*; - -public class JarClassIterationStrategy implements ClassIterationStrategy -{ - private JarFile jarFile; - - /** - * Jar iterator. The input file is turned into a JarFile object, - * which is later used to extract a list of entries to iterate - * over. The implemented method filters through the entries and - * returns any matches. - * @param file a jar file - * @throws Exception - */ - public JarClassIterationStrategy(File file) throws Exception { - this.jarFile = new JarFile(file); - } - - @Override - public Collection getClassesFromPackage(String packagePath) { - // The resulting list. - Collection result = new LinkedList(); - - // Convert to an actual path. - String path = packageToPath(packagePath); - - // Grab the entries from the jar file. - Enumeration entries = jarFile.entries(); - - /* Iterate through all the entries in the jar file, and - * if a file starts with the package path and ends with - * .class, we have a match, in which case we strip the - * extension and convert to a package representation. */ - while (entries.hasMoreElements()) { - String entry = entries.nextElement().getName(); - - if (entry.startsWith(path) && entry.endsWith(".class")) { - result.add( pathToPackage( stripExtension(entry) ) ); - } - } - - // Return the resulting list. - return result; - } - - private String stripExtension(String file) { - int dot = file.lastIndexOf("."); - return file.substring(0, dot); - } - - private String packageToPath(String path) { - return path.replace(".", "/"); - } - - private String pathToPackage(String path) { - return path.replace("/", "."); - } -} diff --git a/src/com/garbagemule/MobArena/util/config/Config.java b/src/com/garbagemule/MobArena/util/config/Config.java new file mode 100644 index 0000000..41a3bcd --- /dev/null +++ b/src/com/garbagemule/MobArena/util/config/Config.java @@ -0,0 +1,446 @@ +package com.garbagemule.MobArena.util.config; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.inventory.ItemStack; + +/** + * Wrapper class for Bukkit's Configuration classes. + * + * The motivation for this class is two-fold: + * + * 1) Provide a means of keeping a reference to the physical disk file + * in the same class as the YamlConfiguration for easy load and save. + * 2) Speed up the access times for the YamlConfiguration by loading all + * values into maps, as to avoid local fields in certain classes. + * + * The specific getters (getInteger, getBoolean, etc.) never call methods on + * the YamlConfiguration. Instead, they interact only with the value maps, + * which speeds up the access times 20-fold. The generic getter (get), does, + * however, interact with the YamlConfiguration (for now). + * + * The mutators (set, remove, etc.) interact with both the YamlConfiguration + * and the value maps for consistency. This means modifications become slightly + * slower, but the difference is neglegible. + * + * @author garbagemule, slipcor + * + * Use this class however you see fit, but please leave this description in, + * as to not unrightfully take credit for our work :) + */ +public class Config +{ + private YamlConfiguration config; + private File configFile; + private Map booleans; + private Map ints; + private Map doubles; + private Map strings; + private Map items; + + /** + * Create a new Config instance that uses the specified file for + * loading and saving. + * @param configFile a YAML file + */ + public Config(File configFile) { + this.config = new YamlConfiguration(); + this.configFile = configFile; + + this.booleans = new HashMap(); + this.ints = new HashMap(); + this.doubles = new HashMap(); + this.strings = new HashMap(); + this.items = new HashMap(); + + this.config.options().indent(4); + } + + /** + * Load the config-file into the YamlConfiguration, and then populate + * the value maps. + * @return true, if the load succeeded, false otherwise. + */ + public boolean load() { + try { + if (!configFile.exists()) { + configFile.createNewFile(); + } + config.load(configFile); + reloadMaps(); + return true; + } + catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * Iterates through all keys in the config-file, and populates the + * value maps. Boolean values are stored in the booleans-map, Strings + * in the strings-map, etc. + */ + public void reloadMaps() { + for (String s : config.getKeys(true)) { + Object o = config.get(s); + + if (o instanceof Boolean) { + booleans.put(s, (Boolean) o); + } else if (o instanceof Integer) { + ints.put(s, (Integer) o); + } else if (o instanceof Double) { + doubles.put(s, (Double) o); + } else if (o instanceof ItemStack) { + items.put(s, (ItemStack) o); + } else if (o instanceof String) { + strings.put(s, (String) o); + } + } + } + + /** + * Save the YamlConfiguration to the config-file. + * @return true, if the save succeeded, false otherwise. + */ + public boolean save() { + try { + config.save(configFile); + load(); // enforce consistency + return true; + } + catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * Get the header of the config-file. + * @return the header + */ + public String getHeader() { + return config.options().header(); + } + + /** + * Set the header of the config-file. + * @param header the header + */ + public void setHeader(String header) { + config.options().header(header); + } + + + + /////////////////////////////////////////////////////////////////////////// + // // + // GETTERS // + // // + /////////////////////////////////////////////////////////////////////////// + + /** + * Get the YamlConfiguration associated with this Config instance. + * Note that changes made directly to the YamlConfiguration will cause an + * inconsistency with the value maps unless reloadMaps() is called. + * @return the YamlConfiguration of this Config instance + */ + public YamlConfiguration getYamlConfiguration() { + return config; + } + + /** + * Grab a section of this Config. + * @param node + * @return + */ + public ConfigSection getConfigSection(String node) { + if (get(node) != null) { + return new ConfigSection(this, node); + } + return null; + } + + /** + * Retrieve a value from the YamlConfiguration. + * @param path the path of the value + * @return the value of the path + */ + public Object get(String path) { + return config.get(path); + } + + /** + * Retrieve a boolean from the value maps. + * @param path the path of the value + * @return the boolean value of the path if the path exists, false otherwise + */ + public boolean getBoolean(String path) { + return getBoolean(path, false); + } + + /** + * Retrieve a boolean from the value maps. + * @param path the path of the value + * @param def a default value to return if the value was not in the map + * @return the boolean value of the path if it exists, def otherwise + */ + public boolean getBoolean(String path, boolean def) { + Boolean result = booleans.get(path); + return (result != null ? result : def); + } + + /** + * Retrieve an int from the value maps. + * @param path the path of the value + * @return the int value of the path if the path exists, 0 otherwise + */ + public int getInt(String path) { + return getInt(path, 0); + } + + /** + * Retrieve an int from the value maps. + * @param path the path of the value + * @param def a default value to return if the value was not in the map + * @return the int value of the path if it exists, def otherwise + */ + public int getInt(String path, int def) { + Integer result = ints.get(path); + return (result != null ? result : def); + } + + /** + * Retrieve a double from the value maps. + * @param path the path of the value + * @return the double value of the path if the path exists, 0D otherwise + */ + public double getDouble(String path) { + return getDouble(path, 0D); + } + + /** + * Retrieve a double from the value maps. + * @param path the path of the value + * @param def a default value to return if the value was not in the map + * @return the double value of the path if it exists, def otherwise + */ + public double getDouble(String path, double def) { + Double result = doubles.get(path); + return (result != null ? result : def); + } + + /** + * Retrieve a string from the value maps. + * @param path the path of the value + * @return the string value of the path if the path exists, null otherwise + */ + public String getString(String path) { + return getString(path, null); + } + + /** + * Retrieve a string from the value maps. + * @param path the path of the value + * @param def a default value to return if the value was not in the map + * @return the string value of the path if it exists, def otherwise + */ + public String getString(String path, String def) { + String result = strings.get(path); + return (result != null ? result : def); + } + + public Location getLocation(String path, World world) { + return getLocation(path, world, null); + } + + public Location getLocation(String path, World world, Location def) { + String string = getString(path); + + if (string == null) + return def; + + return parseLocation(world, string); + } + + public ItemStack getItemStack(String path) { + return getItemStack(path, null); + } + + public ItemStack getItemStack(String path, ItemStack def) { + ItemStack result = items.get(path); + return (result != null ? result : def); + } + + public Set getKeys(String path) { + if (config.get(path) == null) + return null; + + ConfigurationSection section = config.getConfigurationSection(path); + if (section == null) + return null; + + return section.getKeys(false); + } + + @SuppressWarnings("unchecked") + public List getStringList(String path, List def) { + if (config.get(path) == null) + return def != null ? def : new ArrayList(); + + List list = config.getStringList(path); + return (List) list; + } + + + + /////////////////////////////////////////////////////////////////////////// + // // + // MUTATORS // + // // + /////////////////////////////////////////////////////////////////////////// + + /** + * Set the value of the given path in both the value maps and the + * YamlConfiguration. Note that this will only properly put the value + * in its relevant value map, if it is of one of the supported types. + * The method can also be used to remove values from their maps and + * the YamlConfiguration by passing null for the value. + * @param path the path on which to set the value + * @param value the value to set + */ + public void set(String path, Object value) { + if (value instanceof Boolean) { + booleans.put(path, (Boolean) value); + } else if (value instanceof Integer) { + ints.put(path, (Integer) value); + } else if (value instanceof Double) { + doubles.put(path, (Double) value); + } else if (value instanceof ItemStack) { + items.put(path, (ItemStack) value); + } else if (value instanceof String) { + strings.put(path, (String) value); + } else if (value instanceof Location) { + value = locationToString((Location) value); + strings.put(path, value.toString()); + } + + if (value == null) { + booleans.remove(path); + ints.remove(path); + doubles.remove(path); + strings.remove(path); + items.remove(path); + } + + config.set(path, value); + } + + /** + * Remove the node at the given path. Uses the set() method with null + * as the value. + * @param path the path of the node to remove + */ + public void remove(String path) { + this.set(path, null); + } + + + + /////////////////////////////////////////////////////////////////////////// + // // + // UTILITY METHODS // + // // + /////////////////////////////////////////////////////////////////////////// + + /** + * Parse an input string on the form "x,y,z" and an input World to create + * a Location. This method will only accept strings of the specified form. + * @param world the World in which the Location exists + * @param coords a string on the form "x,y,z" + * @return a Location in the given world with the given coordinates + */ + public static Location parseSimpleLocation(World world, String coords) { + String[] parts = coords.split(","); + if (parts.length != 3) + throw new IllegalArgumentException("Input string must contain only x, y, and z"); + + Integer x = parseInteger(parts[0]); + Integer y = parseInteger(parts[1]); + Integer z = parseInteger(parts[2]); + + if (x == null || y == null || z == null) + throw new NullPointerException("Some of the parsed values are null!"); + + return new Location(world, x, y, z); + } + + /** + * Parse an input string on the form "x,y,z,yaw,pitch" and an input World + * to create a Location. This method will only accept strings of the + * specified form. + * @param world the World in which the Location exists + * @param coords a string on the form "x,y,z,yaw,pitch" + * @return a Location in the given world with the given coordinates + */ + public static Location parseLocation(World world, String coords) { + String[] parts = coords.split(","); + if (parts.length != 5) + throw new IllegalArgumentException("Input string must contain x, y, z, yaw and pitch"); + + Integer x = parseInteger(parts[0]); + Integer y = parseInteger(parts[1]); + Integer z = parseInteger(parts[2]); + Float yaw = parseFloat(parts[3]); + Float pitch = parseFloat(parts[4]); + + if (x == null || y == null || z == null || yaw == null || pitch == null) + throw new NullPointerException("Some of the parsed values are null!"); + + return new Location(world, x, y, z, yaw, pitch); + } + + /** + * Create a String representation of a Location object. + * @param loc a Location + * @return a String of the form "x,y,z,yaw,pitch" + */ + public static String locationToString(Location loc) { + StringBuffer result = new StringBuffer(); + + result.append(loc.getBlockX() + ","); + result.append(loc.getBlockY() + ","); + result.append(loc.getBlockZ() + ","); + result.append(loc.getYaw() + ","); + result.append(loc.getPitch()); + + return result.toString(); + } + + private static Integer parseInteger(String s) { + try { + return Integer.parseInt(s.trim()); + } + catch (Exception e) { + return null; + } + } + + private static Float parseFloat(String s) { + try { + return Float.parseFloat(s.trim()); + } + catch (Exception e) { + return null; + } + } +} diff --git a/src/com/garbagemule/MobArena/util/config/ConfigSection.java b/src/com/garbagemule/MobArena/util/config/ConfigSection.java new file mode 100644 index 0000000..f155d03 --- /dev/null +++ b/src/com/garbagemule/MobArena/util/config/ConfigSection.java @@ -0,0 +1,97 @@ +package com.garbagemule.MobArena.util.config; + +import java.util.List; +import java.util.Set; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.inventory.ItemStack; + +import com.garbagemule.MobArena.util.config.Config; + +public class ConfigSection +{ + private Config config; + private String path; + + public ConfigSection(Config config, String path) { + this.config = config; + this.path = (path.endsWith(".") ? path : path + "."); + } + + public Config getParent() { + return config; + } + + public ConfigSection getConfigSection(String path) { + return new ConfigSection(config, this.path + path); + } + + public Object get(String node) { + return config.get(path + node); + } + + public int getInt(String node) { + return config.getInt(path + node); + } + + public int getInt(String node, int def) { + return config.getInt(path + node, def); + } + + public double getDouble(String node) { + return config.getDouble(path + node); + } + + public double getDouble(String node, double def) { + return config.getDouble(path + node, def); + } + + public boolean getBoolean(String node) { + return config.getBoolean(path + node); + } + + public boolean getBoolean(String node, boolean def) { + return config.getBoolean(path + node, def); + } + + public String getString(String node) { + return config.getString(path + node); + } + + public String getString(String node, String def) { + return config.getString(path + node, def); + } + + public Location getLocation(String node, World world) { + return config.getLocation(path + node, world); + } + + public Location getLocation(String node, World world, Location def) { + return config.getLocation(path + node, world, def); + } + + public ItemStack getItemStack(String path) { + return config.getItemStack(path); + } + + public ItemStack getItemStack(String path, ItemStack def) { + return config.getItemStack(path, def); + } + + public Set getKeys() { + return config.getKeys(path); + } + + public Set getKeys(String node) { + return config.getKeys(path + node); + } + + public List getStringList(String node, List def) { + return config.getStringList(path + node, def); + } + + public void set(String node, Object value) { + config.set(path + node, value); + } +} diff --git a/src/com/garbagemule/MobArena/util/config/ConfigUtils.java b/src/com/garbagemule/MobArena/util/config/ConfigUtils.java new file mode 100644 index 0000000..f7627d2 --- /dev/null +++ b/src/com/garbagemule/MobArena/util/config/ConfigUtils.java @@ -0,0 +1,79 @@ +package com.garbagemule.MobArena.util.config; + +import java.util.Set; + +import org.bukkit.configuration.file.YamlConfiguration; + +import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.util.FileUtils; + +public class ConfigUtils +{ + public static void addMissingNodes(MobArena plugin, Config config, String path, String filename) { + assertNodes(plugin, config, path, filename, true); + } + + public static void replaceAllNodes(MobArena plugin, Config config, String path, String filename) { + assertNodes(plugin, config, path, filename, false); + } + + private static void assertNodes(MobArena plugin, Config config, String path, String filename, boolean keepOthers) { + // Grab the section that the path is pointing to. + ConfigSection section = config.getConfigSection(path); + + // If null, create the node. + if (section == null) { + config.set(path, ""); + section = config.getConfigSection(path); + } + + // Extract the yml file. + YamlConfiguration ymlConfig = FileUtils.getConfig(plugin, filename); + + // Assert the nodes. + assertNodes(section, ymlConfig, keepOthers); + } + + private static void assertNodes(ConfigSection config, YamlConfiguration ymlConfig, boolean keepOthers) { + if (config == null || ymlConfig == null) return; + + // Grab the default keys. + Set keys = ymlConfig.getKeys(false); + if (keys == null || keys.isEmpty()) return; + + // First ensure that all default nodes exist + for (String key : keys) { + if (config.get(key) == null) { + Object o = ymlConfig.get(key); + config.set(key, o); + } + } + + // If any other nodes in the config should remain, return + if (keepOthers) return; + + // Otherwise, grab all the current nodes. + Set oldKeys = config.getKeys(); + if (oldKeys == null || oldKeys.isEmpty()) return; + + // Remove all nodes that aren't in the defaults. + for (String old : oldKeys) { + if (!keys.contains(old)) { + config.set(old, null); + } + } + } + + public static String waveRewardList(String arena, String type) { + return "arenas." + arena + ".rewards.waves." + type; + } + + public static String waveReward(String arena, String type, int wave) { + return "arenas." + arena + ".rewards.waves." + type + "." + wave; + } + + public static String waveReward(Arena arena, String type, int wave) { + return "arenas." + arena.configName() + ".rewards.waves." + type + "." + wave; + } +} diff --git a/src/com/garbagemule/MobArena/util/data/PlainText.java b/src/com/garbagemule/MobArena/util/data/PlainText.java deleted file mode 100644 index c0cf907..0000000 --- a/src/com/garbagemule/MobArena/util/data/PlainText.java +++ /dev/null @@ -1,155 +0,0 @@ -package com.garbagemule.MobArena.util.data; - -import java.io.File; -import java.io.FileWriter; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.bukkit.entity.Player; - -import com.garbagemule.MobArena.ArenaLog; -import com.garbagemule.MobArena.ArenaPlayer; -import com.garbagemule.MobArena.MAUtils; -import com.garbagemule.MobArena.MobArena; -import com.garbagemule.MobArena.util.TextUtils; - -public class PlainText -{ - public static void saveSessionData(ArenaLog log) - { - File dir = new File(MobArena.arenaDir, log.getArena().configName()); - if (!dir.exists()) dir.mkdirs(); - - // General information - List toWrite = new LinkedList(); - toWrite.add("Start: " + log.getStartTime()); - toWrite.add("End: " + log.getEndTime()); - toWrite.add("Duration: " + log.getDuration()); - toWrite.add("Last wave: " + log.getLastWave()); - toWrite.add(" "); - - int classLength = longestClassName(log.distribution.keySet()); - int classCount = log.distribution.keySet().size(); - int playerCount = log.players.keySet().size(); - - // Class distribution - toWrite.add("Class Distribution: " + classCount + " classes"); - toWrite.addAll(getClassDistribution(log.distribution, playerCount, classLength)); - toWrite.add(" "); - - // Player data - toWrite.add("Player Data: " + playerCount + " players"); - toWrite.addAll(getPlayerData(log.players, classLength)); - - // Serialize! - serialize(log, dir, "lastsession.txt", toWrite); - } - - public static void updateArenaTotals(ArenaLog log) - { - // Grab the Configuration - //Configuration totals = Totals.getArenaTotals(log.arena); - - // Parse shit - - - // Serialize - - } - - private static void serialize(ArenaLog log, File dir, String filename, List toWrite) - { - try - { - File file = new File(dir, filename); - if (!file.exists()) file.createNewFile(); - - FileWriter fw = new FileWriter(file); - String linebreak = System.getProperty("line.separator"); - for (String s : toWrite) - { - fw.write(s); - fw.write(linebreak); - } - fw.close(); - } - catch (Exception e) - { - e.printStackTrace(); - MobArena.warning("Problem saving session data for arena '" + log.getArena().configName() + "'"); - } - } - - private static List getClassDistribution(Map map, int playerCount, int classLength) - { - List result = new LinkedList(); - - // Add each entry - class: # (percentage%) - for (Map.Entry entry : map.entrySet()) - { - StringBuffer buffy = new StringBuffer(classLength + 15); - - buffy.append("- "); - buffy.append(TextUtils.padRight(entry.getKey() + ":", classLength + 3)); // : - buffy.append(TextUtils.padLeft(entry.getValue().toString(), 2)); // - buffy.append("(" + (entry.getValue()*100/playerCount) + "%)"); // (%) - - result.add(buffy.toString()); - } - - return result; - } - - private static List getPlayerData(Map map, int classLength) - { - List result = new LinkedList(); - String pad = " "; - - // Padding variables; +2 for extra padding - int NAME = 12, CLASS = classLength, WAVE = 4, KILLS = 5, DMGDONE = 7, DMGTAKEN = 8, ACCURACY = 8; - result.add(" " + TextUtils.padRight("NAME", NAME+2) + - TextUtils.padRight("CLASS", CLASS+2) + - TextUtils.padRight("WAVE", WAVE+2) + - TextUtils.padRight("KILLS", KILLS+2) + - TextUtils.padRight("DMGDONE", DMGDONE+2) + - TextUtils.padRight("DMGTAKEN", DMGTAKEN+2) + - TextUtils.padRight("ACCURACY", ACCURACY+2) + - "REWARDS"); - - // Add each player - name class wave dmgdone dmgtaken accuracy rewards - for (Map.Entry entry : map.entrySet()) - { - Player p = entry.getKey(); - ArenaPlayer ap = entry.getValue(); - StringBuffer buffy = new StringBuffer(80); - - String name = (p.getName().length() <= NAME) ? p.getName() : p.getName().substring(0, NAME+1); - buffy.append("- "); - buffy.append(TextUtils.padRight(name, NAME)); buffy.append(pad); - buffy.append(TextUtils.padRight(ap.getClassName(), CLASS)); buffy.append(pad); - buffy.append(TextUtils.padLeft(ap.getStats().lastWave, WAVE)); buffy.append(pad); - buffy.append(TextUtils.padLeft(ap.getStats().kills, KILLS)); buffy.append(pad); - buffy.append(TextUtils.padLeft(ap.getStats().dmgDone, DMGDONE)); buffy.append(pad); - buffy.append(TextUtils.padLeft(ap.getStats().dmgTaken, DMGTAKEN)); buffy.append(pad); - buffy.append(TextUtils.padLeft(((ap.getStats().swings != 0) ? ap.getStats().hits*100/ap.getStats().swings : 0), ACCURACY-1)); buffy.append("%"); buffy.append(pad); - buffy.append(MAUtils.listToString(ap.rewards)); - - result.add(buffy.toString()); - } - - return result; - } - - private static int longestClassName(Collection names) - { - int result = 0; - - for (String c : names) - if (c.length() > result) - result = c.length(); - - return result; - } -} diff --git a/src/com/garbagemule/MobArena/util/data/Totals.java b/src/com/garbagemule/MobArena/util/data/Totals.java deleted file mode 100644 index 087ac8d..0000000 --- a/src/com/garbagemule/MobArena/util/data/Totals.java +++ /dev/null @@ -1,158 +0,0 @@ -package com.garbagemule.MobArena.util.data; - -import java.io.File; - -import org.bukkit.inventory.ItemStack; -import org.bukkit.util.config.Configuration; - -import com.garbagemule.MobArena.Arena; -import com.garbagemule.MobArena.ArenaLog; -import com.garbagemule.MobArena.ArenaPlayer; -import com.garbagemule.MobArena.MAUtils; -import com.garbagemule.MobArena.MobArena; -import com.garbagemule.MobArena.util.FileUtils; - -public class Totals -{ - private static final String totals_yml = "totals.yml"; - - /** - * Update the totals-file with the session data from the ArenaLog object - * @param log ArenaLog to update with - */ - public static void updateArenaTotals(ArenaLog log) - { - // Grab the configuration - Configuration totals = getArenaTotals(log.arena); - totals.load(); - - // General data - updateInt(totals, "general-info.total-games-played", 1, true); - updateInt(totals, "general-info.most-players", log.players.keySet().size(), false); - updateInt(totals, "general-info.highest-wave-reached", log.lastWave, false); - updateInt(totals, "general-info.total-monsters-killed", countKills(log), true); - updateDuration(totals, "general-info.total-duration", log.getDurationLong(), true); - updateDuration(totals, "general-info.longest-session-duration", log.getDurationLong(), false); - - // Classes - for (String c : log.arena.getClasses()) - { - // Array {kills, dmgDone, dmgTaken} - int[] a = getKillsAndDamageByClass(log, c); - updateInt(totals, "classes." + c + ".kills", a[0], true); - updateInt(totals, "classes." + c + ".damage-done", a[1], true); - updateInt(totals, "classes." + c + ".damage-taken", a[2], true); - updateInt(totals, "classes." + c + ".played", log.distribution.get(c), true); - } - - // Rewards - for (ArenaPlayer ap : log.players.values()) - { - for (ItemStack stack : ap.rewards) - { - boolean money = stack.getTypeId() == MobArena.ECONOMY_MONEY_ID; - updateInt(totals, "rewards." + (money ? "money" : stack.getType().toString().toLowerCase()), stack.getAmount(), true); - } - } - - // Players - for (ArenaPlayer ap : log.players.values()) - { - // Basic values - updateInt(totals,"players." + ap.player.getName() + ".games-played", 1, true); - updateInt(totals,"players." + ap.player.getName() + ".kills", ap.getStats().kills, true); - updateInt(totals,"players." + ap.player.getName() + ".damage-done", ap.getStats().dmgDone, true); - updateInt(totals,"players." + ap.player.getName() + ".damage-taken", ap.getStats().dmgTaken, true); - updateInt(totals,"players." + ap.player.getName() + ".swings", ap.getStats().swings, true); - updateInt(totals,"players." + ap.player.getName() + ".hits", ap.getStats().hits, true); - - // Class count - updateInt(totals,"players." + ap.player.getName() + ".classes." + ap.className,1,true); - } - - // Save everything - totals.save(); - } - - /** - * Get or create a Configuration from the totals-file - * @param arena Arena to get or create a Configuration for - * @return Configuration from the arena's totals-file - */ - public static Configuration getArenaTotals(Arena arena) - { - // Create the folder if it doesn't exist. - File dir = new File(MobArena.arenaDir, arena.configName()); - if (!dir.exists()) dir.mkdirs(); - - File file = new File(dir, totals_yml); - if (!file.exists()) FileUtils.extractFile(dir, totals_yml); - - // Grab the totals-file and return the Configuration - return new Configuration(file); - } - - /** - * Update an integer in a config-file - * @param totals Configuration to alter - * @param node Node to alter - * @param b Integer for comparison - * @param increment If true, the node will be incremented by b, otherwise overwritten if greater - */ - private static void updateInt(Configuration totals, String node, int b, boolean increment) - { - int a = totals.getInt(node, 0); - - if (increment) totals.setProperty(node, a+b); - else if (b > a) totals.setProperty(node, b); - } - - /** - * Update a duration in a config-file - * @param totals Configuration to alter - * @param node Node to alter - * @param b Duration for comparison. This is a java.sql.Timestamp.getTime() long - * @param increment If true, the node will be incremented by b, otherwise overwritten if greater - */ - private static void updateDuration(Configuration totals, String node, long b, boolean increment) - { - long a = MAUtils.parseDuration(totals.getString(node, "0:00:00")); - - if (increment) totals.setProperty(node, MAUtils.getDuration(a+b)); - else if (b > a) totals.setProperty(node, MAUtils.getDuration(b)); - } - - /** - * Get total kills from an arena session - * @param log The ArenaLog to count kills in - * @return Total kills - */ - private static int countKills(ArenaLog log) - { - int kills = 0; - for (ArenaPlayer ap : log.players.values()) - kills += ap.getStats().kills; - return kills; - } - - /** - * Get a (dirty) int-array in the form {kills, damage done, damage taken} for a class - * @param log ArenaLog to count kills, damage done/taken from - * @param className The class to count for - * @return Resulting kills, damage done and damage taken in an int-array - */ - private static int[] getKillsAndDamageByClass(ArenaLog log, String className) - { - int kills = 0, dmgDone = 0, dmgTaken = 0; - for (ArenaPlayer ap : log.players.values()) - { - if (!ap.className.equals(className)) - continue; - - kills += ap.getStats().kills; - dmgDone += ap.getStats().dmgDone; - dmgTaken += ap.getStats().dmgTaken; - } - return new int[]{kills, dmgDone, dmgTaken}; - } -} diff --git a/src/com/garbagemule/MobArena/util/data/XML.java b/src/com/garbagemule/MobArena/util/data/XML.java deleted file mode 100644 index a0502e0..0000000 --- a/src/com/garbagemule/MobArena/util/data/XML.java +++ /dev/null @@ -1,182 +0,0 @@ -package com.garbagemule.MobArena.util.data; - -import java.io.File; -import java.io.FileOutputStream; -import java.util.List; -import java.util.Map; - -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.util.config.Configuration; -import org.jdom.Attribute; -import org.jdom.Document; -import org.jdom.Element; -//import org.jdom.Namespace; -import org.jdom.output.XMLOutputter; - -import com.garbagemule.MobArena.ArenaLog; -import com.garbagemule.MobArena.ArenaPlayer; -import com.garbagemule.MobArena.MobArena; - -public class XML -{ - public static void saveSessionData(ArenaLog log) - { - File dir = new File(MobArena.arenaDir, log.getArena().configName()); - if (!dir.exists()) dir.mkdirs(); - - // It's here if people want it. - //Namespace w = Namespace.getNamespace("com.garbagemule.MobArena"); - - // General info - Element ge = new Element("general-info"); - ge.addContent(new Element("start-time").addContent(log.getStartTime().toString())); - ge.addContent(new Element("end-time").addContent(log.getEndTime().toString())); - ge.addContent(new Element("duration").addContent(log.getDuration().toString())); - ge.addContent(new Element("last-wave").addContent(log.getLastWave() + "")); - - // Class distribution - Element cd = new Element("class-distribution"); - for (Map.Entry entry : log.distribution.entrySet()) - cd.addContent(new Element(entry.getKey()).addContent(entry.getValue() + "")); - - // Player data - Element pd = new Element("player-data"); - for (Map.Entry entry : log.players.entrySet()) - { - // Name as attribute - Element p = new Element("player").setAttribute(new Attribute("name", entry.getKey().getName())); - ArenaPlayer ap = entry.getValue(); - - p.addContent(new Element("last-wave").addContent(ap.getStats().lastWave + "")); - p.addContent(new Element("kills").addContent(ap.getStats().lastWave + "")); - p.addContent(new Element("damage-done").addContent(ap.getStats().dmgDone + "")); - p.addContent(new Element("damage-taken").addContent(ap.getStats().dmgTaken + "")); - p.addContent(new Element("swings").addContent(ap.getStats().swings + "")); - p.addContent(new Element("hits").addContent(ap.getStats().hits + "")); - - // Rewards - Element rw = new Element("rewards"); - for (ItemStack stack : ap.rewards) - rw.addContent(getReward(stack)); - - p.addContent(rw); - pd.addContent(p); - } - - // Add the main nodes - Element root = new Element("last-session"); - root.addContent(ge); - root.addContent(cd); - root.addContent(pd); - - // Create a new document - Document doc = new Document(); - doc.addContent(root); - - // Serialize! - serialize(log, dir, doc, "lastsession.xml"); - } - - public static void updateArenaTotals(ArenaLog log) - { - Configuration totals = Totals.getArenaTotals(log.arena); - totals.load(); - - // General data - Element gd = new Element("general-info"); - gd.addContent(new Element("total-games-played").addContent(totals.getInt("general-info.total-games-played", 0) + "")); - gd.addContent(new Element("most-players").addContent(totals.getInt("general-info.most-players", 0) + "")); - gd.addContent(new Element("highest-wave-reached").addContent(totals.getInt("general-info.highest-wave-reached", 0) + "")); - gd.addContent(new Element("total-monsters-killed").addContent(totals.getInt("general-info.total-monsters-killed", 0) + "")); - gd.addContent(new Element("total-duration").addContent(totals.getString("general-info.total-duration", "0:00:00"))); - gd.addContent(new Element("longest-session-duration").addContent(totals.getString("general-info.longest-session-duration", "0:00:00"))); - - // Classes - Element cl = new Element("classes"); - for (String c : log.arena.getClasses()) - { - Element e = new Element("class").setAttribute(new Attribute("name", c)); - e.addContent(new Element("kills").addContent(totals.getInt("classes." + c + ".kills", 0) + "")); - e.addContent(new Element("damage-done").addContent(totals.getInt("classes." + c + ".damage-done", 0) + "")); - e.addContent(new Element("damage-taken").addContent(totals.getInt("classes." + c + ".damage-taken", 0) + "")); - cl.addContent(e); - } - - // Rewards - Element rw = new Element("rewards"); - for (ArenaPlayer ap : log.players.values()) - for (ItemStack stack : ap.rewards) - rw.addContent(getReward(stack)); - - // Players - Element pl = new Element("players"); - for (ArenaPlayer ap : log.players.values()) - { - String name = ap.player.getName(); - Element p = new Element("player").setAttribute(new Attribute("name", name)); - p.addContent(new Element("games-played").addContent(totals.getInt("players." + name + ".games-played", 1) + "")); - p.addContent(new Element("kills").addContent(totals.getInt("players." + name + ".kills", 1) + "")); - p.addContent(new Element("damage-done").addContent(totals.getInt("players." + name + ".damage-done", 1) + "")); - p.addContent(new Element("damage-taken").addContent(totals.getInt("players." + name + ".damage-taken", 1) + "")); - p.addContent(new Element("swings").addContent(totals.getInt("players." + name + ".swings", 1) + "")); - p.addContent(new Element("hits").addContent(totals.getInt("players." + name + ".hits", 1) + "")); - - List classes = totals.getKeys("players." + name + ".classes"); - Element pcl = new Element("classes"); - if (classes != null) - { - for (String c : classes) - pcl.addContent(new Element("class").setAttribute(new Attribute("name", c)).addContent(totals.getInt("players." + name + ".classes." + c, 0) + "")); - } - - p.addContent(pcl); - pl.addContent(p); - } - - // Add the main nodes - Element root = new Element("last-session"); - root.addContent(gd); - root.addContent(cl); - root.addContent(rw); - root.addContent(pl); - - // Create a new document - Document doc = new Document(); - doc.addContent(root); - - // Serialize! - File dir = new File(MobArena.arenaDir, log.getArena().configName()); - if (!dir.exists()) dir.mkdirs(); - serialize(log, dir, doc, "totals.xml"); - } - - private static Element getReward(ItemStack stack) - { - boolean money = stack.getTypeId() == MobArena.ECONOMY_MONEY_ID; - - Element result = new Element("reward"); - result.setAttribute(new Attribute("id", stack.getTypeId() + "")); - result.setAttribute(new Attribute("material", money ? "money" : stack.getType().toString().toLowerCase())); - result.setAttribute(new Attribute("data", money || stack.getData() == null ? "0" : stack.getData().toString().toLowerCase())); - result.setAttribute(new Attribute("amount", stack.getAmount() + "")); - - return result; - } - - private static void serialize(ArenaLog log, File dir, Document doc, String filename) - { - try - { - File file = new File(dir, filename); - FileOutputStream fop = new FileOutputStream(file); - XMLOutputter out = new XMLOutputter(); - out.output(doc, fop); - } - catch (Exception e) - { - e.printStackTrace(); - MobArena.warning("Problem saving session data for arena '" + log.getArena().configName() + "'"); - } - } -} diff --git a/src/com/garbagemule/MobArena/util/data/YAML.java b/src/com/garbagemule/MobArena/util/data/YAML.java deleted file mode 100644 index a6d6006..0000000 --- a/src/com/garbagemule/MobArena/util/data/YAML.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.garbagemule.MobArena.util.data; - -import java.io.File; -import java.util.Map; - -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.util.config.Configuration; - -import com.garbagemule.MobArena.ArenaLog; -import com.garbagemule.MobArena.ArenaPlayer; -import com.garbagemule.MobArena.MobArena; - -public class YAML -{ - public static void saveSessionData(ArenaLog log) - { - File dir = new File(MobArena.arenaDir, log.getArena().configName()); - if (!dir.exists()) dir.mkdirs(); - - // Make Configuration object - Configuration config = new Configuration(new File(dir, "lastsession.yml")); - config.load(); - - // Reset any existing data - config.setProperty("general-info", null); - config.setProperty("class-distribution", null); - config.setProperty("player-data", null); - - // General information - config.setProperty("general-info.start-time", log.getStartTime()); - config.setProperty("general-info.end-time", log.getEndTime()); - config.setProperty("general-info.duration", log.getDuration()); - config.setProperty("general-info.last-wave", log.getLastWave()); - - // Class distribution - for (Map.Entry entry : log.distribution.entrySet()) - config.setProperty("class-distribution." + entry.getKey(), entry.getValue()); - - // Player data - for (Map.Entry entry : log.players.entrySet()) - { - String p = entry.getKey().getName(); - ArenaPlayer ap = entry.getValue(); - - config.setProperty("player-data." + p + ".last-wave", ap.getStats().lastWave); - config.setProperty("player-data." + p + ".kills", ap.getStats().kills); - config.setProperty("player-data." + p + ".damage-done", ap.getStats().dmgDone); - config.setProperty("player-data." + p + ".damage-taken", ap.getStats().dmgTaken); - config.setProperty("player-data." + p + ".swings", ap.getStats().swings); - config.setProperty("player-data." + p + ".hits", ap.getStats().hits); - for (ItemStack stack : ap.rewards) - { - boolean money = stack.getTypeId() == MobArena.ECONOMY_MONEY_ID; - String path = "player-data." + p + ".rewards." + (money ? "money" : stack.getType().toString().toLowerCase()); - config.setProperty(path, config.getInt(path, 0) + stack.getAmount()); - } - } - - // Save the file - config.save(); - } -} diff --git a/src/com/garbagemule/MobArena/util/inventory/InventoryManager.java b/src/com/garbagemule/MobArena/util/inventory/InventoryManager.java new file mode 100644 index 0000000..f364d9a --- /dev/null +++ b/src/com/garbagemule/MobArena/util/inventory/InventoryManager.java @@ -0,0 +1,198 @@ +package com.garbagemule.MobArena.util.inventory; + +import java.io.*; +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; + +import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.framework.Arena; + +public class InventoryManager +{ + private static String EXT = ".inv"; + private File dir; + private Map items, armor; + + public InventoryManager(Arena arena) { + this.dir = new File(arena.getPlugin().getDataFolder(), "inventories"); + this.dir.mkdir(); + + this.items = new HashMap(); + this.armor = new HashMap(); + } + + /** + * Store a player's inventory in memory and in a file. + * @param p a player + * @return true, if the inventory was stored, false if it already existed + */ + public boolean storeInventory(Player p) { + if (items.containsKey(p) && armor.containsKey(p)) { + return false; + } + + // Store the inventory in memory + PlayerInventory inv = p.getInventory(); + ItemStack[] memItems = inv.getContents(); + ItemStack[] memArmor = inv.getArmorContents(); + items.put(p, memItems); + armor.put(p, memArmor); + + // And save it to a file + saveToFile(p); + clearInventory(p); + return true; + } + + /** + * Restore a player's inventory from memory or from a file + * Note that this method is idempotent; calling it multiple times will + * not duplicate player items or anything like that. + * @param p a player + * @return true, if the inventory was restored successfully, false otherwise + */ + public boolean restoreInventory(Player p) { + ItemStack[] memItems = items.remove(p); + ItemStack[] memArmor = armor.remove(p); + + // Restore from inventory if possible + if (memItems != null && memArmor != null) { + PlayerInventory inv = p.getInventory(); + + inv.setContents(memItems); + inv.setArmorContents(memArmor); + + new File(dir, p.getName() + EXT).delete(); + + return true; + } + + // Otherwise, load from file + return loadFromFile(p); + } + + /** + * Clear a player's inventory completely. + * @param p a player + */ + public void clearInventory(Player p) { + PlayerInventory inv = p.getInventory(); + inv.clear(); + inv.setHelmet(null); + inv.setChestplate(null); + inv.setLeggings(null); + inv.setBoots(null); + } + + private boolean saveToFile(Player p) { + File file = new File(dir, p.getName() + EXT); + + // If the file exists, encourage restoring first. + if (file.exists()) { + return false; + } + + try { + SerializableInventory inv = new SerializableInventory(p.getInventory()); + + FileOutputStream fos = new FileOutputStream(file); + ObjectOutputStream oos = new ObjectOutputStream(fos); + + oos.writeObject(inv); + oos.close(); + + return true; + } + catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + private boolean loadFromFile(Player p) { + File file = new File(dir, p.getName() + EXT); + + // If the file doesn't exist, we can't restore from it! + if (!file.exists()) { + return false; + } + + try { + FileInputStream fis = new FileInputStream(file); + ObjectInputStream ois = new ObjectInputStream(fis); + + Object o = ois.readObject(); + ois.close(); + + SerializableInventory inv = (SerializableInventory) o; + SerializableInventory.loadContents(p, inv); + + file.delete(); + + return true; + } + catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + public static boolean hasEmptyInventory(Player p) { + ItemStack[] inventory = p.getInventory().getContents(); + ItemStack[] armor = p.getInventory().getArmorContents(); + + // For inventory, check for null + for (ItemStack stack : inventory) { + if (stack != null) + return false; + } + + // For armor, check for id 0, or AIR + for (ItemStack stack : armor) { + if (stack.getTypeId() != 0) + return false; + } + + return true; + } + + /** + * Restore a player's inventory from file + * @param plugin MobArena instance + * @param p a player + * @return true, if the inventory was restored successfully, false otherwise + */ + public static boolean restoreFromFile(MobArena plugin, Player p) { + File dir = new File(plugin.getDataFolder(), "inventories"); + + File file = new File(dir, p.getName() + EXT); + + // If the file doesn't exist, we can't restore from it! + if (!file.exists()) { + return false; + } + + try { + FileInputStream fis = new FileInputStream(file); + ObjectInputStream ois = new ObjectInputStream(fis); + + Object o = ois.readObject(); + ois.close(); + + SerializableInventory inv = (SerializableInventory) o; + SerializableInventory.loadContents(p, inv); + + file.delete(); + + return true; + } + catch (Exception e) { + e.printStackTrace(); + return false; + } + } +} diff --git a/src/com/garbagemule/MobArena/util/inventory/InventoryUtils.java b/src/com/garbagemule/MobArena/util/inventory/InventoryUtils.java new file mode 100644 index 0000000..3033ab0 --- /dev/null +++ b/src/com/garbagemule/MobArena/util/inventory/InventoryUtils.java @@ -0,0 +1,35 @@ +package com.garbagemule.MobArena.util.inventory; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.inventory.ItemStack; + +public class InventoryUtils +{ + public static SerializableItem parseItemStack(ItemStack stack) { + return SerializableItem.parseSerializableItem(stack); + } + + public static SerializableItem[] parseItemStacks(ItemStack... stacks) { + SerializableItem[] items = new SerializableItem[stacks.length]; + + for (int i = 0; i < items.length; i++) { + items[i] = parseItemStack(stacks[i]); + } + + return items; + } + + public static List extractAll(int id, List items) { + List result = new ArrayList(); + + for (ItemStack stack : items) { + if (stack.getTypeId() == id) { + result.add(stack); + } + } + + return result; + } +} diff --git a/src/com/garbagemule/MobArena/util/inventory/SerializableInventory.java b/src/com/garbagemule/MobArena/util/inventory/SerializableInventory.java new file mode 100644 index 0000000..4ca6912 --- /dev/null +++ b/src/com/garbagemule/MobArena/util/inventory/SerializableInventory.java @@ -0,0 +1,73 @@ +package com.garbagemule.MobArena.util.inventory; + +import java.io.Serializable; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; + +public class SerializableInventory implements Serializable +{ + private static final long serialVersionUID = 5816986232508437560L; + + private SerializableItem[] items, armor; + + public SerializableInventory(PlayerInventory inv) { + ItemStack[] stackItems = inv.getContents(); + ItemStack[] stackArmor = inv.getArmorContents(); + + this.items = new SerializableItem[stackItems.length]; + this.armor = new SerializableItem[stackArmor.length]; + + for (int i = 0; i < stackItems.length; i++) { + this.items[i] = SerializableItem.parseSerializableItem(stackItems[i]); + } + + for (int i = 0; i < stackArmor.length; i++) { + this.armor[i] = SerializableItem.parseSerializableItem(stackArmor[i]); + } + } + + public SerializableInventory(Inventory inv) { + ItemStack[] stacks = inv.getContents(); + this.items = new SerializableItem[stacks.length]; + + for (int i = 0; i < stacks.length; i++) { + this.items[i] = SerializableItem.parseSerializableItem(stacks[i]); + } + } + + public ItemStack[] getItems() { + ItemStack[] result = new ItemStack[items.length]; + for (int i = 0; i < items.length; i++) { + result[i] = (items[i] == null ? null : items[i].toItemStack()); + } + return result; + } + + public ItemStack[] getArmor() { + ItemStack[] result = new ItemStack[armor.length]; + for (int i = 0; i < armor.length; i++) { + result[i] = (armor[i] == null ? null : armor[i].toItemStack()); + } + return result; + } + + public static void loadContents(Player p, SerializableInventory inv) { + if (inv == null) { + return; + } + + p.getInventory().setContents(inv.getItems()); + p.getInventory().setArmorContents(inv.getArmor()); + } + + public static void loadContents(Inventory chestInv, SerializableInventory inv) { + if (inv == null) { + return; + } + + chestInv.setContents(inv.getItems()); + } +} diff --git a/src/com/garbagemule/MobArena/util/inventory/SerializableItem.java b/src/com/garbagemule/MobArena/util/inventory/SerializableItem.java new file mode 100644 index 0000000..25470d0 --- /dev/null +++ b/src/com/garbagemule/MobArena/util/inventory/SerializableItem.java @@ -0,0 +1,55 @@ +package com.garbagemule.MobArena.util.inventory; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; +import org.bukkit.material.MaterialData; + +public class SerializableItem implements Serializable +{ + private static final long serialVersionUID = -2855528738291283052L; + + private int id; + private int amount; + private short damage; + private Byte data; + private Map enchantments; + + private SerializableItem(ItemStack stack) { + this.id = stack.getTypeId(); + this.amount = stack.getAmount(); + this.damage = stack.getDurability(); + + MaterialData md = stack.getData(); + this.data = (md == null ? null : md.getData()); + + this.enchantments = new HashMap(); + for (Entry entry : stack.getEnchantments().entrySet()) { + this.enchantments.put(entry.getKey().getId(), entry.getValue()); + } + } + + public ItemStack toItemStack() { + ItemStack stack = new ItemStack(id, amount, damage, data); + + if (!enchantments.isEmpty()) { + for (Entry entry : this.enchantments.entrySet()) { + stack.addUnsafeEnchantment(Enchantment.getById(entry.getKey()), entry.getValue()); + } + } + + return stack; + } + + public static SerializableItem parseSerializableItem(ItemStack stack) { + if (stack == null) { + return null; + } + + return new SerializableItem(stack); + } +} diff --git a/src/com/garbagemule/MobArena/waves/AbstractWave.java b/src/com/garbagemule/MobArena/waves/AbstractWave.java index d42918b..652bb33 100644 --- a/src/com/garbagemule/MobArena/waves/AbstractWave.java +++ b/src/com/garbagemule/MobArena/waves/AbstractWave.java @@ -2,226 +2,125 @@ package com.garbagemule.MobArena.waves; import java.util.List; import java.util.Map; -import java.util.Random; import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.entity.Creature; -import org.bukkit.entity.LivingEntity; -import com.garbagemule.MobArena.Arena; -import com.garbagemule.MobArena.util.WaveUtils; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.waves.enums.*; public abstract class AbstractWave implements Wave { - private Arena arena; - private World world; - private String waveName; - private int wave, frequency, priority; + private String name; + + private WaveBranch branch; // recurrent, single + private WaveType type; // default, special, swarm, boss + private double healthMultiplier, amountMultiplier; - private WaveBranch branch; - private WaveType type; - private WaveGrowth growth; - /** - * Basic wave constructor. - * @param name The config-file identifier - * @param wave Initial wave number. This is the first wave number this wave can spawn at. - * @param frequency How often the wave can spawn. - * @param priority The priority of the wave. - * @param branch The branch type (single, recurrent) - */ - public AbstractWave(Arena arena, String waveName, int wave, int frequency, int priority, WaveBranch branch) - { - this.arena = arena; - this.world = arena.getWorld(); - this.waveName = waveName; - this.wave = wave; - this.frequency = frequency; - this.priority = priority; - this.branch = branch; - } + private int firstWave, frequency, priority; - // Default recurrent wave constructor - public AbstractWave(Arena arena, String name, int wave, int frequency, int priority) - { - this(arena, name, wave, frequency, priority, WaveBranch.RECURRENT); - } + private List spawnpoints; - // Default single wave constructor - public AbstractWave(Arena arena, String name, int wave) - { - this(arena, name, wave, 0, 0, WaveBranch.SINGLE); - } - - /** - * Check if a wave matches a wave number. - * SINGLE WAVES match, if their wave number is the same as the - * parameter. - * RECURRENT WAVES match, if their wave number subtracted from - * the parameter divides the frequency. The wave number must be - * greater than or equal to the parameter. - * @param wave The wave number to compare - * @return true, if the wave matches the wave number - */ - public boolean matches(int wave) - { - if (branch == WaveBranch.SINGLE) - return this.wave == wave; - - if (branch == WaveBranch.RECURRENT && wave >= this.wave) - return ((wave - this.wave) % frequency == 0); - - return false; - } - - /** - * Spawn an MACreature in the given location. The actual LivingEntity - * spawned is returned. - * @param creature The MACreature to spawn - * @param loc The location to spawn the MACreature in - * @return The resulting LivingEntity - */ - public LivingEntity spawnMonster(MACreature creature, Location loc) - { - // Spawn - LivingEntity e = creature.spawn(getArena(), getWorld(), loc); - if (e == null) return null; - - // Add to collection - getArena().addMonster(e); - - // Boost health - int health = (int) Math.min(150D, e.getHealth() * healthMultiplier); - e.setHealth(Math.max(1, health)); + @Override + public abstract Map getMonstersToSpawn(int wave, int playerCount, Arena arena); - // Grab a random target. - if (e instanceof Creature) - { - Creature c = (Creature) e; - c.setTarget(WaveUtils.getClosestPlayer(getArena(), e)); - } + @Override + public List getSpawnpoints(Arena arena) { + return WaveUtils.getValidSpawnpoints(arena, spawnpoints, arena.getPlayersInArena()); + } + + @Override + public void setSpawnpoints(List spawnpoints) { + this.spawnpoints = spawnpoints; + } + + @Override + public void announce(Arena arena, int wave) { + type.announce(arena, wave); + } - return e; + @Override + public String getName() { + return name; } - /** - * Helper method for spawning a bunch of monsters over a - * collection of spawnpoints. Used by wave types DEFAULT, - * SPECIAL and SWARM. - * @param monsters A collection of monsters to spawn, and how many of each - * @param spawnpoints The spawnpoints to spawn the monsters over - */ - public void spawnAll(Map monsters, List spawnpoints) - { - Random random = new Random(); - int spawnpointCount = spawnpoints.size(); - int index = random.nextInt(spawnpointCount); - - for (Map.Entry entry : monsters.entrySet()) - { - for (int i = 0; i < entry.getValue(); i++) - { - spawnMonster(entry.getKey(), spawnpoints.get(index % spawnpointCount)); - index++; - } - } + @Override + public void setName(String name) { + this.name = name; } - - // GETTERS - public Arena getArena() - { - return arena; - } - - public World getWorld() - { - return world; - } - - public WaveBranch getBranch() - { + + @Override + public WaveBranch getBranch() { return branch; } - public WaveType getType() - { + @Override + public void setBranch(WaveBranch branch) { + this.branch = branch; + } + + @Override + public WaveType getType() { return type; } - - public WaveGrowth getGrowth() - { - return growth; + + @Override + public void setType(WaveType type) { + this.type = type; } - public int getWave() - { - return wave; + @Override + public int getFirstWave() { + return firstWave; } - public int getFrequency() - { + @Override + public void setFirstWave(int firstWave) { + this.firstWave = firstWave; + } + + @Override + public int getFrequency() { return frequency; } - public int getPriority() - { + @Override + public void setFrequency(int frequency) { + this.frequency = frequency; + } + + @Override + public int getPriority() { return priority; } - - public double getHealthMultiplier() - { + + @Override + public void setPriority(int priority) { + this.priority = priority; + } + + @Override + public double getHealthMultiplier() { return healthMultiplier; } - public double getAmountMultiplier() - { + @Override + public void setHealthMultiplier(double healthMultiplier) { + this.healthMultiplier = healthMultiplier; + } + + @Override + public double getAmountMultiplier() { return amountMultiplier; } - public String getName() - { - return waveName; + @Override + public void setAmountMultiplier(double amountMultiplier) { + this.amountMultiplier = amountMultiplier; } - // SETTERS - public void setBranch(WaveBranch branch) - { - this.branch = branch; - } - - public void setType(WaveType type) - { - this.type = type; - } - - public void setGrowth(WaveGrowth growth) - { - this.growth = growth; - } - - public void setHealthMultiplier(double value) - { - healthMultiplier = Math.max(0.1D, value); - } - - public void setAmountMultiplier(double value) - { - amountMultiplier = Math.max(0.1D, value); - } - - // MISC - public String toString() - { - if (branch == WaveBranch.RECURRENT) - return "[Wave type=" + type + - " name=" + waveName + - " branch=" + branch.toString().charAt(0) + - " freq=" + frequency + - " prio=" + priority + "]"; - return "[Wave type=" + type + - " name=" + waveName + - " branch=" + branch.toString().charAt(0) + - " wave=" + wave + "]"; + @Override + public boolean matches(int wave) { + return branch.matches(wave, this); } } diff --git a/src/com/garbagemule/MobArena/waves/BossAbility.java b/src/com/garbagemule/MobArena/waves/BossAbility.java index fc36abb..c7223dd 100644 --- a/src/com/garbagemule/MobArena/waves/BossAbility.java +++ b/src/com/garbagemule/MobArena/waves/BossAbility.java @@ -1,11 +1,11 @@ package com.garbagemule.MobArena.waves; +import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Random; -import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.Creature; @@ -15,10 +15,9 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.util.Vector; -import com.garbagemule.MobArena.Arena; import com.garbagemule.MobArena.MAUtils; import com.garbagemule.MobArena.MobArena; -import com.garbagemule.MobArena.util.WaveUtils; +import com.garbagemule.MobArena.framework.Arena; public enum BossAbility @@ -37,6 +36,7 @@ public enum BossAbility Location bLoc = boss.getLocation(); Location loc = bLoc.add(bLoc.getDirection().normalize().multiply(2).toLocation(boss.getWorld(), bLoc.getYaw(), bLoc.getPitch())); Fireball fireball = boss.getWorld().spawn(loc, Fireball.class); + fireball.setFireTicks(100); fireball.setIsIncendiary(false); } }, @@ -45,7 +45,7 @@ public enum BossAbility public void run(Arena arena, LivingEntity boss) { for (Player p : getNearbyPlayers(arena, boss, 5)) - p.setFireTicks(20); + p.setFireTicks(20); } }, LIGHTNINGAURA("Lightning Aura") @@ -66,8 +66,7 @@ public enum BossAbility }, LIVINGBOMB("Living Bomb") { - public void run(final Arena arena, LivingEntity boss) - { + public void run(final Arena arena, LivingEntity boss) { final LivingEntity target = getTarget(boss); if (target == null) return; @@ -75,19 +74,24 @@ public enum BossAbility target.setFireTicks(60); // Create an explosion after 3 seconds - Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(arena.getPlugin(), - new Runnable() - { - public void run() - { - if (!arena.getLivingPlayers().contains(target)) + arena.getPlugin().getServer().getScheduler().scheduleSyncDelayedTask(arena.getPlugin(), + new Runnable() { + public void run() { + if (!arena.inArena((Player) target)) { return; + } + + // If the player put out the fire, don't explode. + if (target.getFireTicks() <= 0) { + return; + } arena.getWorld().createExplosion(target.getLocation(), 2F); - for(Player p : getNearbyPlayers(arena, target, 3)) + for (Player p : getNearbyPlayers(arena, target, 3)) { p.setFireTicks(40); + } } - }, 61); + }, 59); } }, CHAINLIGHTNING("Chain Lightning") @@ -102,12 +106,12 @@ public enum BossAbility private void strikeLightning(final Arena arena, final Player p, final List done) { - Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(arena.getPlugin(), + arena.getPlugin().getServer().getScheduler().scheduleSyncDelayedTask(arena.getPlugin(), new Runnable() { public void run() { - if (!arena.getLivingPlayers().contains(p)) + if (!arena.getPlayersInArena().contains(p)) return; // Smite the target @@ -135,10 +139,32 @@ public enum BossAbility if (target == null) return; Location loc = target.getLocation(); - loc.setYaw(target.getLocation().getYaw() + 45 + MobArena.random.nextInt(270)); + loc.setYaw(loc.getYaw() + 45 + MobArena.random.nextInt(270)); target.teleport(loc); } }, + DISORIENTNEARBY("Disorient Nearby") + { + public void run(Arena arena, LivingEntity boss) + { + for (Player p : getNearbyPlayers(arena, boss, 5)) { + Location loc = p.getLocation(); + loc.setYaw(loc.getYaw() + 45 + MobArena.random.nextInt(270)); + p.teleport(loc); + } + } + }, + DISORIENTDISTANT("Disorient Distant") + { + public void run(Arena arena, LivingEntity boss) + { + for (Player p : getDistantPlayers(arena, boss, 8)) { + Location loc = p.getLocation(); + loc.setYaw(loc.getYaw() + 45 + MobArena.random.nextInt(270)); + p.teleport(loc); + } + } + }, ROOTTARGET("Root Target") { public void run(final Arena arena, LivingEntity boss) @@ -147,22 +173,22 @@ public enum BossAbility if (target == null) return; final Location loc = target.getLocation(); - final int freezeTaskId = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(arena.getPlugin(), + final int freezeTaskId = arena.getPlugin().getServer().getScheduler().scheduleSyncRepeatingTask(arena.getPlugin(), new Runnable() { public void run() { - if (arena.getLivingPlayers().contains(target)) + if (arena.getPlayersInArena().contains(target)) target.teleport(loc); } }, 3, 3); - Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(arena.getPlugin(), + arena.getPlugin().getServer().getScheduler().scheduleSyncDelayedTask(arena.getPlugin(), new Runnable() { public void run() { - Bukkit.getServer().getScheduler().cancelTask(freezeTaskId); + arena.getPlugin().getServer().getScheduler().cancelTask(freezeTaskId); } }, 45); } @@ -171,7 +197,7 @@ public enum BossAbility { public void run(Arena arena, LivingEntity boss) { - List list = arena.getLivingPlayers(); + List list = new ArrayList(arena.getPlayersInArena()); boss.teleport(list.get((new Random()).nextInt(list.size()))); } }, @@ -180,7 +206,7 @@ public enum BossAbility public void run(Arena arena, LivingEntity boss) { // Grab the players and add the boss - List entities = new LinkedList(arena.getArenaPlayers()); + List entities = new ArrayList(arena.getPlayersInArena()); entities.add(boss); // Grab the locations @@ -198,7 +224,7 @@ public enum BossAbility { public void run(Arena arena, LivingEntity boss) { - List players = arena.getLivingPlayers(); + List players = new ArrayList(arena.getPlayersInArena()); Block block = players.get(MobArena.random.nextInt(players.size())).getLocation().getBlock(); if (block.getTypeId() == 0) { @@ -319,7 +345,7 @@ public enum BossAbility { List result = new LinkedList(); for (Entity e : boss.getNearbyEntities(x, x, x)) - if (arena.getLivingPlayers().contains(e)) + if (arena.getPlayersInArena().contains(e)) result.add((Player) e); return result; } @@ -334,19 +360,17 @@ public enum BossAbility protected List getDistantPlayers(Arena arena, Entity boss, int x) { List result = new LinkedList(); - for (Player p : arena.getLivingPlayers()) - if (MAUtils.distanceSquared(p, boss.getLocation()) > (double) (x*x)) + for (Player p : arena.getPlayersInArena()) + if (MAUtils.distanceSquared(arena.getPlugin(), p, boss.getLocation()) > (double) (x*x)) result.add(p); return result; } - public static BossAbility fromString(String string) - { + public static BossAbility fromString(String string) { return WaveUtils.getEnumFromString(BossAbility.class, string.replaceAll("[-_\\.]", "")); } - public String toString() - { + public String toString() { return name; } } diff --git a/src/com/garbagemule/MobArena/waves/BossAbilityThread.java b/src/com/garbagemule/MobArena/waves/BossAbilityThread.java new file mode 100644 index 0000000..47fd489 --- /dev/null +++ b/src/com/garbagemule/MobArena/waves/BossAbilityThread.java @@ -0,0 +1,52 @@ +package com.garbagemule.MobArena.waves; + +import java.util.List; +import java.util.Set; + +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.waves.types.BossWave; + +public class BossAbilityThread implements Runnable +{ + private BossWave wave; + private List abilities; + private Arena arena; + private int counter; + + public BossAbilityThread(BossWave wave, List abilities, Arena arena) { + this.wave = wave; + this.abilities = abilities; + this.arena = arena; + this.counter = 0; + } + + @Override + public void run() { + // If we have no abilities, we can't execute any, so just quit. + if (abilities.isEmpty()) { + return; + } + + // If the arena isn't running or has no players, quit. + if (!arena.isRunning() || arena.getPlayersInArena().isEmpty()) { + return; + } + + // If all bosses are dead, quit. + Set bosses = wave.getMABosses(); + if (bosses.isEmpty()) { + return; + } + + // Get the next ability in the list. + BossAbility ability = abilities.get(counter++ % abilities.size()); + + // And make each boss in this boss wave use it! + for (MABoss boss : bosses) { + ability.run(arena, boss.getEntity()); + } + + // Schedule for another run! + wave.scheduleTask(arena, this, wave.getAbilityInterval()); + } +} diff --git a/src/com/garbagemule/MobArena/waves/BossWave.java b/src/com/garbagemule/MobArena/waves/BossWave.java deleted file mode 100644 index a91c5dd..0000000 --- a/src/com/garbagemule/MobArena/waves/BossWave.java +++ /dev/null @@ -1,189 +0,0 @@ -package com.garbagemule.MobArena.waves; - -import java.util.LinkedList; -import java.util.List; -import java.util.Set; - -import net.minecraft.server.WorldServer; - -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.craftbukkit.CraftWorld; -import org.bukkit.craftbukkit.entity.CraftEntity; -import org.bukkit.entity.Creature; -import org.bukkit.entity.LivingEntity; -//import org.bukkit.util.config.Configuration; - -import com.garbagemule.MobArena.Arena; -import com.garbagemule.MobArena.MAUtils; -import com.garbagemule.MobArena.Msg; -import com.garbagemule.MobArena.util.Config; -import com.garbagemule.MobArena.util.WaveUtils; - -public class BossWave extends AbstractWave -{ - private MACreature boss; - private LivingEntity bossCreature; - private List abilities; - private Set adds; - private BossHealth bossHealth; - private int healthAmount, abilityTask, abilityInterval; - private boolean lowHealthAnnounced = false, abilityAnnounce; - - // Recurrent - public BossWave(Arena arena, String name, int wave, int frequency, int priority, Config config, String path) - { - super(arena, name, wave, frequency, priority); - load(config, path); - } - - // Single - public BossWave(Arena arena, String name, int wave, Config config, String path) - { - super(arena, name, wave); - load(config, path); - } - - private void load(Config config, String path) - { - setType(WaveType.BOSS); - abilityTask = -1; - abilities = new LinkedList(); - - // Get monster and health - boss = MACreature.fromString(config.getString(path + "monster")); - bossHealth = WaveUtils.getEnumFromString(BossHealth.class, config.getString(path + "health"), BossHealth.MEDIUM); - - // Get abilities - abilityInterval = config.getInt(path + "ability-interval", 3) * 20; - abilityAnnounce = config.getBoolean(path + "ability-announce", true); - String abilities = config.getString(path + "abilities"); - if (abilities != null) - { - for (String a : abilities.split(",")) - { - String ability = a.trim(); - addAbility(BossAbility.fromString(ability)); - } - } - } - - public void spawn(int wave) - { - // Announce spawning - MAUtils.tellAll(getArena(), Msg.WAVE_BOSS, ""+wave); - - // Spawn the boss and set the arena - bossCreature = boss.spawn(getArena(), getWorld(), getArena().getBossSpawnpoint()); - if (bossCreature instanceof Creature) - ((Creature) bossCreature).setTarget(MAUtils.getClosestPlayer(bossCreature, getArena())); - getArena().addMonster(bossCreature); - getArena().setBossWave(this); - - // Set the health stuff - bossCreature.setHealth(bossCreature.getMaxHealth()); - healthAmount = bossHealth.getAmount(getArena().getPlayerCount()); - - startAbilityTasks(); - } - - private void startAbilityTasks() - { - final int abilityCount = abilities.size(); - - // If there are no abilities, don't start the timer. - if (abilityCount == 0) - return; - - abilityTask = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(getArena().getPlugin(), - new Runnable() - { - private int counter = 0; - - public void run() - { - // Check to see if the boss is still alive. If not, end this boss wave. - if (bossCreature.isDead()) - { - clear(); - return; - } - - // Grab the next ability - BossAbility ability = abilities.get(counter % abilityCount); - - // Announce it - if (abilityAnnounce) - MAUtils.tellAll(getArena(), Msg.WAVE_BOSS_ABILITY, ability.toString()); - - // Activate! - ability.run(getArena(), bossCreature); - - // Increment counter - counter++; - } - }, 100, abilityInterval); - } - - public void cancelAbilityTask() - { - if (abilityTask != -1) - Bukkit.getServer().getScheduler().cancelTask(abilityTask); - } - - public void clear() - { - cancelAbilityTask(); - getArena().setBossWave(null); - - if (bossCreature == null) return; - - CraftEntity ce = (CraftEntity) bossCreature; - CraftWorld cw = (CraftWorld) getWorld(); - WorldServer ws = cw.getHandle(); - Location l = bossCreature.getLocation(); - ws.createExplosion(ce.getHandle(), l.getX(), l.getY() + 1, l.getZ(), 1f, false); - - bossCreature.remove(); - } - - public void addAbility(BossAbility ability) - { - abilities.add(ability); - } - - public void addAdds(Creature creature) - { - adds.add(creature); - } - - public LivingEntity getEntity() - { - return bossCreature; - } - - public int getHealth() - { - return healthAmount; - } - - public void setHealth(int healthAmount) - { - this.healthAmount = healthAmount; - } - - public void subtractHealth(int amount) - { - healthAmount -= amount; - } - - public boolean isLowHealthAnnounced() - { - return lowHealthAnnounced; - } - - public void setLowHealthAnnounced(boolean value) - { - lowHealthAnnounced = value; - } -} diff --git a/src/com/garbagemule/MobArena/waves/DefaultWave.java b/src/com/garbagemule/MobArena/waves/DefaultWave.java deleted file mode 100644 index 34b94c5..0000000 --- a/src/com/garbagemule/MobArena/waves/DefaultWave.java +++ /dev/null @@ -1,81 +0,0 @@ -package com.garbagemule.MobArena.waves; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; - -import org.bukkit.Location; -//import org.bukkit.util.config.Configuration; - -import com.garbagemule.MobArena.Arena; -import com.garbagemule.MobArena.MAUtils; -import com.garbagemule.MobArena.Msg; -import com.garbagemule.MobArena.util.Config; -import com.garbagemule.MobArena.util.WaveUtils; - -public class DefaultWave extends NormalWave -{ - // Recurrent - public DefaultWave(Arena arena, String name, int wave, int frequency, int priority, Config config, String path) - { - super(arena, name, wave, frequency, priority, config, path); - load(config, path, WaveType.DEFAULT); - } - - // Single - public DefaultWave(Arena arena, String name, int wave, Config config, String path) - { - super(arena, name, wave, config, path); - load(config, path, WaveType.DEFAULT); - } - - /** - * Default waves spawn an amount of random monsters, picked from a - * map of probabilities. The amount to spawn depends on the wave - * number and player count. - */ - public void spawn(int wave) - { - // Announce spawning - MAUtils.tellAll(getArena(), Msg.WAVE_DEFAULT, ""+wave); - - // Get the valid spawnpoints, and initialize counter - List validSpawnpoints = WaveUtils.getValidSpawnpoints(getArena(), getArena().getLivingPlayers()); - - // Initialize the total amount of mobs to spawn - int totalToSpawn = (int) (getGrowth().getAmount(wave, getArena().getPlayerCount()) * getAmountMultiplier()); - - // Spawn all the monsters - spawnAll(getMonstersToSpawn(totalToSpawn), validSpawnpoints); - } - - private Map getMonstersToSpawn(int totalToSpawn) - { - Map result = new HashMap(); - Random random = new Random(); - int randomNumber; - MACreature creature; - - if (totalToSpawn < 1) totalToSpawn = 1; - for (int i = 0; i < totalToSpawn; i++) - { - randomNumber = random.nextInt(getTotalProbability()); - - // Find the monster that corresponds to the random number, and increment its value - for (Map.Entry entry : getProbabilityMap().entrySet()) - { - if (randomNumber > entry.getKey()) continue; - - creature = entry.getValue(); - if (result.containsKey(entry.getValue())) - result.put(creature, result.get(creature) + 1); - else - result.put(creature, 1); - break; - } - } - - return result; - } -} diff --git a/src/com/garbagemule/MobArena/waves/MABoss.java b/src/com/garbagemule/MobArena/waves/MABoss.java new file mode 100644 index 0000000..c598945 --- /dev/null +++ b/src/com/garbagemule/MobArena/waves/MABoss.java @@ -0,0 +1,48 @@ +package com.garbagemule.MobArena.waves; + +import org.bukkit.entity.LivingEntity; + +public class MABoss +{ + private LivingEntity entity; + private int health, health25, maxHealth; + private boolean dead, lowHealth; + + public MABoss(LivingEntity entity, int maxHealth) { + this.entity = entity; + this.dead = false; + this.lowHealth = false; + + this.health = this.maxHealth = maxHealth; + this.health25 = maxHealth / 4; + } + + public LivingEntity getEntity() { + return entity; + } + + public int getHealth() { + return health; + } + + public int getMaxHealth() { + return maxHealth; + } + + public void damage(int amount) { + health -= amount; + + if (health <= health25 && !lowHealth) { + lowHealth = true; + //System.out.println("Boss is at 25%!"); + } + + if (health <= 0) { + dead = true; + } + } + + public boolean isDead() { + return dead; + } +} diff --git a/src/com/garbagemule/MobArena/waves/MACreature.java b/src/com/garbagemule/MobArena/waves/MACreature.java index 4d5d6c3..3e0d90d 100644 --- a/src/com/garbagemule/MobArena/waves/MACreature.java +++ b/src/com/garbagemule/MobArena/waves/MACreature.java @@ -2,15 +2,15 @@ package com.garbagemule.MobArena.waves; import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.entity.Creature; import org.bukkit.entity.CreatureType; import org.bukkit.entity.Creeper; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Slime; import org.bukkit.entity.Wolf; -import com.garbagemule.MobArena.Arena; import com.garbagemule.MobArena.MobArena; -import com.garbagemule.MobArena.util.WaveUtils; +import com.garbagemule.MobArena.framework.Arena; public enum MACreature { @@ -65,29 +65,25 @@ public enum MACreature private CreatureType type; - private MACreature(CreatureType type) - { + private MACreature(CreatureType type) { this.type = type; } - public CreatureType getType() - { + public CreatureType getType() { return type; } - public static MACreature fromString(String string) - { + public static MACreature fromString(String string) { return WaveUtils.getEnumFromString(MACreature.class, string.replaceAll("[-_\\.]", "")); } - public LivingEntity spawn(Arena arena, World world, Location loc) - { + public LivingEntity spawn(Arena arena, World world, Location loc) { LivingEntity e = world.spawnCreature(loc, type); switch (this) { case EXPLODINGSHEEP: - arena.addExplodingSheep(e); + arena.getMonsterManager().addExplodingSheep(e); break; case POWEREDCREEPERS: ((Creeper) e).setPowered(true); @@ -129,6 +125,11 @@ public enum MACreature break; } + if (e instanceof Creature) { + Creature c = (Creature) e; + c.setTarget(WaveUtils.getClosestPlayer(arena, e)); + } + return e; } } diff --git a/src/com/garbagemule/MobArena/waves/NormalWave.java b/src/com/garbagemule/MobArena/waves/NormalWave.java deleted file mode 100644 index 88722d0..0000000 --- a/src/com/garbagemule/MobArena/waves/NormalWave.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.garbagemule.MobArena.waves; - -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; - -//import org.bukkit.util.config.Configuration; - -import com.garbagemule.MobArena.Arena; -import com.garbagemule.MobArena.MAUtils; -import com.garbagemule.MobArena.util.Config; -import com.garbagemule.MobArena.util.WaveUtils; - -public abstract class NormalWave extends AbstractWave -{ - private int totalProbability = 0; - private Map probabilities = new TreeMap(); - - // Recurrent - public NormalWave(Arena arena, String name, int wave, int frequency, int priority, Config config, String path) - { - super(arena, name, wave, frequency, priority); - } - - // Single - public NormalWave(Arena arena, String name, int wave, Config config, String path) - { - super(arena, name, wave); - } - - /** - * Prepare the wave for spawning by initializing the variables and - * populating the collections needed. - * @param config The config-file - * @param path The absolute path of the wave - * @param type DEFAULT or SPECIAL - */ - public void load(Config config, String path, WaveType type) - { - // Set type and (for DEFAULT) growth. - setType(type); - if (type == WaveType.DEFAULT) - setGrowth(WaveUtils.getEnumFromString(WaveGrowth.class, config.getString(path + "growth"), WaveGrowth.OLD)); - - // Load monsters - int prob; - Set monsters = config.getKeys(path + "monsters"); - if (monsters != null && !monsters.isEmpty()) - { - for (String m : config.getKeys(path + "monsters")) - { - prob = config.getInt(path + "monsters." + m, 1); - if (prob == 0) continue; - - incTotalProbability(prob); - probabilities.put(totalProbability, MACreature.fromString(m)); - } - } - else - { - if (type == WaveType.DEFAULT) - { - probabilities.put(10, MACreature.ZOMBIES); - probabilities.put(20, MACreature.SKELETONS); - probabilities.put(30, MACreature.SPIDERS); - probabilities.put(40, MACreature.CREEPERS); - probabilities.put(50, MACreature.WOLVES); - totalProbability = 50; - } - else if (type == WaveType.SPECIAL) - { - probabilities.put(10, MACreature.POWEREDCREEPERS); - probabilities.put(20, MACreature.ANGRYWOLVES); - probabilities.put(30, MACreature.ZOMBIEPIGMEN); - probabilities.put(40, MACreature.SLIMES); - totalProbability = 40; - } - } - - // Load multipliers - setHealthMultiplier(MAUtils.getDouble(config, path + "health-multiplier", 1D)); - setAmountMultiplier(MAUtils.getDouble(config, path + "amount-multiplier", 1D)); - } - - public int getTotalProbability() - { - return totalProbability; - } - - public void incTotalProbability(int value) - { - totalProbability += value; - } - - public Map getProbabilityMap() - { - return probabilities; - } - - public abstract void spawn(int wave); -} diff --git a/src/com/garbagemule/MobArena/waves/SheepBouncer.java b/src/com/garbagemule/MobArena/waves/SheepBouncer.java new file mode 100644 index 0000000..0895572 --- /dev/null +++ b/src/com/garbagemule/MobArena/waves/SheepBouncer.java @@ -0,0 +1,96 @@ +package com.garbagemule.MobArena.waves; + +import java.util.HashSet; +import java.util.Set; + +import net.minecraft.server.WorldServer; + +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.entity.CraftEntity; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; + +import com.garbagemule.MobArena.framework.Arena; + +public class SheepBouncer implements Runnable +{ + public static final int BOUNCE_INTERVAL = 20; + private Arena arena; + private Set sheep; + + public SheepBouncer(Arena arena) { + this.arena = arena; + } + + @Override + public void run() { + // If the arena isn't running or has no players, bail out + if (!arena.isRunning() || arena.getPlayersInArena().isEmpty()) { + return; + } + + // Put all the sheep in a new collection for iteration purposes. + sheep = new HashSet(arena.getMonsterManager().getExplodingSheep()); + + // If there are no sheep, reschedule and return. + if (sheep.isEmpty()) { + arena.scheduleTask(this, BOUNCE_INTERVAL); + return; + } + + for (LivingEntity e : sheep) { + // If an entity is null just ignore it. + if (e == null) { + continue; + } + + // If the sheep is dead, remove it. + if (e.isDead()) { + arena.getMonsterManager().removeMonster(e); + arena.getMonsterManager().removeExplodingSheep(e); + continue; + } + + // Create an explosion if there's a player amongst the nearby entities. + for (Entity entity : e.getNearbyEntities(2D, 2D, 2D)) { + if (entity instanceof Player) { + CraftEntity ce = (CraftEntity) e; + CraftWorld cw = (CraftWorld) e.getWorld(); + WorldServer ws = cw.getHandle(); + + ws.createExplosion(ce.getHandle(), e.getLocation().getX(), e.getLocation().getY() + 1, e.getLocation().getZ(), 2f, false); + e.remove(); + + break; + } + } + + // Otherwise, if it's not already bouncing, BOUNCE! + if (Math.abs(e.getVelocity().getY()) < 1) + e.setVelocity(e.getVelocity().setY(0.5)); + } + + // Reschedule for more bouncy madness! + arena.scheduleTask(this, BOUNCE_INTERVAL); + } + + /*private boolean isTargetNearby(Creature c, LivingEntity t) { + // Null or dead, return false + if (t == null || c == null || c.isDead()) { + return false; + } + + // If the subjects are in different worlds, return false. + if (c.getWorld() != t.getWorld()) { + return false; + } + + // If distance is more than 3 blocks, not close enough. + if (c.getLocation().distanceSquared(t.getLocation()) > 8D) { + return false; + } + + return true; + }*/ +} diff --git a/src/com/garbagemule/MobArena/waves/SpecialWave.java b/src/com/garbagemule/MobArena/waves/SpecialWave.java deleted file mode 100644 index 1bf49d8..0000000 --- a/src/com/garbagemule/MobArena/waves/SpecialWave.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.garbagemule.MobArena.waves; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; - -import org.bukkit.Location; -//import org.bukkit.util.config.Configuration; - -import com.garbagemule.MobArena.Arena; -import com.garbagemule.MobArena.MAUtils; -import com.garbagemule.MobArena.Msg; -import com.garbagemule.MobArena.util.Config; -import com.garbagemule.MobArena.util.WaveUtils; - -public class SpecialWave extends NormalWave -{ - // Recurrent - public SpecialWave(Arena arena, String name, int wave, int frequency, int priority, Config config, String path) - { - super(arena, name, wave, frequency, priority, config, path); - load(config, path, WaveType.SPECIAL); - } - - // Single - public SpecialWave(Arena arena, String name, int wave, Config config, String path) - { - super(arena, name, wave, config, path); - load(config, path, WaveType.SPECIAL); - } - - public void spawn(int wave) - { - // Announce spawning - MAUtils.tellAll(getArena(), Msg.WAVE_SPECIAL, ""+wave); - - // Get the valid spawnpoints, and initialize counter - List validSpawnpoints = WaveUtils.getValidSpawnpoints(getArena(), getArena().getLivingPlayers()); - - // Strike some lightning! - if (getArena().isLightningEnabled()) - for (Location loc : validSpawnpoints) - getWorld().strikeLightningEffect(loc); - - // Spawn all the monsters - spawnAll(getMonstersToSpawn(getArena().getPlayerCount()), validSpawnpoints); - } - - private Map getMonstersToSpawn(int playerCount) - { - Map result = new HashMap(); - - Random random = new Random(); - int randomNumber = random.nextInt(getTotalProbability()); - for (Map.Entry entry : getProbabilityMap().entrySet()) - { - if (randomNumber > entry.getKey()) continue; - - int amount; - switch (entry.getValue()) - { - case POWEREDCREEPERS: - case ZOMBIEPIGMEN: - case ANGRYWOLVES: amount = playerCount * 2; break; - case SLIMES: amount = playerCount * 4; break; - case GIANTS: - case GHASTS: amount = 2; - default: amount = playerCount + 1; break; - } - - result.put(entry.getValue(), (int) (amount * getAmountMultiplier())); - break; - } - - return result; - } -} diff --git a/src/com/garbagemule/MobArena/waves/SwarmWave.java b/src/com/garbagemule/MobArena/waves/SwarmWave.java deleted file mode 100644 index d23fadc..0000000 --- a/src/com/garbagemule/MobArena/waves/SwarmWave.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.garbagemule.MobArena.waves; - -import java.util.List; - -import org.bukkit.Location; -import org.bukkit.entity.LivingEntity; -//import org.bukkit.util.config.Configuration; - -import com.garbagemule.MobArena.Arena; -import com.garbagemule.MobArena.MAUtils; -import com.garbagemule.MobArena.Msg; -import com.garbagemule.MobArena.util.Config; -import com.garbagemule.MobArena.util.WaveUtils; - -public class SwarmWave extends AbstractWave -{ - private MACreature monster; - private SwarmAmount amount; - - // Recurrent - public SwarmWave(Arena arena, String name, int wave, int frequency, int priority, Config config, String path) - { - super(arena, name, wave, frequency, priority); - load(config, path); - } - - // Single - public SwarmWave(Arena arena, String name, int wave, Config config, String path) - { - super(arena, name, wave); - load(config, path); - } - - private void load(Config config, String path) - { - // Set the wave type - setType(WaveType.SWARM); - - // Get the monster type - monster = MACreature.fromString(config.getString(path + "monster")); - - // And the amount - amount = WaveUtils.getEnumFromString(SwarmAmount.class, config.getString(path + "amount"), SwarmAmount.LOW); - - // Load multipliers - setHealthMultiplier(MAUtils.getDouble(config, path + "health-multiplier", 1D)); - setAmountMultiplier(MAUtils.getDouble(config, path + "amount-multiplier", 1D)); - } - - public void spawn(int wave) - { - // Announce spawning - MAUtils.tellAll(getArena(), Msg.WAVE_SWARM, ""+wave); - - // Get the valid spawnpoints, and initialize counter - List validSpawnpoints = WaveUtils.getValidSpawnpoints(getArena(), getArena().getLivingPlayers()); - - // Spawn the hellians! - int toSpawn = (int) (amount.getAmount(getArena().getPlayerCount()) * getAmountMultiplier()); - spawnAll(monster, toSpawn, validSpawnpoints); - } - - public void spawnAll(MACreature monster, int amount, List spawnpoints) - { - int spawnpointCount = spawnpoints.size(); - for (int i = 0; i < amount; i++) - { - LivingEntity e = spawnMonster(monster, spawnpoints.get(i % spawnpointCount)); - if (e == null) continue; - - // Boost health - int health = (int) Math.min(150D, 1 * getHealthMultiplier()); - e.setHealth(Math.max(1, health)); - } - } -} diff --git a/src/com/garbagemule/MobArena/waves/Wave.java b/src/com/garbagemule/MobArena/waves/Wave.java index 49260d8..b7a98c2 100644 --- a/src/com/garbagemule/MobArena/waves/Wave.java +++ b/src/com/garbagemule/MobArena/waves/Wave.java @@ -1,144 +1,136 @@ package com.garbagemule.MobArena.waves; -import com.garbagemule.MobArena.Arena; -import com.garbagemule.MobArena.util.WaveUtils; +import java.util.List; +import java.util.Map; + +import org.bukkit.Location; + +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.waves.enums.*; public interface Wave { - public enum WaveBranch - { - SINGLE, RECURRENT; - } - - public enum WaveType - { - DEFAULT, SPECIAL, SWARM, BOSS; - - public static WaveType fromString(String string) - { - return WaveUtils.getEnumFromString(WaveType.class, string); - } - } - - public enum WaveGrowth - { - OLD(0), SLOW(0.5), MEDIUM(0.65), FAST(0.8), PSYCHO(1.2); - private double exp; - - private WaveGrowth(double exp) - { - this.exp = exp; - } - - public static WaveGrowth fromString(String string) - { - return WaveUtils.getEnumFromString(WaveGrowth.class, string, OLD); - } - - public int getAmount(int wave, int playerCount) - { - if (this == OLD) return wave + playerCount; - - double pc = (double) playerCount; - double w = (double) wave; - - double base = Math.min(Math.ceil(pc/2) + 1, 13); - return (int) ( base * Math.pow(w, exp) ); - } - } - - public enum BossHealth - { - LOW(8), MEDIUM(15), HIGH(25), PSYCHO(40); - private int multiplier; - - private BossHealth(int multiplier) - { - this.multiplier = multiplier; - } - - public int getAmount(int playerCount) - { - return (playerCount + 1) * 20 * multiplier; - } - - public static BossHealth fromString(String string) - { - return WaveUtils.getEnumFromString(BossHealth.class, string); - } - } - - public enum SwarmAmount - { - LOW(10), MEDIUM(20), HIGH(30), PSYCHO(60); - private int multiplier; - - private SwarmAmount(int multiplier) - { - this.multiplier = multiplier; - } - - public int getAmount(int playerCount) - { - return Math.max(1, playerCount / 2) * multiplier; - } - - public static SwarmAmount fromString(String string) - { - return WaveUtils.getEnumFromString(SwarmAmount.class, string); - } - } - /** - * The spawn() method must spawn one or more monsters in - * the arena. The monster count, damage, health, etc. can - * be modified by the wave parameter. - * @param wave Wave number + * Populate a map of which monsters and how many of each this + * wave should spawn, given the wave number, player count and + * an arena object. + * @param wave the current wave number + * @param playerCount the amount of players + * @param arena an Arena + * @return a collection of MACreatures and how many of each to spawn */ - public void spawn(int wave); + public Map getMonstersToSpawn(int wave, int playerCount, Arena arena); /** - * Get the type of wave. - * @return The WaveType of this Wave. + * Get a list of spawnpoints upon which the monsters of this + * wave may be spawned. Note that it is expected that the + * getMonstersToSpawn() method is called first, and that each + * monster is then spawned on a location given in the list + * from this method. + * @param arena an Arena + * @return a list of valid spawnpoints */ - public WaveType getType(); + public List getSpawnpoints(Arena arena); + + /** + * Set the list of spawnpoints on which the monsters of this + * wave may be spawned. If the value is null, all spawnpoints + * of the arena region will be considered. + * @param spawnpoints a list of spawnpoints + */ + public void setSpawnpoints(List spawnpoints); + + /** + * Announce to all players that this wave is spawning. + * @param arena an arena + * @param wave a wave number + */ + public void announce(Arena arena, int wave); + + /** + * Get the wave's name. + * @return The name + */ + public String getName(); + + /** + * Set the name of this wave. + * @param name a name + */ + public void setName(String name); /** * Get the branch type. * @return The WaveBranch of this Wave. */ public WaveBranch getBranch(); + + /** + * Set the type of branch + * @param branch recurrent or single + */ + public void setBranch(WaveBranch branch); /** - * Get the growth rate of this wave. - * @return The growth rate + * Get the type of wave. + * @return a WaveType */ - public WaveGrowth getGrowth(); + public WaveType getType(); + + /** + * Set the type of wave. + * @param type a WaveType + */ + public void setType(WaveType type); /** - * Get the first wave number for this wave - * @return The wave number + * Get the first wave this Wave instance may spawn on. + * @return a wave number */ - public int getWave(); + public int getFirstWave(); + + /** + * Set the first wave this Wave instance may spawn on. + * @param firstWave a wave number + */ + public void setFirstWave(int firstWave); /** * Get the wave's frequency, i.e. wave number "modulo" - * @return The wave's frequency + * @return a frequency */ public int getFrequency(); + /** + * Set the wave's frequency + * @param frequency a frequency + */ + public void setFrequency(int frequency); + /** * Get the wave's priority value. - * @return The priority + * @return a priority */ public int getPriority(); + /** + * Set the wave's priority. + * @param priority a priority + */ + public void setPriority(int priority); + /** * Get the wave's health multiplier. * @return The health multiplier */ public double getHealthMultiplier(); + /** + * Get the wave's health multiplier. + * @param healthMultiplier a double in the range ]0;1] + */ + public void setHealthMultiplier(double healthMultiplier); + /** * Get the wave's amount multiplier. * @return The amount multiplier @@ -146,22 +138,10 @@ public interface Wave public double getAmountMultiplier(); /** - * Get the wave's name. - * @return The name + * Set the wave's amount multiplier. + * @param amountMultiplier a positive double */ - public String getName(); - - /** - * Get the arena of this wave. - * @return The arena - */ - public Arena getArena(); - - /** - * Set the wave's growth - * @param growth How fast the wave will grow - */ - public void setGrowth(WaveGrowth growth); + public void setAmountMultiplier(double amountMultiplier); /** * Check if this wave matches the wave number. diff --git a/src/com/garbagemule/MobArena/waves/WaveManager.java b/src/com/garbagemule/MobArena/waves/WaveManager.java new file mode 100644 index 0000000..590abee --- /dev/null +++ b/src/com/garbagemule/MobArena/waves/WaveManager.java @@ -0,0 +1,137 @@ +package com.garbagemule.MobArena.waves; + +import java.util.SortedSet; +import java.util.TreeSet; + +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.util.config.Config; +import com.garbagemule.MobArena.util.config.ConfigSection; +import com.garbagemule.MobArena.waves.enums.*; + +public class WaveManager +{ + private Arena arena; + private Config config; + + private Wave defaultWave, currentWave; + private TreeSet recurrentWaves, singleWaves, singleWavesInstance; + + private int wave, finalWave; + + public WaveManager(Arena arena, Config config) { + this.arena = arena; + this.config = config; + this.wave = 0; + this.finalWave = 0; + + reloadWaves(); + } + + public void reload() { + config.load(); + reloadWaves(); + } + + public void save() { + config.save(); + } + + public TreeSet getRecurrentWaves() { + return recurrentWaves; + } + + public void reset() { + wave = 0; + singleWavesInstance = new TreeSet(singleWaves); + } + + public void reloadWaves() { + ConfigSection rConfig = config.getConfigSection("arenas." + arena.configName() + ".waves.recurrent"); + ConfigSection sConfig = config.getConfigSection("arenas." + arena.configName() + ".waves.single"); + + recurrentWaves = WaveParser.parseWaves(arena, rConfig, WaveBranch.RECURRENT); + singleWaves = WaveParser.parseWaves(arena, sConfig, WaveBranch.SINGLE); + + finalWave = config.getInt("arenas." + arena.configName() + ".settings.final-wave", 0); + + if (recurrentWaves.isEmpty()) { + arena.getPlugin().warning(WaveError.NO_RECURRENT_WAVES.format(arena.configName())); + + Wave def = WaveParser.createDefaultWave(); + recurrentWaves.add(def); + } + + defaultWave = recurrentWaves.first(); + } + + /** + * Increment the wave number and get the next Wave to be spawned. + * Note that this method is a mutator. + * @return the next Wave + */ + public Wave next() { + wave++; + + if (!singleWavesInstance.isEmpty() && singleWavesInstance.first().matches(wave)) { + currentWave = singleWavesInstance.pollFirst(); + } + else { + SortedSet matches = getMatchingRecurrentWaves(wave); + currentWave = (matches.isEmpty() ? defaultWave : matches.last()); + } + + return currentWave; + } + + /** + * Get the next Wave to be spawned. This is an accessor and does not + * advance the "counter". Note that the Wave objects, however, are + * mutable. + * @return the next Wave + */ + public Wave getNext() { + int next = wave + 1; + + if (!singleWavesInstance.isEmpty() && singleWavesInstance.first().matches(next)) { + return singleWavesInstance.first(); + } + + SortedSet matches = getMatchingRecurrentWaves(wave); + return (matches.isEmpty() ? defaultWave : matches.last()); + } + + /** + * Get the current wave that's being used. + * Note that the current wave might not have spawned yet. + * @return the current wave + */ + public Wave getCurrent() { + return currentWave; + } + + /** + * Get the current wave number. + * @return the current wave number + */ + public int getWaveNumber() { + return wave; + } + + /** + * Get the final wave number. + * @return the final wave number + */ + public int getFinalWave() { + return finalWave; + } + + private SortedSet getMatchingRecurrentWaves(int wave) { + TreeSet result = new TreeSet(WaveUtils.getRecurrentComparator()); + for (Wave w : recurrentWaves) { + if (w.matches(wave)) { + result.add(w); + } + } + return result; + } +} diff --git a/src/com/garbagemule/MobArena/waves/WaveParser.java b/src/com/garbagemule/MobArena/waves/WaveParser.java new file mode 100644 index 0000000..cb5904a --- /dev/null +++ b/src/com/garbagemule/MobArena/waves/WaveParser.java @@ -0,0 +1,380 @@ +package com.garbagemule.MobArena.waves; + +import java.util.*; + +import org.bukkit.Location; +import org.bukkit.inventory.ItemStack; + +import com.garbagemule.MobArena.MobArena; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.region.ArenaRegion; +import com.garbagemule.MobArena.util.ItemParser; +import com.garbagemule.MobArena.util.config.ConfigSection; +import com.garbagemule.MobArena.waves.enums.*; +import com.garbagemule.MobArena.waves.types.BossWave; +import com.garbagemule.MobArena.waves.types.DefaultWave; +import com.garbagemule.MobArena.waves.types.SpecialWave; +import com.garbagemule.MobArena.waves.types.SupplyWave; +import com.garbagemule.MobArena.waves.types.SwarmWave; +import com.garbagemule.MobArena.waves.types.UpgradeWave; + +public class WaveParser +{ + public static TreeSet parseWaves(Arena arena, ConfigSection config, WaveBranch branch) { + // Grab the plugin for error reporting. + MobArena plugin = arena.getPlugin(); + + // Create a TreeSet with the Comparator for the specific branch. + TreeSet result = new TreeSet(WaveUtils.getComparator(branch)); + + // If the config is null, return the empty set. + if (config == null) { + plugin.warning(WaveError.BRANCH_MISSING.format(branch.toString().toLowerCase(), arena.configName())); + return result; + } + + // If no waves were found, return the empty set. + Set waves = config.getKeys(); + if (waves == null/* || waves.isEmpty()*/) { + plugin.warning(WaveError.BRANCH_MISSING.format(branch.toString().toLowerCase(), arena.configName())); + return result; + } + + // Otherwise, parse each wave in the branch. + for (String wave : waves) { + ConfigSection waveSection = config.getConfigSection(wave); + Wave w = parseWave(arena, wave, waveSection, branch); + + // Only add properly parsed waves. + if (w == null) { + continue; + } + + result.add(w); + } + + return result; + } + + public static Wave parseWave(Arena arena, String name, ConfigSection config, WaveBranch branch) { + // Grab the plugin for error reporting. + MobArena plugin = arena.getPlugin(); + + // Grab the WaveType and verify that it isn't null. + String t = config.getString("type", null); + WaveType type = WaveType.fromString(t); + + if (type == null) { + plugin.warning(WaveError.INVALID_TYPE.format(t, name, arena.configName())); + return null; + } + + // Prepare the result + Wave result = null; + + // Switch on the type of wave. + switch (type) { + case DEFAULT: + result = parseDefaultWave(arena, name, config); + break; + case SPECIAL: + result = parseSpecialWave(arena, name, config); + break; + case SWARM: + result = parseSwarmWave(arena, name, config); + break; + case SUPPLY: + result = parseSupplyWave(arena, name, config); + break; + case UPGRADE: + result = parseUpgradeWave(arena, name, config); + break; + case BOSS: + result = parseBossWave(arena, name, config); + break; + } + + // Check that the result isn't null + if (result == null) { + plugin.warning(WaveError.INVALID_WAVE.format(name, arena.configName())); + return null; + } + + // Grab the branch-specific nodes. + int priority = config.getInt("priority", -1); + int frequency = config.getInt("frequency", -1); + int firstWave = config.getInt("wave", frequency); + + // Get multipliers + double healthMultiplier = config.getDouble("health-multiplier", -1D); + if (healthMultiplier == -1D) { + healthMultiplier = config.getInt("health-multiplier", 1); + } + + double amountMultiplier = config.getDouble("amount-multiplier", -1D); + if (amountMultiplier == -1D) { + amountMultiplier = config.getInt("amount-multiplier", 1); + } + + // Grab the specific spawnpoints if any + List spawnpoints = getSpawnpoints(arena, name, config); + + // Recurrent must have priority + frequency, single must have firstWave + if (branch == WaveBranch.RECURRENT && (priority == -1 || frequency <= 0)) { + plugin.warning(WaveError.RECURRENT_NODES.format(name, arena.configName())); + return null; + } else if (branch == WaveBranch.SINGLE && firstWave <= 0) { + plugin.warning(WaveError.SINGLE_NODES.format(name, arena.configName())); + return null; + } + + // Set the important required values. + result.setName(name); + result.setBranch(branch); + result.setFirstWave(firstWave); + result.setPriority(priority); + result.setFrequency(frequency); + + // And the multipliers. + result.setHealthMultiplier(healthMultiplier); + result.setAmountMultiplier(amountMultiplier); + + // Aaand the spawnpoints + result.setSpawnpoints(spawnpoints); + + return result; + } + + private static Wave parseDefaultWave(Arena arena, String name, ConfigSection config) { + // Grab the monster map. + SortedMap monsters = getMonsterMap(config); + if (monsters == null || monsters.isEmpty()) { + arena.getPlugin().warning(WaveError.MONSTER_MAP_MISSING.format(name, arena.configName())); + return null; + } + + // Create the wave. + DefaultWave result = new DefaultWave(monsters); + + // Grab the WaveGrowth + String grw = config.getString("growth"); + WaveGrowth growth = WaveGrowth.fromString(grw); + result.setGrowth(growth); + + return result; + } + + private static Wave parseSpecialWave(Arena arena, String name, ConfigSection config) { + SortedMap monsters = getMonsterMap(config); + if (monsters == null || monsters.isEmpty()) { + arena.getPlugin().warning(WaveError.MONSTER_MAP_MISSING.format(name, arena.configName())); + return null; + } + + SpecialWave result = new SpecialWave(monsters); + return result; + } + + private static Wave parseSwarmWave(Arena arena, String name, ConfigSection config) { + MACreature monster = getSingleMonster(config); + if (monster == null) { + arena.getPlugin().warning(WaveError.SINGLE_MONSTER_MISSING.format(name, arena.configName())); + return null; + } + + SwarmWave result = new SwarmWave(monster); + + // Grab SwarmAmount + String amnt = config.getString("amount"); + SwarmAmount amount = SwarmAmount.fromString(amnt); + result.setAmount(amount); + + return result; + } + + private static Wave parseSupplyWave(Arena arena, String name, ConfigSection config) { + SortedMap monsters = getMonsterMap(config); + if (monsters == null || monsters.isEmpty()) { + arena.getPlugin().warning(WaveError.MONSTER_MAP_MISSING.format(name, arena.configName())); + return null; + } + + SupplyWave result = new SupplyWave(monsters); + + // Grab the loot. + String loot = config.getString("drops"); + List stacks = ItemParser.parseItems(loot); + result.setDropList(stacks); + + return result; + } + + private static Wave parseUpgradeWave(Arena arena, String name, ConfigSection config) { + Map> classMap = getUpgradeMap(config); + if (classMap == null || classMap.isEmpty()) { + arena.getPlugin().warning(WaveError.UPGRADE_MAP_MISSING.format(name, arena.configName())); + return null; + } + + UpgradeWave result = new UpgradeWave(classMap); + + // Determine if all items should be given + boolean giveAll = config.getBoolean("give-all-items", false); + result.setGiveAll(giveAll); + + return result; + } + + private static Wave parseBossWave(Arena arena, String name, ConfigSection config) { + MACreature monster = getSingleMonster(config); + if (monster == null) { + arena.getPlugin().warning(WaveError.SINGLE_MONSTER_MISSING.format(name, arena.configName())); + return null; + } + + BossWave result = new BossWave(monster); + + // Grab the boss health + String hlth = config.getString("health"); + BossHealth health = BossHealth.fromString(hlth); + result.setHealth(health); + + // And the abilities. + String ablts = config.getString("abilities"); + if (ablts != null) { + String[] parts = ablts.split(","); + for (String ability : parts) { + BossAbility a = BossAbility.fromString(ability.trim()); + if (a == null) { + arena.getPlugin().warning(WaveError.BOSS_ABILITY.format(ability.trim(), name, arena.configName())); + continue; + } + + result.addBossAbility(a); + } + } + + // As well as the ability interval. + int interval = config.getInt("ability-interval", 3) * 20; + result.setAbilityInterval(interval); + + return result; + } + + /** + * Scan the ConfigSection for a "monster" (singular) node, which + * must be exactly a single monster. + * @param config a ConfigSection + * @return an MACreature, if the monster node contains one that is valid + */ + private static MACreature getSingleMonster(ConfigSection config) { + String monster = config.getString("monster"); + if (monster == null) { + return null; + } + + MACreature result = MACreature.fromString(monster); + return result; + } + + /** + * Scan the ConfigSection for a "monsters" (plural) node, which + * must contain a list of at least one "monster: number" node. + * @param config + * @return a "reverse" map of monsters and numbers + */ + private static SortedMap getMonsterMap(ConfigSection config) { + Set monsters = config.getKeys("monsters"); + if (monsters == null || monsters.isEmpty()) { + return null; + } + + // Prepare the map. + SortedMap monsterMap = new TreeMap(); + int sum = 0; + String path = "monsters."; + + // Check all the monsters. + for (String monster : monsters) { + MACreature creature = MACreature.fromString(monster); + if (creature == null) continue; + + int prob = config.getInt(path + monster, 0); + if (prob == 0) continue; + + sum += prob; + monsterMap.put(sum, creature); + } + + return monsterMap; + } + + private static List getSpawnpoints(Arena arena, String name, ConfigSection config) { + MobArena plugin = arena.getPlugin(); + List result = new ArrayList(); + + String spawnString = config.getString("spawnpoints"); + if (spawnString == null) { + return result; + } + + // Split the string by commas + String[] spawns = spawnString.split(","); + + ArenaRegion region = arena.getRegion(); + for (String spawn : spawns) { + Location spawnpoint = region.getSpawnpoint(spawn.trim()); + + if (spawnpoint == null) { + plugin.warning("Spawnpoint '" + spawn + "' in wave '" + name + "' for arena '" + arena.configName() + "' could not be parsed!"); + continue; + } + + result.add(spawnpoint); + } + + return result; + } + + private static Map> getUpgradeMap(ConfigSection config) { + Set classes = config.getKeys("upgrades"); + if (classes == null || classes.isEmpty()) { + return null; + } + + Map> upgrades = new HashMap>(); + String path = "upgrades."; + + for (String className : classes) { + String itemList = config.getString(path + className); + List stacks = ItemParser.parseItems(itemList); + + if (className.equalsIgnoreCase("All")) { + className = "All"; + } + upgrades.put(className.toLowerCase(), stacks); + } + + return upgrades; + } + + public static Wave createDefaultWave() { + SortedMap monsters = new TreeMap(); + monsters.put(10, MACreature.ZOMBIE); + monsters.put(20, MACreature.SKELETON); + monsters.put(30, MACreature.SPIDER); + monsters.put(40, MACreature.SLIMESMALL); + + DefaultWave result = new DefaultWave(monsters); + result.setName("MA_DEFAULT_WAVE"); + result.setBranch(WaveBranch.RECURRENT); + result.setFirstWave(1); + result.setPriority(1); + result.setFrequency(1); + result.setGrowth(WaveGrowth.OLD); + result.setHealthMultiplier(1D); + result.setAmountMultiplier(1D); + + return result; + } +} diff --git a/src/com/garbagemule/MobArena/util/WaveUtils.java b/src/com/garbagemule/MobArena/waves/WaveUtils.java similarity index 77% rename from src/com/garbagemule/MobArena/util/WaveUtils.java rename to src/com/garbagemule/MobArena/waves/WaveUtils.java index d2fc686..f39e2c0 100644 --- a/src/com/garbagemule/MobArena/util/WaveUtils.java +++ b/src/com/garbagemule/MobArena/waves/WaveUtils.java @@ -1,57 +1,55 @@ -package com.garbagemule.MobArena.util; +package com.garbagemule.MobArena.waves; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.List; -import java.util.Set; -import java.util.TreeSet; import org.bukkit.Location; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; -//import org.bukkit.util.config.Configuration; -import com.garbagemule.MobArena.Arena; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.waves.enums.*; import com.garbagemule.MobArena.MAUtils; import com.garbagemule.MobArena.MobArena; -import com.garbagemule.MobArena.waves.*; -import com.garbagemule.MobArena.waves.Wave.*; public class WaveUtils { /** * Get all the spawnpoints that have players nearby. - */ - public static List getValidSpawnpoints(Arena arena, Collection players) - { + */ + public static List getValidSpawnpoints(Arena arena, List spawnpoints, Collection players) { + MobArena plugin = arena.getPlugin(); List result = new ArrayList(); - for (Location l : arena.getSpawnpoints()) - { - for (Player p : players) - { - if (MAUtils.distanceSquared(p, l) >= MobArena.MIN_PLAYER_DISTANCE_SQUARED) + // Ensure that we do have some spawnpoints. + if (spawnpoints == null || spawnpoints.isEmpty()) { + spawnpoints = arena.getRegion().getSpawnpointList(); + } + + // Loop through each one and check if any players are in range. + for (Location l : spawnpoints) { + for (Player p : players) { + if (MAUtils.distanceSquared(plugin, p, l) >= MobArena.MIN_PLAYER_DISTANCE_SQUARED) { continue; - + } result.add(l); break; } } - // If no players are in range, just use all the spawnpoints. - if (result.isEmpty()) - { - MobArena.warning("Spawnpoints of arena '" + arena.configName() + "' may be too far apart!"); - return arena.getAllSpawnpoints();//result.addAll(arena.getAllSpawnpoints()); + // If no spawnpoints in range, just return all of them. + if (result.isEmpty()) { + plugin.warning("Spawnpoints of arena '" + arena.configName() + "' may be too far apart!"); + return spawnpoints; } - - // Else, return the valid spawnpoints. return result; } public static Player getClosestPlayer(Arena arena, Entity e) { + MobArena plugin = arena.getPlugin(); // Set up the comparison variable and the result. double dist = 0; double current = Double.POSITIVE_INFINITY; @@ -59,11 +57,11 @@ public class WaveUtils /* Iterate through the ArrayList, and update current and result every * time a squared distance smaller than current is found. */ - for (Player p : arena.getLivingPlayers()) + for (Player p : arena.getPlayersInArena()) { if (!arena.getWorld().equals(p.getWorld())) { - MobArena.info("Player '" + p.getName() + "' is not in the right world. Kicking..."); + plugin.info("Player '" + p.getName() + "' is not in the right world. Kicking..."); p.kickPlayer("[MobArena] Cheater! (Warped out of the arena world.)"); continue; } @@ -81,8 +79,9 @@ public class WaveUtils /** * Grab and process all the waves in the config-file for the arena. */ - public static TreeSet getWaves(Arena arena, Config config, WaveBranch branch) + /*public static TreeSet getWaves(Arena arena, Config config, WaveBranch branch) { + MobArena plugin = arena.getPlugin(); // Determine the branch type of the wave, and grab the appropriate comparator String b = branch.toString().toLowerCase(); TreeSet result = new TreeSet(getComparator(branch)); @@ -102,14 +101,14 @@ public class WaveUtils wave = getWave(arena, config, path + "." + w + ".", w, branch); if (wave != null) result.add(wave); - else MobArena.warning("Wave '" + w + "' in " + path + " was not added!"); + else plugin.warning("Wave '" + w + "' in " + path + " was not added!"); } } // If there are no waves and the type is 'recurrent', add a couple of auto-generated waves. if (branch == WaveBranch.RECURRENT && (result.isEmpty() || waves == null)) { - MobArena.info("No valid recurrent waves detected for arena '" + arena.configName() + "'. Using defaults..."); + plugin.info("No valid recurrent waves detected for arena '" + arena.configName() + "'. Using defaults..."); DefaultWave def = new DefaultWave(arena, "DEF_WAVE_AUTO", 1, 1, 1, config, path + ".DEF_WAVE_AUTO."); SpecialWave spec = new SpecialWave(arena, "SPEC_WAVE_AUTO", 4, 4, 2, config, path + ".SPEC_WAVE_AUTO."); result.add(def); @@ -117,17 +116,19 @@ public class WaveUtils } return result; - } + }*/ /** * Get a single wave based on the config-file, the path, and branch * @return A Wave object if it is well defined, null otherwise. */ - private static Wave getWave(Arena arena, Config config, String path, String name, WaveBranch branch) + /*private static Wave getWave(Arena arena, Config config, String path, String name, WaveBranch branch) { + MobArena plugin = arena.getPlugin(); + // Grab the wave type, if null or not well defined, return null WaveType type = WaveType.fromString(config.getString(path + "type")); - if (type == null || !isWaveWellDefined(config, path, branch, type)) + if (type == null || !isWaveWellDefined(plugin, config, path, branch, type)) return null; Wave result = null; @@ -160,7 +161,7 @@ public class WaveUtils result = new BossWave(arena, name, wave, config, path); } return result; - } + }*/ @@ -184,7 +185,7 @@ public class WaveUtils * @param type The wave type * @return true, only if the entire wave-node is well-defined. */ - private static boolean isWaveWellDefined(Config config, String path, WaveBranch branch, WaveType type) + /*private static boolean isWaveWellDefined(MobArena plugin, Config config, String path, WaveBranch branch, WaveType type) { // This boolean is used in the "leaf methods" boolean wellDefined = true; @@ -193,7 +194,7 @@ public class WaveUtils int hMulti = MAUtils.getInt(config, path + "health-multiplier"); if (hMulti < 0) { - MobArena.warning("Invalid health multiplier '" + hMulti + "' in " + path); + plugin.warning("Invalid health multiplier '" + hMulti + "' in " + path); wellDefined = false; } @@ -201,7 +202,7 @@ public class WaveUtils int aMulti = MAUtils.getInt(config, path + "amount-multiplier"); if (aMulti < 0) { - MobArena.warning("Invalid amount multiplier '" + aMulti + "' in " + path); + plugin.warning("Invalid amount multiplier '" + aMulti + "' in " + path); wellDefined = false; } @@ -213,12 +214,12 @@ public class WaveUtils int frequency = config.getInt(path + "frequency", 0); if (priority == 0) { - MobArena.warning("Missing 'priority'-node in " + path); + plugin.warning("Missing 'priority'-node in " + path); wellDefined = false; } if (frequency == 0) { - MobArena.warning("Missing 'frequency'-node in " + path); + plugin.warning("Missing 'frequency'-node in " + path); wellDefined = false; } @@ -226,7 +227,7 @@ public class WaveUtils int wave = MAUtils.getInt(config, path + "wave"); if (wave < 0) { - MobArena.warning("'wave' must be greater than 0 in " + path); + plugin.warning("'wave' must be greater than 0 in " + path); wellDefined = false; } } @@ -236,20 +237,20 @@ public class WaveUtils int wave = MAUtils.getInt(config, path + "wave"); if (wave == 0) { - MobArena.warning("Missing 'wave'-node in " + path); + plugin.warning("Missing 'wave'-node in " + path); wellDefined = false; } else if (wave < 0) { - MobArena.warning("'wave' must be greater than 0 in " + path); + plugin.warning("'wave' must be greater than 0 in " + path); wellDefined = false; } } else wellDefined = false; // Passed branch-checks; check type - return isTypeWellDefined(config, path, type, wellDefined); - } + return isTypeWellDefined(plugin, config, path, type, wellDefined); + }*/ /** * Check if a wave type in the config-file is well-defined. @@ -261,19 +262,19 @@ public class WaveUtils * @param wellDefined Pass-through boolean for "leaf methods". * @return true, only if the entire wave-node is well-defined. */ - private static boolean isTypeWellDefined(Config config, String path, WaveType type, boolean wellDefined) + /*private static boolean isTypeWellDefined(MobArena plugin, Config config, String path, WaveType type, boolean wellDefined) { if (type == WaveType.DEFAULT) - return isDefaultWaveWellDefined(config, path, wellDefined); + return isDefaultWaveWellDefined(plugin, config, path, wellDefined); else if (type == WaveType.SPECIAL) - return isSpecialWaveWellDefined(config, path, wellDefined); + return isSpecialWaveWellDefined(plugin, config, path, wellDefined); else if (type == WaveType.BOSS) - return isBossWaveWellDefined(config, path, wellDefined); + return isBossWaveWellDefined(plugin, config, path, wellDefined); else if (type == WaveType.SWARM) - return isSwarmWaveWellDefined(config, path, wellDefined); + return isSwarmWaveWellDefined(plugin, config, path, wellDefined); return false; - } + }*/ /** * Check if a default wave is well-defined. @@ -284,18 +285,18 @@ public class WaveUtils * @param wellDefined Pass-through boolean for "leaf methods". * @return true, only if the entire wave-node is well-defined. */ - private static boolean isDefaultWaveWellDefined(Config config, String path, boolean wellDefined) + /*private static boolean isDefaultWaveWellDefined(MobArena plugin, Config config, String path, boolean wellDefined) { // OPTIONAL: Wave growth String growth = config.getString(path + "growth"); if (growth != null && WaveGrowth.fromString(growth) == null) { - MobArena.warning("Invalid wave growth '" + growth + "' in " + path); + plugin.warning("Invalid wave growth '" + growth + "' in " + path); wellDefined = false; } - return isNormalWaveWellDefined(config, path, wellDefined); - } + return isNormalWaveWellDefined(plugin, config, path, wellDefined); + }*/ /** * Check if a special wave is well-defined. @@ -305,10 +306,10 @@ public class WaveUtils * @param wellDefined Pass-through boolean for "leaf methods". * @return true, only if the entire wave-node is well-defined. */ - private static boolean isSpecialWaveWellDefined(Config config, String path, boolean wellDefined) + /*private static boolean isSpecialWaveWellDefined(MobArena plugin, Config config, String path, boolean wellDefined) { - return isNormalWaveWellDefined(config, path, wellDefined); - } + return isNormalWaveWellDefined(plugin, config, path, wellDefined); + }*/ /** * Check if a default or special wave is well-defined. @@ -320,7 +321,7 @@ public class WaveUtils * @param wellDefined Pass-through boolean for "leaf methods". * @return true, wellDefined is true. */ - private static boolean isNormalWaveWellDefined(Config config, String path, boolean wellDefined) + /*private static boolean isNormalWaveWellDefined(MobArena plugin, Config config, String path, boolean wellDefined) { // OPTIONAL: Monsters Set monsters = config.getKeys(path + "monsters"); @@ -331,14 +332,14 @@ public class WaveUtils if (MACreature.fromString(monster) != null) continue; - MobArena.warning("Invalid monster type '" + monster + "' in " + path); + plugin.warning("Invalid monster type '" + monster + "' in " + path); wellDefined = false; } } - else MobArena.info("No monsters listed in " + path + ", using defaults..."); + else plugin.info("No monsters listed in " + path + ", using defaults..."); return wellDefined; - } + }*/ /** * Check if a swarm wave is well defined @@ -347,18 +348,18 @@ public class WaveUtils * @param wellDefined Pass-through boolean for "leaf methods". * @return true, wellDefined is true. */ - private static boolean isSwarmWaveWellDefined(Config config, String path, boolean wellDefined) + /*private static boolean isSwarmWaveWellDefined(MobArena plugin, Config config, String path, boolean wellDefined) { // REQUIRED: Monster type String monster = config.getString(path + "monster"); if (monster == null) { - MobArena.warning("Missing monster type in '" + path); + plugin.warning("Missing monster type in '" + path); wellDefined = false; } else if (MACreature.fromString(monster) == null) { - MobArena.warning("Invalid monster type '" + monster + "' in " + path); + plugin.warning("Invalid monster type '" + monster + "' in " + path); wellDefined = false; } @@ -366,12 +367,12 @@ public class WaveUtils String amount = config.getString(path + "amount"); if (amount != null && SwarmAmount.fromString(amount) == null) { - MobArena.warning("Invalid swarm amount '" + amount + "' in " + path); + plugin.warning("Invalid swarm amount '" + amount + "' in " + path); wellDefined = false; } return wellDefined; - } + }*/ /** * Check if a boss wave is well defined. @@ -380,18 +381,18 @@ public class WaveUtils * @param wellDefined Pass-through boolean for "leaf methods". * @return true, wellDefined is true. */ - private static boolean isBossWaveWellDefined(Config config, String path, boolean wellDefined) + /*private static boolean isBossWaveWellDefined(MobArena plugin, Config config, String path, boolean wellDefined) { // REQUIRED: Monster type String monster = config.getString(path + "monster"); if (monster == null) { - MobArena.warning("Missing monster type in '" + path); + plugin.warning("Missing monster type in '" + path); wellDefined = false; } else if (MACreature.fromString(monster) == null) { - MobArena.warning("Invalid monster type '" + monster + "' in " + path); + plugin.warning("Invalid monster type '" + monster + "' in " + path); wellDefined = false; } @@ -404,7 +405,7 @@ public class WaveUtils if (BossAbility.fromString(ability.trim()) != null) continue; - MobArena.warning("Invalid boss ability '" + ability + "' in " + path); + plugin.warning("Invalid boss ability '" + ability + "' in " + path); wellDefined = false; } } @@ -413,7 +414,7 @@ public class WaveUtils int abilityDelay = config.getInt(path + "ability-interval", 3); if (abilityDelay <= 0) { - MobArena.warning("Boss ability-delay must be greater than 0, " + path); + plugin.warning("Boss ability-delay must be greater than 0, " + path); wellDefined = false; } @@ -426,12 +427,12 @@ public class WaveUtils String health = config.getString(path + "health"); if (health != null && BossHealth.fromString(health) == null) { - MobArena.warning("Invalid boss health '" + health + "' in " + path); + plugin.warning("Invalid boss health '" + health + "' in " + path); wellDefined = false; } return wellDefined; - } + }*/ @@ -466,9 +467,9 @@ public class WaveUtils { public int compare(Wave w1, Wave w2) { - if (w1.getWave() < w2.getWave()) + if (w1.getFirstWave() < w2.getFirstWave()) return -1; - else if (w1.getWave() > w2.getWave()) + else if (w1.getFirstWave() > w2.getFirstWave()) return 1; else return 0; } diff --git a/src/com/garbagemule/MobArena/waves/enums/BossHealth.java b/src/com/garbagemule/MobArena/waves/enums/BossHealth.java new file mode 100644 index 0000000..78ea0b8 --- /dev/null +++ b/src/com/garbagemule/MobArena/waves/enums/BossHealth.java @@ -0,0 +1,21 @@ +package com.garbagemule.MobArena.waves.enums; + +import com.garbagemule.MobArena.waves.WaveUtils; + +public enum BossHealth +{ + LOW(8), MEDIUM(15), HIGH(25), PSYCHO(40); + private int multiplier; + + private BossHealth(int multiplier) { + this.multiplier = multiplier; + } + + public int getMax(int playerCount) { + return (playerCount + 1) * 20 * multiplier; + } + + public static BossHealth fromString(String string) { + return WaveUtils.getEnumFromString(BossHealth.class, string, MEDIUM); + } +} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/waves/enums/SwarmAmount.java b/src/com/garbagemule/MobArena/waves/enums/SwarmAmount.java new file mode 100644 index 0000000..81a5a2d --- /dev/null +++ b/src/com/garbagemule/MobArena/waves/enums/SwarmAmount.java @@ -0,0 +1,21 @@ +package com.garbagemule.MobArena.waves.enums; + +import com.garbagemule.MobArena.waves.WaveUtils; + +public enum SwarmAmount +{ + LOW(10), MEDIUM(20), HIGH(30), PSYCHO(60); + private int multiplier; + + private SwarmAmount(int multiplier) { + this.multiplier = multiplier; + } + + public int getAmount(int playerCount) { + return Math.max(1, playerCount / 2) * multiplier; + } + + public static SwarmAmount fromString(String string) { + return WaveUtils.getEnumFromString(SwarmAmount.class, string, LOW); + } +} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/waves/enums/WaveBranch.java b/src/com/garbagemule/MobArena/waves/enums/WaveBranch.java new file mode 100644 index 0000000..eaefcb8 --- /dev/null +++ b/src/com/garbagemule/MobArena/waves/enums/WaveBranch.java @@ -0,0 +1,25 @@ +package com.garbagemule.MobArena.waves.enums; + +import com.garbagemule.MobArena.waves.Wave; + +public enum WaveBranch +{ + SINGLE { + @Override + public boolean matches(int wave, Wave w) { + return (w.getFirstWave() == wave); + } + }, + + RECURRENT { + @Override + public boolean matches(int wave, Wave w) { + if (wave < w.getFirstWave()) { + return false; + } + return ((wave - w.getFirstWave()) % w.getFrequency() == 0); + } + }; + + public abstract boolean matches(int wave, Wave w); +} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/waves/enums/WaveError.java b/src/com/garbagemule/MobArena/waves/enums/WaveError.java new file mode 100644 index 0000000..6fe785a --- /dev/null +++ b/src/com/garbagemule/MobArena/waves/enums/WaveError.java @@ -0,0 +1,32 @@ +package com.garbagemule.MobArena.waves.enums; + +public enum WaveError +{ + INVALID_WAVE("Wave '%s' for arena '%s' could not be parsed."), + NO_RECURRENT_WAVES("No valid recurrent waves found for arena '%s'. Check the config-file. Using implicit default wave."), + + BRANCH_MISSING("The '%s' branch for arena '%s' is empty. Check the config-file."), + INVALID_TYPE("Invalid type '%s' for wave '%s' in arena '%s'. Skipping..."), + + RECURRENT_NODES("Recurrent wave '%s' in arena '%s' is missing either the 'frequency' or the 'priority' node. Skipping..."), + SINGLE_NODES("Single wave '%s' in arena '%s' is missing the 'wave' node. Skipping..."), + + MONSTER_MAP_MISSING("Missing 'monsters' node for wave '%s' in arena '%s'."), + SINGLE_MONSTER_MISSING("Missing 'monster' node for wave '%s' in arena '%s'."), + + BOSS_ABILITY("Invalid boss ability '%s' for wave '%s' in arena '%s'."), + + SUPPLY_DROPS("Missing 'drops' node for wave '%s' in arena '%s'."), + + UPGRADE_MAP_MISSING("Missing 'upgrades' node for wave '%s' in arena '%s'."); + + private String msg; + + private WaveError(String msg) { + this.msg = msg; + } + + public String format(Object... args) { + return String.format(msg, args); + } +} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/waves/enums/WaveGrowth.java b/src/com/garbagemule/MobArena/waves/enums/WaveGrowth.java new file mode 100644 index 0000000..f80e7af --- /dev/null +++ b/src/com/garbagemule/MobArena/waves/enums/WaveGrowth.java @@ -0,0 +1,27 @@ +package com.garbagemule.MobArena.waves.enums; + +import com.garbagemule.MobArena.waves.WaveUtils; + +public enum WaveGrowth +{ + OLD(0), SLOW(0.5), MEDIUM(0.65), FAST(0.8), PSYCHO(1.2); + private double exp; + + private WaveGrowth(double exp) { + this.exp = exp; + } + + public static WaveGrowth fromString(String string) { + return WaveUtils.getEnumFromString(WaveGrowth.class, string, OLD); + } + + public int getAmount(int wave, int playerCount) { + if (this == OLD) return wave + playerCount; + + double pc = (double) playerCount; + double w = (double) wave; + + double base = Math.min(Math.ceil(pc/2) + 1, 13); + return (int) ( base * Math.pow(w, exp) ); + } +} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/waves/enums/WaveType.java b/src/com/garbagemule/MobArena/waves/enums/WaveType.java new file mode 100644 index 0000000..238b815 --- /dev/null +++ b/src/com/garbagemule/MobArena/waves/enums/WaveType.java @@ -0,0 +1,57 @@ +package com.garbagemule.MobArena.waves.enums; + +import com.garbagemule.MobArena.Messenger; +import com.garbagemule.MobArena.Msg; +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.waves.WaveUtils; + +public enum WaveType +{ + DEFAULT { + @Override + public void announce(Arena arena, int wave) { + Messenger.tellAll(arena, Msg.WAVE_DEFAULT, ""+wave); + } + }, + + SPECIAL { + @Override + public void announce(Arena arena, int wave) { + Messenger.tellAll(arena, Msg.WAVE_SPECIAL, ""+wave); + } + }, + + SWARM { + @Override + public void announce(Arena arena, int wave) { + Messenger.tellAll(arena, Msg.WAVE_SWARM, ""+wave); + } + }, + + SUPPLY { + @Override + public void announce(Arena arena, int wave) { + Messenger.tellAll(arena, Msg.WAVE_SUPPLY, ""+wave); + } + }, + + BOSS { + @Override + public void announce(Arena arena, int wave) { + Messenger.tellAll(arena, Msg.WAVE_BOSS, ""+wave); + } + }, + + UPGRADE { + @Override + public void announce(Arena arena, int wave) { + Messenger.tellAll(arena, Msg.WAVE_UPGRADE, ""+wave); + } + }; + + public abstract void announce(Arena arena, int wave); + + public static WaveType fromString(String string) { + return WaveUtils.getEnumFromString(WaveType.class, string); + } +} \ No newline at end of file diff --git a/src/com/garbagemule/MobArena/waves/types/BossWave.java b/src/com/garbagemule/MobArena/waves/types/BossWave.java new file mode 100644 index 0000000..39ad13e --- /dev/null +++ b/src/com/garbagemule/MobArena/waves/types/BossWave.java @@ -0,0 +1,97 @@ +package com.garbagemule.MobArena.waves.types; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.waves.AbstractWave; +import com.garbagemule.MobArena.waves.BossAbility; +import com.garbagemule.MobArena.waves.BossAbilityThread; +import com.garbagemule.MobArena.waves.MABoss; +import com.garbagemule.MobArena.waves.MACreature; +import com.garbagemule.MobArena.waves.enums.*; +import com.garbagemule.MobArena.MobArena; + +public class BossWave extends AbstractWave +{ + private MACreature monster; + private Set bosses; + private BossHealth health; + + private List abilities; + private boolean activated; + + private int abilityInterval; + + public BossWave(MACreature monster) { + this.monster = monster; + this.bosses = new HashSet(); + this.abilities = new ArrayList(); + this.activated = false; + this.setType(WaveType.BOSS); + } + + @Override + public Map getMonstersToSpawn(int wave, int playerCount, Arena arena) { + Map result = new HashMap(); + result.put(monster, 1); + return result; + } + + public int getMaxHealth(int playerCount) { + return health.getMax(playerCount); + } + + public void setHealth(BossHealth health) { + this.health = health; + } + + public void addMABoss(MABoss boss) { + bosses.add(boss); + } + + public Set getMABosses() { + Set result = new HashSet(); + for (MABoss b : bosses) { + if (!b.isDead()) { + result.add(b); + } + } + return result; + } + + public void addBossAbility(BossAbility ability) { + abilities.add(ability); + } + + public int getAbilityInterval() { + return abilityInterval; + } + + public void setAbilityInterval(int abilityInterval) { + this.abilityInterval = abilityInterval; + } + + public void activateAbilities(Arena arena) { + if (activated) { + return; + } + + BossAbilityThread bat = new BossAbilityThread(this, abilities, arena); + scheduleTask(arena, bat, 100); + activated = true; + } + + public void scheduleTask(Arena arena, Runnable r, int delay) { + MobArena plugin = arena.getPlugin(); + + plugin.getServer().getScheduler().scheduleSyncDelayedTask( + plugin, + r, + delay); + } +} diff --git a/src/com/garbagemule/MobArena/waves/types/DefaultWave.java b/src/com/garbagemule/MobArena/waves/types/DefaultWave.java new file mode 100644 index 0000000..802f77c --- /dev/null +++ b/src/com/garbagemule/MobArena/waves/types/DefaultWave.java @@ -0,0 +1,61 @@ +package com.garbagemule.MobArena.waves.types; + +import java.util.*; + +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.waves.AbstractWave; +import com.garbagemule.MobArena.waves.MACreature; +import com.garbagemule.MobArena.waves.enums.*; + +public class DefaultWave extends AbstractWave +{ + private SortedMap monsterMap; + private WaveGrowth growth; + + public DefaultWave(SortedMap monsterMap) { + this.monsterMap = monsterMap; + this.growth = WaveGrowth.OLD; + this.setType(WaveType.DEFAULT); + } + + @Override + public Map getMonstersToSpawn(int wave, int playerCount, Arena arena) { + // Get the amount of monsters to spawn. + int toSpawn = (int) Math.max(1D, growth.getAmount(wave, playerCount) * super.getAmountMultiplier()); + + // Grab the total probability sum. + int total = monsterMap.lastKey(); + + // Random number generator. + Random random = new Random(); + + // Prepare the monster map. + Map monsters = new HashMap(); + + // Generate some random amounts. + for (int i = 0; i < toSpawn; i++) { + int value = random.nextInt(total) + 1; + + for (Map.Entry entry : monsterMap.entrySet()) { + if (value > entry.getKey()) { + continue; + } + + Integer current = monsters.get(entry.getValue()); + monsters.put(entry.getValue(), (current == null ? 1 : current + 1)); + break; + } + } + //TODO: Remember amount-multiplier. + // Return the map. + return monsters; + } + + public WaveGrowth getGrowth() { + return growth; + } + + public void setGrowth(WaveGrowth growth) { + this.growth = growth; + } +} diff --git a/src/com/garbagemule/MobArena/waves/types/SpecialWave.java b/src/com/garbagemule/MobArena/waves/types/SpecialWave.java new file mode 100644 index 0000000..052b2bb --- /dev/null +++ b/src/com/garbagemule/MobArena/waves/types/SpecialWave.java @@ -0,0 +1,51 @@ +package com.garbagemule.MobArena.waves.types; + +import java.util.*; + +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.waves.AbstractWave; +import com.garbagemule.MobArena.waves.MACreature; +import com.garbagemule.MobArena.waves.enums.WaveType; + +public class SpecialWave extends AbstractWave +{ + private SortedMap monsterMap; + + public SpecialWave(SortedMap monsterMap) { + this.monsterMap = monsterMap; + this.setType(WaveType.SPECIAL); + } + + @Override + public Map getMonstersToSpawn(int wave, int playerCount, Arena arena) { + // Random number. + Random random = new Random(); + int value = random.nextInt(monsterMap.lastKey()); + + // Prepare the monster map. + Map result = new HashMap(); + + for (Map.Entry entry : monsterMap.entrySet()) { + if (value > entry.getKey()) { + continue; + } + + int amount; + switch (entry.getValue()) { + case POWEREDCREEPERS: + case ZOMBIEPIGMEN: + case ANGRYWOLVES: amount = playerCount * 2; break; + case SLIMES: amount = playerCount * 4; break; + case GIANTS: + case GHASTS: amount = 2; + default: amount = playerCount + 1; break; + } + + amount = (int) Math.max(1D, amount * super.getAmountMultiplier()); + result.put(entry.getValue(), amount); + break; + } + + return result; + } +} diff --git a/src/com/garbagemule/MobArena/waves/types/SupplyWave.java b/src/com/garbagemule/MobArena/waves/types/SupplyWave.java new file mode 100644 index 0000000..fef917e --- /dev/null +++ b/src/com/garbagemule/MobArena/waves/types/SupplyWave.java @@ -0,0 +1,61 @@ +package com.garbagemule.MobArena.waves.types; + +import java.util.*; + +import org.bukkit.inventory.ItemStack; + +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.waves.AbstractWave; +import com.garbagemule.MobArena.waves.MACreature; +import com.garbagemule.MobArena.waves.enums.WaveType; + +public class SupplyWave extends AbstractWave +{ + private SortedMap monsterMap; + private List drops; + + public SupplyWave(SortedMap monsterMap) { + this.monsterMap = monsterMap; + this.setType(WaveType.SUPPLY); + } + + @Override + public Map getMonstersToSpawn(int wave, int playerCount, Arena arena) { + // Grab the total probability sum. + int total = monsterMap.lastKey(); + + // Random number generator. + Random random = new Random(); + + // Prepare the monster map. + Map monsters = new HashMap(); + + int toSpawn = (int) Math.max(1D, playerCount * super.getAmountMultiplier()); + + // Spawn a monster for each player. + for (int i = 0; i < toSpawn; i++) { + int value = random.nextInt(total) + 1; + + for (Map.Entry entry : monsterMap.entrySet()) { + if (value > entry.getKey()) { + continue; + } + + Integer current = monsters.get(entry.getValue()); + monsters.put(entry.getValue(), (current == null ? 1 : current + 1)); + break; + } + } + + // Return the map. + return monsters; + } + + public List getDropList() { + return drops; + } + + public void setDropList(List drops) { + this.drops = drops; + } +} diff --git a/src/com/garbagemule/MobArena/waves/types/SwarmWave.java b/src/com/garbagemule/MobArena/waves/types/SwarmWave.java new file mode 100644 index 0000000..547a312 --- /dev/null +++ b/src/com/garbagemule/MobArena/waves/types/SwarmWave.java @@ -0,0 +1,40 @@ +package com.garbagemule.MobArena.waves.types; + +import java.util.*; + +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.waves.AbstractWave; +import com.garbagemule.MobArena.waves.MACreature; +import com.garbagemule.MobArena.waves.enums.*; + +public class SwarmWave extends AbstractWave +{ + private MACreature monster; + private SwarmAmount amount; + + public SwarmWave(MACreature monster) { + this.monster = monster; + this.amount = SwarmAmount.LOW; + this.setType(WaveType.SWARM); + } + + @Override + public Map getMonstersToSpawn(int wave, int playerCount, Arena arena) { + // Prepare the monster map. + Map result = new HashMap(); + + // Add the monster and the swarm amount. + int toSpawn = (int) Math.max(1D, amount.getAmount(playerCount) * super.getAmountMultiplier()); + result.put(monster, toSpawn); + + return result; + } + + public SwarmAmount getAmount() { + return amount; + } + + public void setAmount(SwarmAmount amount) { + this.amount = amount; + } +} diff --git a/src/com/garbagemule/MobArena/waves/types/UpgradeWave.java b/src/com/garbagemule/MobArena/waves/types/UpgradeWave.java new file mode 100644 index 0000000..eee631a --- /dev/null +++ b/src/com/garbagemule/MobArena/waves/types/UpgradeWave.java @@ -0,0 +1,51 @@ +package com.garbagemule.MobArena.waves.types; + +import java.util.*; + +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; + +import com.garbagemule.MobArena.framework.Arena; +import com.garbagemule.MobArena.waves.AbstractWave; +import com.garbagemule.MobArena.waves.MACreature; +import com.garbagemule.MobArena.waves.enums.WaveType; + +public class UpgradeWave extends AbstractWave +{ + private Map> classMap; + private boolean giveAll; + + public UpgradeWave(Map> classMap) { + this.classMap = classMap; + this.setType(WaveType.UPGRADE); + } + + @Override + public Map getMonstersToSpawn(int wave, int playerCount, Arena arena) { + return new HashMap(); + } + + public void grantItems(Player p, String className) { + List stacks = classMap.get(className.toLowerCase()); + if (stacks == null || stacks.isEmpty()) return; + + PlayerInventory inv = p.getInventory(); + + // Check if we need to add all of the items or just one. + if (giveAll) { + for (ItemStack stack : stacks) { + inv.addItem(stack); + } + } + // Get a random item from the list. + else { + int index = new Random().nextInt(stacks.size()); + inv.addItem(stacks.get(index)); + } + } + + public void setGiveAll(boolean giveAll) { + this.giveAll = giveAll; + } +} diff --git a/src/com/garbagemule/register/payment/Method.java b/src/com/garbagemule/register/payment/Method.java deleted file mode 100644 index b4c4ff4..0000000 --- a/src/com/garbagemule/register/payment/Method.java +++ /dev/null @@ -1,183 +0,0 @@ -package com.garbagemule.register.payment; - -import org.bukkit.plugin.Plugin; - -/** - * Interface to be implemented by a payment method. - * - * @author Nijikokun (@nijikokun) - * @copyright Copyright (C) 2011 - * @license AOL license - */ -public interface Method { - /** - * Encodes the Plugin into an Object disguised as the Plugin. - * If you want the original Plugin Class you must cast it to the correct - * Plugin, to do so you have to verify the name and or version then cast. - * - *
-     *  if(method.getName().equalsIgnoreCase("iConomy"))
-     *   iConomy plugin = ((iConomy)method.getPlugin());
- * - * @return Object - * @see #getName() - * @see #getVersion() - */ - public Object getPlugin(); - - /** - * Returns the actual name of this method. - * - * @return String Plugin name. - */ - public String getName(); - - /** - * Returns the actual version of this method. - * - * @return String Plugin version. - */ - public String getVersion(); - - /** - * Returns the amount of decimal places that get stored - * NOTE: it will return -1 if there is no rounding - * - * @return int for each decimal place - */ - public int fractionalDigits(); - - /** - * Formats amounts into this payment methods style of currency display. - * - * @param amount Double - * @return String - Formatted Currency Display. - */ - public String format(double amount); - - /** - * Allows the verification of bank API existence in this payment method. - * - * @return boolean - */ - public boolean hasBanks(); - - /** - * Determines the existence of a bank via name. - * - * @param bank Bank name - * @return boolean - * @see #hasBanks - */ - public boolean hasBank(String bank); - - /** - * Determines the existence of an account via name. - * - * @param name Account name - * @return boolean - */ - public boolean hasAccount(String name); - - /** - * Check to see if an account name is tied to a bank. - * - * @param bank Bank name - * @param name Account name - * @return boolean - */ - public boolean hasBankAccount(String bank, String name); - - /** - * Forces an account creation - * - * @param name Account name - * @return boolean - */ - public boolean createAccount(String name); - - /** - * Forces an account creation - * - * @param name Account name - * @param balance Initial account balance - * @return boolean - */ - public boolean createAccount(String name, Double balance); - - /** - * Returns a MethodAccount class for an account name. - * - * @param name Account name - * @return MethodAccount or Null - */ - public MethodAccount getAccount(String name); - - - /** - * Returns a MethodBankAccount class for an account name. - * - * @param bank Bank name - * @param name Account name - * @return MethodBankAccount or Null - */ - public MethodBankAccount getBankAccount(String bank, String name); - - /** - * Checks to verify the compatibility between this Method and a plugin. - * Internal usage only, for the most part. - * - * @param plugin Plugin - * @return boolean - */ - public boolean isCompatible(Plugin plugin); - - /** - * Set Plugin data. - * - * @param plugin Plugin - */ - public void setPlugin(Plugin plugin); - - /** - * Contains Calculator and Balance functions for Accounts. - */ - public interface MethodAccount { - public double balance(); - public boolean set(double amount); - public boolean add(double amount); - public boolean subtract(double amount); - public boolean multiply(double amount); - public boolean divide(double amount); - public boolean hasEnough(double amount); - public boolean hasOver(double amount); - public boolean hasUnder(double amount); - public boolean isNegative(); - public boolean remove(); - - @Override - public String toString(); - } - - /** - * Contains Calculator and Balance functions for Bank Accounts. - */ - public interface MethodBankAccount { - public double balance(); - public String getBankName(); - public int getBankId(); - public boolean set(double amount); - public boolean add(double amount); - public boolean subtract(double amount); - public boolean multiply(double amount); - public boolean divide(double amount); - public boolean hasEnough(double amount); - public boolean hasOver(double amount); - public boolean hasUnder(double amount); - public boolean isNegative(); - public boolean remove(); - - @Override - public String toString(); - } -} diff --git a/src/com/garbagemule/register/payment/Methods.java b/src/com/garbagemule/register/payment/Methods.java deleted file mode 100644 index 41920a8..0000000 --- a/src/com/garbagemule/register/payment/Methods.java +++ /dev/null @@ -1,236 +0,0 @@ -package com.garbagemule.register.payment; - -import java.util.HashSet; -import java.util.Set; - -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.PluginManager; - -/** - * The Methods initializes Methods that utilize the Method interface - * based on a "first come, first served" basis. - * - * Allowing you to check whether a payment method exists or not. - * - * Methods also allows you to set a preferred method of payment before it captures - * payment plugins in the initialization process. - * - * in bukkit.yml: - *
- *  economy:
- *      preferred: "iConomy"
- * 
- * - * @author: Nijikokun (@nijikokun) - * @copyright: Copyright (C) 2011 - * @license: AOL license - */ -public class Methods { - private static String version = null; - private static boolean self = false; - private static Method Method = null; - private static String preferred = ""; - private static Set Methods = new HashSet(); - private static Set Dependencies = new HashSet(); - private static Set Attachables = new HashSet(); - - static { - _init(); - } - - /** - * Implement all methods along with their respective name & class. - */ - private static void _init() { - addMethod("iConomy", new com.garbagemule.register.payment.methods.iCo6()); - addMethod("iConomy", new com.garbagemule.register.payment.methods.iCo5()); - addMethod("iConomy", new com.garbagemule.register.payment.methods.iCo4()); - addMethod("BOSEconomy", new com.garbagemule.register.payment.methods.BOSE6()); - addMethod("BOSEconomy", new com.garbagemule.register.payment.methods.BOSE7()); - addMethod("Essentials", new com.garbagemule.register.payment.methods.EE17()); - addMethod("Currency", new com.garbagemule.register.payment.methods.MCUR()); - Dependencies.add("MultiCurrency"); - } - - /** - * Used by the plugin to setup version - * - * @param v version - */ - public static void setVersion(String v) { - version = v; - } - - /** - * Use to reset methods during disable - */ - public static void reset() { - version = null; - self = false; - Method = null; - preferred = ""; - Attachables.clear(); - } - - /** - * Use to get version of Register plugin - * @return version - */ - public static String getVersion() { - return version; - } - - /** - * Returns an array of payment method names that have been loaded - * through the _init method. - * - * @return Set - Array of payment methods that are loaded. - * @see #setMethod(org.bukkit.plugin.Plugin) - */ - public static Set getDependencies() { - return Dependencies; - } - - /** - * Interprets Plugin class data to verify whether it is compatible with an existing payment - * method to use for payments and other various economic activity. - * - * @param plugin Plugin data from bukkit, Internal Class file. - * @return Method or Null - */ - public static Method createMethod(Plugin plugin) { - for (Method method: Methods) - if (method.isCompatible(plugin)) { - method.setPlugin(plugin); - return method; - } - - return null; - } - - private static void addMethod(String name, Method method) { - Dependencies.add(name); - Methods.add(method); - } - - /** - * Verifies if Register has set a payment method for usage yet. - * - * @return boolean - * @see #setMethod(org.bukkit.plugin.Plugin) - * @see #checkDisabled(org.bukkit.plugin.Plugin) - */ - public static boolean hasMethod() { - return (Method != null); - } - - /** - * Checks Plugin Class against a multitude of checks to verify it's usability - * as a payment method. - * - * @param PluginManager the plugin manager for the server - * @return boolean True on success, False on failure. - */ - public static boolean setMethod(PluginManager manager) { - if (hasMethod()) - return true; - - if (self) { - self = false; - return false; - } - - int count = 0; - boolean match = false; - Plugin plugin = null; - - for (String name : getDependencies()) { - if (hasMethod()) - break; - - plugin = manager.getPlugin(name); - if (plugin == null || !plugin.isEnabled()) - continue; - - Method current = createMethod(plugin); - if (current == null) - continue; - - if (preferred.isEmpty()) - Method = current; - else - Attachables.add(current); - } - - if (!preferred.isEmpty()) { - do { - if (hasMethod()) - match = true; - else { - for (Method attached : Attachables) { - if (attached == null) - continue; - - if (hasMethod()) { - match = true; break; - } - - if (preferred.isEmpty()) - Method = attached; - - if (count == 0) - if (preferred.equalsIgnoreCase(attached.getName())) - Method = attached; - - else - Method = attached; - } - - count++; - } - } while (!match); - } - - return hasMethod(); - } - - /** - * Sets the preferred economy - * - * @return boolean - */ - public static boolean setPreferred(String check) { - if (getDependencies().contains(check)) { - preferred = check; - return true; - } - - return false; - } - - /** - * Grab the existing and initialized (hopefully) Method Class. - * - * @return Method or Null - */ - public static Method getMethod() { - return Method; - } - - /** - * Verify is a plugin is disabled, only does this if we there is an existing payment - * method initialized in Register. - * - * @param method Plugin data from bukkit, Internal Class file. - * @return boolean - */ - public static boolean checkDisabled(Plugin method) { - if(!hasMethod()) - return true; - - if (Method.isCompatible(method)) - Method = null; - - return (Method == null); - } -} diff --git a/src/com/garbagemule/register/payment/methods/BOSE6.java b/src/com/garbagemule/register/payment/methods/BOSE6.java deleted file mode 100644 index b3e1cbf..0000000 --- a/src/com/garbagemule/register/payment/methods/BOSE6.java +++ /dev/null @@ -1,234 +0,0 @@ -package com.garbagemule.register.payment.methods; - -import com.garbagemule.register.payment.Method; - -import cosine.boseconomy.BOSEconomy; -import org.bukkit.plugin.Plugin; - -/** - * BOSEconomy 6 Implementation of Method - * - * @author Nijikokun (@nijikokun) - * @copyright (c) 2011 - * @license AOL license - */ -@SuppressWarnings("deprecation") -public class BOSE6 implements Method { - private BOSEconomy BOSEconomy; - - public BOSEconomy getPlugin() { - return this.BOSEconomy; - } - - public String getName() { - return "BOSEconomy"; - } - - public String getVersion() { - return "0.6.2"; - } - - public int fractionalDigits() { - return 0; - } - - public String format(double amount) { - String currency = this.BOSEconomy.getMoneyNamePlural(); - - if(amount == 1) - currency = this.BOSEconomy.getMoneyName(); - - return amount + " " + currency; - } - - public boolean hasBanks() { - return true; - } - - public boolean hasBank(String bank) { - return this.BOSEconomy.bankExists(bank); - } - - public boolean hasAccount(String name) { - return this.BOSEconomy.playerRegistered(name, false); - } - - public boolean hasBankAccount(String bank, String name) { - return this.BOSEconomy.isBankOwner(bank, name) - || this.BOSEconomy.isBankMember(bank, name); - } - - public boolean createAccount(String name) { - if(hasAccount(name)) - return false; - - this.BOSEconomy.registerPlayer(name); - return true; - } - - public boolean createAccount(String name, Double balance) { - if(hasAccount(name)) - return false; - - this.BOSEconomy.registerPlayer(name); - this.BOSEconomy.setPlayerMoney(name, balance, false); - return true; - } - - public MethodAccount getAccount(String name) { - if(!hasAccount(name)) - return null; - - return new BOSEAccount(name, this.BOSEconomy); - } - - public MethodBankAccount getBankAccount(String bank, String name) { - if(!hasBankAccount(bank, name)) - return null; - - return new BOSEBankAccount(bank, BOSEconomy); - } - - public boolean isCompatible(Plugin plugin) { - return plugin.getDescription().getName().equalsIgnoreCase("boseconomy") - && plugin instanceof BOSEconomy - && plugin.getDescription().getVersion().equals("0.6.2"); - } - - public void setPlugin(Plugin plugin) { - BOSEconomy = (BOSEconomy) plugin; - } - - public class BOSEAccount implements MethodAccount { - private final String name; - private final BOSEconomy BOSEconomy; - - public BOSEAccount(String name, BOSEconomy bOSEconomy) { - this.name = name; - this.BOSEconomy = bOSEconomy; - } - - public double balance() { - return (double) this.BOSEconomy.getPlayerMoney(this.name); - } - - public boolean set(double amount) { - int IntAmount = (int)Math.ceil(amount); - return this.BOSEconomy.setPlayerMoney(this.name, IntAmount, false); - } - - public boolean add(double amount) { - int IntAmount = (int)Math.ceil(amount); - return this.BOSEconomy.addPlayerMoney(this.name, IntAmount, false); - } - - public boolean subtract(double amount) { - int IntAmount = (int)Math.ceil(amount); - int balance = (int)this.balance(); - return this.BOSEconomy.setPlayerMoney(this.name, (balance - IntAmount), false); - } - - public boolean multiply(double amount) { - int IntAmount = (int)Math.ceil(amount); - int balance = (int)this.balance(); - return this.BOSEconomy.setPlayerMoney(this.name, (balance * IntAmount), false); - } - - public boolean divide(double amount) { - int IntAmount = (int)Math.ceil(amount); - int balance = (int)this.balance(); - return this.BOSEconomy.setPlayerMoney(this.name, (balance / IntAmount), false); - } - - public boolean hasEnough(double amount) { - return (this.balance() >= amount); - } - - public boolean hasOver(double amount) { - return (this.balance() > amount); - } - - public boolean hasUnder(double amount) { - return (this.balance() < amount); - } - - public boolean isNegative() { - return (this.balance() < 0); - } - - public boolean remove() { - return false; - } - } - - public class BOSEBankAccount implements MethodBankAccount { - private final String bank; - private final BOSEconomy BOSEconomy; - - public BOSEBankAccount(String bank, BOSEconomy bOSEconomy) { - this.bank = bank; - this.BOSEconomy = bOSEconomy; - } - - public String getBankName() { - return this.bank; - } - - public int getBankId() { - return -1; - } - - public double balance() { - return (double) this.BOSEconomy.getBankMoney(bank); - } - - public boolean set(double amount) { - int IntAmount = (int)Math.ceil(amount); - return this.BOSEconomy.setBankMoney(bank, IntAmount, true); - } - - public boolean add(double amount) { - int IntAmount = (int)Math.ceil(amount); - int balance = (int)this.balance(); - return this.BOSEconomy.setBankMoney(bank, (balance + IntAmount), false); - } - - public boolean subtract(double amount) { - int IntAmount = (int)Math.ceil(amount); - int balance = (int)this.balance(); - return this.BOSEconomy.setBankMoney(bank, (balance - IntAmount), false); - } - - public boolean multiply(double amount) { - int IntAmount = (int)Math.ceil(amount); - int balance = (int)this.balance(); - return this.BOSEconomy.setBankMoney(bank, (balance * IntAmount), false); - } - - public boolean divide(double amount) { - int IntAmount = (int)Math.ceil(amount); - int balance = (int)this.balance(); - return this.BOSEconomy.setBankMoney(bank, (balance / IntAmount), false); - } - - public boolean hasEnough(double amount) { - return (this.balance() >= amount); - } - - public boolean hasOver(double amount) { - return (this.balance() > amount); - } - - public boolean hasUnder(double amount) { - return (this.balance() < amount); - } - - public boolean isNegative() { - return (this.balance() < 0); - } - - public boolean remove() { - return this.BOSEconomy.removeBank(bank); - } - } -} \ No newline at end of file diff --git a/src/com/garbagemule/register/payment/methods/BOSE7.java b/src/com/garbagemule/register/payment/methods/BOSE7.java deleted file mode 100644 index 376eaff..0000000 --- a/src/com/garbagemule/register/payment/methods/BOSE7.java +++ /dev/null @@ -1,223 +0,0 @@ -package com.garbagemule.register.payment.methods; - -import com.garbagemule.register.payment.Method; - -import cosine.boseconomy.BOSEconomy; -import org.bukkit.plugin.Plugin; - -/** - * BOSEconomy 7 Implementation of Method - * - * @author Acrobot - * @author Nijikokun (@nijikokun) - * @copyright (c) 2011 - * @license AOL license - */ -public class BOSE7 implements Method { - private BOSEconomy BOSEconomy; - - public BOSEconomy getPlugin() { - return this.BOSEconomy; - } - - public String getName() { - return "BOSEconomy"; - } - - public String getVersion() { - return "0.7.0"; - } - - public int fractionalDigits() { - return this.BOSEconomy.getFractionalDigits(); - } - - public String format(double amount) { - String currency = this.BOSEconomy.getMoneyNamePlural(); - - if(amount == 1) - currency = this.BOSEconomy.getMoneyName(); - - return amount + " " + currency; - } - - public boolean hasBanks() { - return true; - } - - public boolean hasBank(String bank) { - return this.BOSEconomy.bankExists(bank); - } - - public boolean hasAccount(String name) { - return this.BOSEconomy.playerRegistered(name, false); - } - - public boolean hasBankAccount(String bank, String name) { - return this.BOSEconomy.isBankOwner(bank, name) || this.BOSEconomy.isBankMember(bank, name); - } - - public boolean createAccount(String name) { - if(hasAccount(name)) - return false; - - this.BOSEconomy.registerPlayer(name); - return true; - } - - public boolean createAccount(String name, Double balance) { - if(hasAccount(name)) - return false; - - this.BOSEconomy.registerPlayer(name); - this.BOSEconomy.setPlayerMoney(name, balance, false); - return true; - } - - public MethodAccount getAccount(String name) { - if(!hasAccount(name)) - return null; - - return new BOSEAccount(name, this.BOSEconomy); - } - - public MethodBankAccount getBankAccount(String bank, String name) { - if(!hasBankAccount(bank, name)) - return null; - - return new BOSEBankAccount(bank, BOSEconomy); - } - - public boolean isCompatible(Plugin plugin) { - return plugin.getDescription().getName().equalsIgnoreCase("boseconomy") - && plugin instanceof BOSEconomy - && !plugin.getDescription().getVersion().equals("0.6.2"); - } - - public void setPlugin(Plugin plugin) { - BOSEconomy = (BOSEconomy)plugin; - } - - public class BOSEAccount implements MethodAccount { - private String name; - private BOSEconomy BOSEconomy; - - public BOSEAccount(String name, BOSEconomy bOSEconomy) { - this.name = name; - this.BOSEconomy = bOSEconomy; - } - - public double balance() { - return this.BOSEconomy.getPlayerMoneyDouble(this.name); - } - - public boolean set(double amount) { - return this.BOSEconomy.setPlayerMoney(this.name, amount, false); - } - - public boolean add(double amount) { - return this.BOSEconomy.addPlayerMoney(this.name, amount, false); - } - - public boolean subtract(double amount) { - double balance = this.balance(); - return this.BOSEconomy.setPlayerMoney(this.name, (balance - amount), false); - } - - public boolean multiply(double amount) { - double balance = this.balance(); - return this.BOSEconomy.setPlayerMoney(this.name, (balance * amount), false); - } - - public boolean divide(double amount) { - double balance = this.balance(); - return this.BOSEconomy.setPlayerMoney(this.name, (balance / amount), false); - } - - public boolean hasEnough(double amount) { - return (this.balance() >= amount); - } - - public boolean hasOver(double amount) { - return (this.balance() > amount); - } - - public boolean hasUnder(double amount) { - return (this.balance() < amount); - } - - public boolean isNegative() { - return (this.balance() < 0); - } - - public boolean remove() { - return false; - } - } - - public class BOSEBankAccount implements MethodBankAccount { - private String bank; - private BOSEconomy BOSEconomy; - - public BOSEBankAccount(String bank, BOSEconomy bOSEconomy) { - this.bank = bank; - this.BOSEconomy = bOSEconomy; - } - - public String getBankName() { - return this.bank; - } - - public int getBankId() { - return -1; - } - - public double balance() { - return this.BOSEconomy.getBankMoneyDouble(bank); - } - - public boolean set(double amount) { - return this.BOSEconomy.setBankMoney(bank, amount, true); - } - - public boolean add(double amount) { - double balance = this.balance(); - return this.BOSEconomy.setBankMoney(bank, (balance + amount), false); - } - - public boolean subtract(double amount) { - double balance = this.balance(); - return this.BOSEconomy.setBankMoney(bank, (balance - amount), false); - } - - public boolean multiply(double amount) { - double balance = this.balance(); - return this.BOSEconomy.setBankMoney(bank, (balance * amount), false); - } - - public boolean divide(double amount) { - double balance = this.balance(); - return this.BOSEconomy.setBankMoney(bank, (balance / amount), false); - } - - public boolean hasEnough(double amount) { - return (this.balance() >= amount); - } - - public boolean hasOver(double amount) { - return (this.balance() > amount); - } - - public boolean hasUnder(double amount) { - return (this.balance() < amount); - } - - public boolean isNegative() { - return (this.balance() < 0); - } - - public boolean remove() { - return this.BOSEconomy.removeBank(bank); - } - } -} \ No newline at end of file diff --git a/src/com/garbagemule/register/payment/methods/EE17.java b/src/com/garbagemule/register/payment/methods/EE17.java deleted file mode 100644 index ed282e8..0000000 --- a/src/com/garbagemule/register/payment/methods/EE17.java +++ /dev/null @@ -1,223 +0,0 @@ -package com.garbagemule.register.payment.methods; - -import com.garbagemule.register.payment.Method; -import com.earth2me.essentials.Essentials; -import com.earth2me.essentials.api.Economy; - -import org.bukkit.plugin.Plugin; - -/** - * Essentials 17 Implementation of Method - * - * @author Nijikokun (@nijikokun) - * @author Snowleo - * @author Acrobot - * @author KHobbits - * @copyright (c) 2011 - * @license AOL license - */ -public class EE17 implements Method { - private Essentials Essentials; - - public Essentials getPlugin() { - return this.Essentials; - } - - public String getName() { - return "Essentials"; - } - - public String getVersion() { - return "2.2"; - } - - public int fractionalDigits() { - return -1; - } - - public String format(double amount) { - return Economy.format(amount); - } - - public boolean hasBanks() { - return false; - } - - public boolean hasBank(String bank) { - return false; - } - - public boolean hasAccount(String name) { - return Economy.playerExists(name); - } - - public boolean hasBankAccount(String bank, String name) { - return false; - } - - public boolean createAccount(String name) { - if(hasAccount(name)) - return false; - - Economy.createNPC(name); - return true; - } - - public boolean createAccount(String name, Double balance) { - if(hasAccount(name)) - return false; - - Economy.createNPC(name); - - try { - Economy.setMoney(name, balance); - } catch (Exception ex) { - System.out.println("[REGISTER] Error in Essentials Economy: " + ex.getMessage()); - return false; - } - - return true; - } - - public MethodAccount getAccount(String name) { - if(!hasAccount(name)) - return null; - - return new EEcoAccount(name); - } - - public MethodBankAccount getBankAccount(String bank, String name) { - return null; - } - - public boolean isCompatible(Plugin plugin) { - try { Class.forName("com.earth2me.essentials.api.Economy"); } - catch(Exception e) { return false; } - - return plugin.getDescription().getName().equalsIgnoreCase("essentials") - && plugin instanceof Essentials; - } - - public void setPlugin(Plugin plugin) { - Essentials = (Essentials)plugin; - } - - public class EEcoAccount implements MethodAccount { - private String name; - - public EEcoAccount(String name) { - this.name = name; - } - - public double balance() { - Double balance = 0.0; - - try { - balance = Economy.getMoney(this.name); - } catch (Exception ex) { - System.out.println("[REGISTER] Error in Essentials Economy: " + ex.getMessage()); - } - - return balance; - } - - public boolean set(double amount) { - try { - Economy.setMoney(name, amount); - } catch (Exception ex) { - System.out.println("[REGISTER] Error in Essentials Economy: " + ex.getMessage()); - return false; - } - - return true; - } - - public boolean add(double amount) { - try { - Economy.add(name, amount); - } catch (Exception ex) { - System.out.println("[REGISTER] Error in Essentials Economy: " + ex.getMessage()); - return false; - } - - return true; - } - - public boolean subtract(double amount) { - try { - Economy.subtract(name, amount); - } catch (Exception ex) { - System.out.println("[REGISTER] Error in Essentials Economy: " + ex.getMessage()); - return false; - } - - return true; - } - - public boolean multiply(double amount) { - try { - Economy.multiply(name, amount); - } catch (Exception ex) { - System.out.println("[REGISTER] Error in Essentials Economy: " + ex.getMessage()); - return false; - } - - return true; - } - - public boolean divide(double amount) { - try { - Economy.divide(name, amount); - } catch (Exception ex) { - System.out.println("[REGISTER] Error in Essentials Economy: " + ex.getMessage()); - return false; - } - - return true; - } - - public boolean hasEnough(double amount) { - try { - return Economy.hasEnough(name, amount); - } catch (Exception ex) { - System.out.println("[REGISTER] Error in Essentials Economy: " + ex.getMessage()); - } - - return false; - } - - public boolean hasOver(double amount) { - try { - return Economy.hasMore(name, amount); - } catch (Exception ex) { - System.out.println("[REGISTER] Error in Essentials Economy: " + ex.getMessage()); - } - - return false; - } - - public boolean hasUnder(double amount) { - try { - return Economy.hasLess(name, amount); - } catch (Exception ex) { - System.out.println("[REGISTER] Error in Essentials Economy: " + ex.getMessage()); - } - - return false; - } - - public boolean isNegative() { - try { - return Economy.isNegative(name); - } catch (Exception ex) { - System.out.println("[REGISTER] Error in Essentials Economy: " + ex.getMessage()); - } - - return false; - } - - public boolean remove() { - return false; - } - } -} \ No newline at end of file diff --git a/src/com/garbagemule/register/payment/methods/MCUR.java b/src/com/garbagemule/register/payment/methods/MCUR.java deleted file mode 100644 index c6a758c..0000000 --- a/src/com/garbagemule/register/payment/methods/MCUR.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.garbagemule.register.payment.methods; - -import com.garbagemule.register.payment.Method; - -import me.ashtheking.currency.Currency; -import me.ashtheking.currency.CurrencyList; - -import org.bukkit.plugin.Plugin; - -/** - * MultiCurrency Method implementation. - * - * @author Acrobot - * @copyright (c) 2011 - * @license AOL license - */ -public class MCUR implements Method { - private Currency currencyList; - - public Object getPlugin() { - return this.currencyList; - } - - public String getName() { - return "MultiCurrency"; - } - - public String getVersion() { - return "0.09"; - } - - public int fractionalDigits() { - return -1; - } - - public String format(double amount) { - return amount + " Currency"; - } - - public boolean hasBanks() { - return false; - } - - public boolean hasBank(String bank) { - return false; - } - - public boolean hasAccount(String name) { - return true; - } - - public boolean hasBankAccount(String bank, String name) { - return false; - } - - public boolean createAccount(String name) { - CurrencyList.setValue((String) CurrencyList.maxCurrency(name)[0], name, 0); - return true; - } - - public boolean createAccount(String name, Double balance) { - CurrencyList.setValue((String) CurrencyList.maxCurrency(name)[0], name, balance); - return true; - } - - public MethodAccount getAccount(String name) { - return new MCurrencyAccount(name); - } - - public MethodBankAccount getBankAccount(String bank, String name) { - return null; - } - - public boolean isCompatible(Plugin plugin) { - return (plugin.getDescription().getName().equalsIgnoreCase("Currency") - || plugin.getDescription().getName().equalsIgnoreCase("MultiCurrency")) - && plugin instanceof Currency; - } - - public void setPlugin(Plugin plugin) { - currencyList = (Currency) plugin; - } - - public class MCurrencyAccount implements MethodAccount{ - private String name; - - public MCurrencyAccount(String name) { - this.name = name; - } - - public double balance() { - return CurrencyList.getValue((String) CurrencyList.maxCurrency(name)[0], name); - } - - public boolean set(double amount) { - CurrencyList.setValue((String) CurrencyList.maxCurrency(name)[0], name, amount); - return true; - } - - public boolean add(double amount) { - return CurrencyList.add(name, amount); - } - - public boolean subtract(double amount) { - return CurrencyList.subtract(name, amount); - } - - public boolean multiply(double amount) { - return CurrencyList.multiply(name, amount); - } - - public boolean divide(double amount) { - return CurrencyList.divide(name, amount); - } - - public boolean hasEnough(double amount) { - return CurrencyList.hasEnough(name, amount); - } - - public boolean hasOver(double amount) { - return CurrencyList.hasOver(name, amount); - } - - public boolean hasUnder(double amount) { - return CurrencyList.hasUnder(name, amount); - } - - public boolean isNegative() { - return CurrencyList.isNegative(name); - } - - public boolean remove() { - return CurrencyList.remove(name); - } - } -} diff --git a/src/com/garbagemule/register/payment/methods/iCo4.java b/src/com/garbagemule/register/payment/methods/iCo4.java deleted file mode 100644 index e4a2ede..0000000 --- a/src/com/garbagemule/register/payment/methods/iCo4.java +++ /dev/null @@ -1,167 +0,0 @@ -package com.garbagemule.register.payment.methods; - -import com.garbagemule.register.payment.Method; -import com.nijiko.coelho.iConomy.iConomy; -import com.nijiko.coelho.iConomy.system.Account; - - -import org.bukkit.plugin.Plugin; - -/** - * iConomy 4 Implementation of Method - * - * @author Nijikokun (@nijikokun) - * @copyright (c) 2011 - * @license AOL license - */ -public class iCo4 implements Method { - private iConomy iConomy; - - public iConomy getPlugin() { - return this.iConomy; - } - - public String getName() { - return "iConomy"; - } - - public String getVersion() { - return "4"; - } - - public int fractionalDigits() { - return 2; - } - - public String format(double amount) { - return com.nijiko.coelho.iConomy.iConomy.getBank().format(amount); - } - - public boolean hasBanks() { - return false; - } - - public boolean hasBank(String bank) { - return false; - } - - public boolean hasAccount(String name) { - return com.nijiko.coelho.iConomy.iConomy.getBank().hasAccount(name); - } - - public boolean hasBankAccount(String bank, String name) { - return false; - } - - public boolean createAccount(String name) { - if(hasAccount(name)) - return false; - - try { - com.nijiko.coelho.iConomy.iConomy.getBank().addAccount(name); - } catch(Exception E) { - return false; - } - - return true; - } - - public boolean createAccount(String name, Double balance) { - if(hasAccount(name)) - return false; - - try { - com.nijiko.coelho.iConomy.iConomy.getBank().addAccount(name, balance); - } catch(Exception E) { - return false; - } - - return true; - } - - public MethodAccount getAccount(String name) { - return new iCoAccount(com.nijiko.coelho.iConomy.iConomy.getBank().getAccount(name)); - } - - public MethodBankAccount getBankAccount(String bank, String name) { - return null; - } - - public boolean isCompatible(Plugin plugin) { - return plugin.getDescription().getName().equalsIgnoreCase("iconomy") - && plugin.getClass().getName().equals("com.nijiko.coelho.iConomy.iConomy") - && plugin instanceof iConomy; - } - - public void setPlugin(Plugin plugin) { - iConomy = (iConomy)plugin; - } - - public class iCoAccount implements MethodAccount { - private Account account; - - public iCoAccount(Account account) { - this.account = account; - } - - public Account getiCoAccount() { - return account; - } - - public double balance() { - return this.account.getBalance(); - } - - public boolean set(double amount) { - if(this.account == null) return false; - this.account.setBalance(amount); - return true; - } - - public boolean add(double amount) { - if(this.account == null) return false; - this.account.add(amount); - return true; - } - - public boolean subtract(double amount) { - if(this.account == null) return false; - this.account.subtract(amount); - return true; - } - - public boolean multiply(double amount) { - if(this.account == null) return false; - this.account.multiply(amount); - return true; - } - - public boolean divide(double amount) { - if(this.account == null) return false; - this.account.divide(amount); - return true; - } - - public boolean hasEnough(double amount) { - return this.account.hasEnough(amount); - } - - public boolean hasOver(double amount) { - return this.account.hasOver(amount); - } - - public boolean hasUnder(double amount) { - return (this.balance() < amount); - } - - public boolean isNegative() { - return this.account.isNegative(); - } - - public boolean remove() { - if(this.account == null) return false; - this.account.remove(); - return true; - } - } -} diff --git a/src/com/garbagemule/register/payment/methods/iCo5.java b/src/com/garbagemule/register/payment/methods/iCo5.java deleted file mode 100644 index 77c73bd..0000000 --- a/src/com/garbagemule/register/payment/methods/iCo5.java +++ /dev/null @@ -1,243 +0,0 @@ -package com.garbagemule.register.payment.methods; - -import com.garbagemule.register.payment.Method; -import com.iConomy.iConomy; -import com.iConomy.system.Account; -import com.iConomy.system.BankAccount; -import com.iConomy.system.Holdings; -import com.iConomy.util.Constants; - - -import org.bukkit.plugin.Plugin; - -/** - * iConomy 5 Implementation of Method - * - * @author Nijikokun (@nijikokun) - * @copyright (c) 2011 - * @license AOL license - */ -public class iCo5 implements Method { - private iConomy iConomy; - - public iConomy getPlugin() { - return this.iConomy; - } - - public String getName() { - return "iConomy"; - } - - public String getVersion() { - return "5"; - } - - public int fractionalDigits() { - return 2; - } - - public String format(double amount) { - return com.iConomy.iConomy.format(amount); - } - - public boolean hasBanks() { - return Constants.Banking; - } - - public boolean hasBank(String bank) { - return (hasBanks()) && com.iConomy.iConomy.Banks.exists(bank); - } - - public boolean hasAccount(String name) { - return com.iConomy.iConomy.hasAccount(name); - } - - public boolean hasBankAccount(String bank, String name) { - return (hasBank(bank)) && com.iConomy.iConomy.getBank(bank).hasAccount(name); - } - - public boolean createAccount(String name) { - if(hasAccount(name)) - return false; - - return com.iConomy.iConomy.Accounts.create(name); - } - - public boolean createAccount(String name, Double balance) { - if(hasAccount(name)) - return false; - - if(!com.iConomy.iConomy.Accounts.create(name)) - return false; - - getAccount(name).set(balance); - - return true; - } - - public MethodAccount getAccount(String name) { - return new iCoAccount(com.iConomy.iConomy.getAccount(name)); - } - - public MethodBankAccount getBankAccount(String bank, String name) { - return new iCoBankAccount(com.iConomy.iConomy.getBank(bank).getAccount(name)); - } - - public boolean isCompatible(Plugin plugin) { - return plugin.getDescription().getName().equalsIgnoreCase("iconomy") - && plugin.getClass().getName().equals("com.iConomy.iConomy") - && plugin instanceof iConomy; - } - - public void setPlugin(Plugin plugin) { - iConomy = (iConomy)plugin; - } - - public class iCoAccount implements MethodAccount { - private Account account; - private Holdings holdings; - - public iCoAccount(Account account) { - this.account = account; - this.holdings = account.getHoldings(); - } - - public Account getiCoAccount() { - return account; - } - - public double balance() { - return this.holdings.balance(); - } - - public boolean set(double amount) { - if(this.holdings == null) return false; - this.holdings.set(amount); - return true; - } - - public boolean add(double amount) { - if(this.holdings == null) return false; - this.holdings.add(amount); - return true; - } - - public boolean subtract(double amount) { - if(this.holdings == null) return false; - this.holdings.subtract(amount); - return true; - } - - public boolean multiply(double amount) { - if(this.holdings == null) return false; - this.holdings.multiply(amount); - return true; - } - - public boolean divide(double amount) { - if(this.holdings == null) return false; - this.holdings.divide(amount); - return true; - } - - public boolean hasEnough(double amount) { - return this.holdings.hasEnough(amount); - } - - public boolean hasOver(double amount) { - return this.holdings.hasOver(amount); - } - - public boolean hasUnder(double amount) { - return this.holdings.hasUnder(amount); - } - - public boolean isNegative() { - return this.holdings.isNegative(); - } - - public boolean remove() { - if(this.account == null) return false; - this.account.remove(); - return true; - } - } - - public class iCoBankAccount implements MethodBankAccount { - private BankAccount account; - private Holdings holdings; - - public iCoBankAccount(BankAccount account) { - this.account = account; - this.holdings = account.getHoldings(); - } - - public BankAccount getiCoBankAccount() { - return account; - } - - public String getBankName() { - return this.account.getBankName(); - } - - public int getBankId() { - return this.account.getBankId(); - } - - public double balance() { - return this.holdings.balance(); - } - - public boolean set(double amount) { - if(this.holdings == null) return false; - this.holdings.set(amount); - return true; - } - - public boolean add(double amount) { - if(this.holdings == null) return false; - this.holdings.add(amount); - return true; - } - - public boolean subtract(double amount) { - if(this.holdings == null) return false; - this.holdings.subtract(amount); - return true; - } - - public boolean multiply(double amount) { - if(this.holdings == null) return false; - this.holdings.multiply(amount); - return true; - } - - public boolean divide(double amount) { - if(this.holdings == null) return false; - this.holdings.divide(amount); - return true; - } - - public boolean hasEnough(double amount) { - return this.holdings.hasEnough(amount); - } - - public boolean hasOver(double amount) { - return this.holdings.hasOver(amount); - } - - public boolean hasUnder(double amount) { - return this.holdings.hasUnder(amount); - } - - public boolean isNegative() { - return this.holdings.isNegative(); - } - - public boolean remove() { - if(this.account == null) return false; - this.account.remove(); - return true; - } - } -} \ No newline at end of file diff --git a/src/com/garbagemule/register/payment/methods/iCo6.java b/src/com/garbagemule/register/payment/methods/iCo6.java deleted file mode 100644 index ca013f0..0000000 --- a/src/com/garbagemule/register/payment/methods/iCo6.java +++ /dev/null @@ -1,159 +0,0 @@ -package com.garbagemule.register.payment.methods; - -import com.garbagemule.register.payment.Method; -import com.iCo6.iConomy; -import com.iCo6.system.Account; -import com.iCo6.system.Accounts; -import com.iCo6.system.Holdings; - - -import org.bukkit.plugin.Plugin; - -/** - * iConomy 6 Implementation of Method - * - * @author Nijikokun (@nijikokun) - * @copyright (c) 2011 - * @license AOL license - */ -public class iCo6 implements Method { - private iConomy iConomy; - - public iConomy getPlugin() { - return this.iConomy; - } - - public String getName() { - return "iConomy"; - } - - public String getVersion() { - return "6"; - } - - public int fractionalDigits() { - return 2; - } - - public String format(double amount) { - return com.iCo6.iConomy.format(amount); - } - - public boolean hasBanks() { - return false; - } - - public boolean hasBank(String bank) { - return false; - } - - public boolean hasAccount(String name) { - return (new Accounts()).exists(name); - } - - public boolean hasBankAccount(String bank, String name) { - return false; - } - - public boolean createAccount(String name) { - if(hasAccount(name)) - return false; - - return (new Accounts()).create(name); - } - - public boolean createAccount(String name, Double balance) { - if(hasAccount(name)) - return false; - - return (new Accounts()).create(name, balance); - } - - public MethodAccount getAccount(String name) { - return new iCoAccount((new Accounts()).get(name)); - } - - public MethodBankAccount getBankAccount(String bank, String name) { - return null; - } - - public boolean isCompatible(Plugin plugin) { - return plugin.getDescription().getName().equalsIgnoreCase("iconomy") - && plugin.getClass().getName().equals("com.iCo6.iConomy") - && plugin instanceof iConomy; - } - - public void setPlugin(Plugin plugin) { - iConomy = (iConomy)plugin; - } - - public class iCoAccount implements MethodAccount { - private Account account; - private Holdings holdings; - - public iCoAccount(Account account) { - this.account = account; - this.holdings = account.getHoldings(); - } - - public Account getiCoAccount() { - return account; - } - - public double balance() { - return this.holdings.getBalance(); - } - - public boolean set(double amount) { - if(this.holdings == null) return false; - this.holdings.setBalance(amount); - return true; - } - - public boolean add(double amount) { - if(this.holdings == null) return false; - this.holdings.add(amount); - return true; - } - - public boolean subtract(double amount) { - if(this.holdings == null) return false; - this.holdings.subtract(amount); - return true; - } - - public boolean multiply(double amount) { - if(this.holdings == null) return false; - this.holdings.multiply(amount); - return true; - } - - public boolean divide(double amount) { - if(this.holdings == null) return false; - this.holdings.divide(amount); - return true; - } - - public boolean hasEnough(double amount) { - return this.holdings.hasEnough(amount); - } - - public boolean hasOver(double amount) { - return this.holdings.hasOver(amount); - } - - public boolean hasUnder(double amount) { - return this.holdings.hasUnder(amount); - } - - public boolean isNegative() { - return this.holdings.isNegative(); - } - - public boolean remove() { - if(this.account == null) return false; - this.account.remove(); - return true; - } - } -} diff --git a/test/config.yml b/test/config.yml index 6059fac..7cd8e4d 100644 --- a/test/config.yml +++ b/test/config.yml @@ -76,7 +76,10 @@ arenas: priority: 1 frequency: 1 monsters: - mushroom_cows: 10 + zombies: 30 + skeletons: 18 + spiders: 5 + mushroom_cows: 1 wave: 1 boss1: type: boss diff --git a/test/garbagemule/mobarena/standard/TestNewConfig.java b/test/garbagemule/mobarena/standard/TestNewConfig.java deleted file mode 100644 index 0094471..0000000 --- a/test/garbagemule/mobarena/standard/TestNewConfig.java +++ /dev/null @@ -1,212 +0,0 @@ -package garbagemule.mobarena.standard; - -import static org.junit.Assert.*; - -import java.io.*; -import java.sql.Timestamp; -import java.text.SimpleDateFormat; -import java.util.*; - -import org.apache.commons.io.FileUtils; -import org.bukkit.util.config.Configuration; -import org.junit.*; - -import com.garbagemule.MobArena.util.Config; - -@SuppressWarnings("deprecation") -public class TestNewConfig -{ - private Configuration oldConfig; - private Config newConfig; - private File testFileOld, testFileNew; - - @Before - public void setup() { - testFileOld = makeTestFile("test", "config.yml"); - testFileNew = makeTestFile("test", "config.yml"); - - oldConfig = new Configuration(testFileOld); - newConfig = new Config(testFileNew); - - oldConfig.load(); - newConfig.load(); - } - - @After - public void cleanup() { - testFileOld.delete(); - testFileNew.delete(); - } - - @Test - public void getProperty() { - String path = "arenas.lol.rewards.waves.after.7"; - - Object oldObj = oldConfig.getProperty(path); - Object newObj = newConfig.getProperty(path); - - assertEquals(oldObj, newObj); - } - - @Test - public void getInt() { - String path = "arenas.lol.settings.first-wave-delay"; - int oldInt = oldConfig.getInt(path, -1); - int newInt = newConfig.getInt(path, -2); - - assertEquals(oldInt, newInt); - } - - @Test - public void getString() { - String path = "classes.Knight.items"; - String oldString = oldConfig.getString(path, "old"); - String newString = newConfig.getString(path, "new"); - - assertEquals(oldString, newString); - - path = "classes.Knight.armor"; - oldString = oldConfig.getString(path, "old"); - newString = newConfig.getString(path, "new"); - - assertEquals(oldString, newString); - } - - @Test - public void getBoolean() { - String path = "global-settings.enabled"; - boolean oldBoolean = oldConfig.getBoolean(path, false); - boolean newBoolean = newConfig.getBoolean(path, true); - - assertEquals(oldBoolean, newBoolean); - - // Test with both permutations of the default value. - oldBoolean = oldConfig.getBoolean(path, true); - newBoolean = newConfig.getBoolean(path, false); - - assertEquals(oldBoolean, newBoolean); - } - - @Test - public void getKeys() { - String path = "classes"; - - List oldList = new LinkedList(); - List newList = new LinkedList(); - - oldList.addAll(oldConfig.getKeys(path)); - newList.addAll(newConfig.getKeys(path)); - - // Sort, just in case. - Collections.sort(oldList); - Collections.sort(newList); - - assertEquals(oldList, newList); - } - - @Test - public void getStringList() { - String path = "classes.Knight.permissions"; - - List oldList = oldConfig.getStringList(path, null); - List newList = newConfig.getStringList(path, null); - assertNotNull(oldList); - assertNotNull(newList); - assertFalse(oldList.isEmpty()); - assertFalse(newList.isEmpty()); - - assertEquals(oldList, newList); - - // Empty lists. - path = "classes.Tank.permissions"; - - oldList = oldConfig.getStringList(path, new LinkedList()); - newList = newConfig.getStringList(path, new LinkedList()); - assertNotNull(oldList); - assertNotNull(newList); - assertTrue(oldList.isEmpty()); - assertTrue(newList.isEmpty()); - - assertEquals(oldList, newList); - - // Null values behave the same as empty lists. - oldList = oldConfig.getStringList(path, null); - newList = newConfig.getStringList(path, null); - assertNotNull(oldList); - assertNotNull(newList); - assertTrue(oldList.isEmpty()); - assertTrue(newList.isEmpty()); - - assertEquals(oldList, newList); - - - // Non-existing lists. - path = "classes.Archer.permissions"; - - oldList = oldConfig.getStringList(path, new LinkedList()); - newList = newConfig.getStringList(path, new LinkedList()); - assertNotNull(oldList); - assertNotNull(newList); - assertTrue(oldList.isEmpty()); - assertTrue(newList.isEmpty()); - - assertEquals(oldList, newList); - } - - @Test - public void removeProperty() { - String path = "global-settings.enabled"; - - // Make sure something exists first. - Object oldObj = oldConfig.getProperty(path); - Object newObj = newConfig.getProperty(path); - assertNotNull(oldObj); - assertNotNull(newObj); - - assertEquals(oldObj, newObj); - - // Remove and try again. - oldConfig.removeProperty(path); - newConfig.removeProperty(path); - - // They should now both be null. - oldObj = oldConfig.getProperty(path); - newObj = newConfig.getProperty(path); - assertNull(oldObj); - assertNull(newObj); - - assertEquals(oldObj, newObj); - - // Should be idempotent. - oldConfig.removeProperty(path); - newConfig.removeProperty(path); - - oldObj = oldConfig.getProperty(path); - newObj = newConfig.getProperty(path); - assertNull(oldObj); - assertNull(newObj); - - assertEquals(oldObj, newObj); - } - - private File makeTestFile(String path, String filename) { - // Grab the time - Timestamp timestamp = new Timestamp(new Date().getTime()); - - // Convert to a string - String time = new SimpleDateFormat("MM-dd-yyyy-H_m_s_S").format(timestamp); - - // Make a new file - File testFile = new File(path + File.separator + time + "_" + filename); - - // Start copying the bytes - try { - FileUtils.copyFile(new File(path + File.separator + filename), testFile); - } - catch (Exception e) { - e.printStackTrace(); - } - - return testFile; - } -} diff --git a/test/garbagemule/mobarena/standard/TestUserCommands.java b/test/garbagemule/mobarena/standard/TestUserCommands.java deleted file mode 100644 index a44ed57..0000000 --- a/test/garbagemule/mobarena/standard/TestUserCommands.java +++ /dev/null @@ -1,208 +0,0 @@ -package garbagemule.mobarena.standard; - -import static org.junit.Assert.*; - -import mock.bukkit.*; -import mock.mobarena.*; -import mock.util.MockLogger; - -import org.junit.*; - -import com.garbagemule.MobArena.*; -import com.garbagemule.MobArena.commands.*; - -public class TestUserCommands -{ - private static final String LABEL = "ma"; - - private MockLogger log; - private String expected; - - private MobArenaPlugin plugin; - private ArenaMaster arenaMaster; - private CommandHandler commandHandler; - private MockPlayer player; - - @Before - public void setup() { - // Set up the log.; - log = new MockLogger(); - log.log("Start"); - - // Create a plugin. - plugin = new MockMobArena(); - - // Get the ArenaMaster. - arenaMaster = plugin.getArenaMaster(); - - // Create a player and a command handler. - player = new MockPlayer("garbagemule", log); - commandHandler = new CommandHandler(plugin); - } - - @After - public void cleanup() { - log = null; - plugin = null; - arenaMaster = null; - player = null; - commandHandler = null; - } - - - - /* ********************************************************************* */ - /* - /* JOIN COMMAND - /* - /* ********************************************************************* */ - - // TODO: Expand all tests to check that the player is indeed added and warped. - - @Test - public void expectArguments() { - commandHandler.onCommand(player, null, LABEL, compileArgs()); - expected = MockLogger.compileMsgToPlayer(player, Msg.MISC_NONE); - assertEquals(expected, log.getLastEntry().getValue()); - } - - @Test - public void playerCanJoinExistingArena() { - // Create some arenas. - createArenas("test","test2","test21","test12"); - - // Try to join an existing arena. - commandHandler.onCommand(player, null, LABEL, compileArgs("join","test")); - - // Success! - expected = MockLogger.compileMsgToPlayer(player, Msg.JOIN_PLAYER_JOINED); - assertEquals(expected, log.getLastEntry().getValue()); - - // Verify that the player is now in the lobby. - Arena a = arenaMaster.getArenaWithName("test"); - assertTrue(a.inLobby(player)); - } - - @Test - public void playerCantJoinNonExistingArena() { - // Create some arenas. - createArenas("test","test2","test21","test12"); - - // Try to join one that doesn't exist. - commandHandler.onCommand(player, null, LABEL, compileArgs("join","test1")); - - // Failure! - expected = MockLogger.compileMsgToPlayer(player, Msg.ARENA_DOES_NOT_EXIST); - assertEquals(expected, log.getLastEntry().getValue()); - } - - @Test - public void argsRequiredForMultipleArenas() { - // Create some arenas. - createArenas("test","test2","test21","test12"); - - // Try to join with no arguments. - commandHandler.onCommand(player, null, LABEL, compileArgs("join")); - - // Should join the only existing arena. - expected = MockLogger.compileMsgToPlayer(player, Msg.JOIN_ARG_NEEDED); - assertEquals(expected, log.getLastEntry().getValue()); - } - - @Test - public void noArgsNeededForOneArenaOnly() { - // Create one arena. - createArenas("gjklqwejklewjglkejg"); - - // Try to join with no arguments. - commandHandler.onCommand(player, null, LABEL, compileArgs("join")); - - // Should join the only existing arena. - expected = MockLogger.compileMsgToPlayer(player, Msg.JOIN_PLAYER_JOINED); - assertEquals(expected, log.getLastEntry().getValue()); - - // Verify that the player is now in the lobby. - Arena a = arenaMaster.getArenaWithName("gjklqwejklewjglkejg"); - assertTrue(a.inLobby(player)); - } - - @Test - public void playerCanOnlyJoinPermittedArenas() { - // Create a couple of arenas. - createArenas("yay", "nay"); - - // Give the player no permission for one. - player.setPermission("mobarena.arenas.nay", false); - - // Try to join. - commandHandler.onCommand(player, null, LABEL, compileArgs("join","nay")); - - // No permission. - expected = MockLogger.compileMsgToPlayer(player, Msg.JOIN_ARENA_PERMISSION); - assertEquals(expected, log.getLastEntry().getValue()); - - // Verify that the player didn't join and isn't in the lobby. - Arena a = arenaMaster.getArenaWithName("nay"); - assertFalse(a.inLobby(player)); - } - - - - /* ********************************************************************* */ - /* - /* LIST ARENAS COMMAND - /* - /* ********************************************************************* */ - - @Test - public void shouldListAllArenas() { - // Create some arenas. - createArenas("one", "two", "three", "four"); - - // Try to list them. - commandHandler.onCommand(player, null, LABEL, compileArgs("arenas")); - - // Should show all of them, because player has permission to all per default. - expected = MockLogger.compileMsgToPlayer(player, Msg.MISC_LIST_ARENAS.toString("one, two, three, four")); - assertEquals(expected, log.getLastEntry().getValue()); - } - - @Test - public void shouldListMiscNoneIfNoArenas() { - // Create an arena and remove the permission. - createArenas("one"); - player.setPermission("mobarena.arenas.one", false); - - // Try to list arenas. - commandHandler.onCommand(player, null, LABEL, compileArgs("arenas")); - - // Should display MISC_NONE - String none = Msg.MISC_NONE.toString(); - expected = MockLogger.compileMsgToPlayer(player, Msg.MISC_LIST_ARENAS.toString(none)); - assertEquals(expected, log.getLastEntry().getValue()); - } - - @Test - public void shouldDisplayOnlyPermittedArenas() { - // Create three arenas, remove permissions for one. - createArenas("one", "two", "three"); - player.setPermission("mobarena.arenas.two", false); - - // List arenas. - commandHandler.onCommand(player, null, LABEL, compileArgs("arenas")); - - // Should display one and three. - expected = MockLogger.compileMsgToPlayer(player, Msg.MISC_LIST_ARENAS.toString("one, three")); - assertEquals(expected, log.getLastEntry().getValue()); - } - - private void createArenas(String... args) { - for (String s : args) { - arenaMaster.createArenaNode(s, null); - } - } - - private String[] compileArgs(String... args) { - return args; - } -} diff --git a/test/mock/bukkit/MockPlayer.java b/test/mock/bukkit/MockPlayer.java index 177d59e..22aed64 100644 --- a/test/mock/bukkit/MockPlayer.java +++ b/test/mock/bukkit/MockPlayer.java @@ -9,10 +9,13 @@ import org.bukkit.*; import org.bukkit.block.Block; import org.bukkit.entity.*; import org.bukkit.event.entity.EntityDamageEvent; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.inventory.*; import org.bukkit.map.MapView; import org.bukkit.permissions.*; import org.bukkit.plugin.Plugin; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; import org.bukkit.util.Vector; public class MockPlayer implements Player @@ -973,4 +976,136 @@ public class MockPlayer implements Player } + @Override + public Player getKiller() + { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean teleport(Location arg0, TeleportCause arg1) + { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean teleport(Entity arg0, TeleportCause arg1) + { + // TODO Auto-generated method stub + return false; + } + + @Override + public long getFirstPlayed() + { + // TODO Auto-generated method stub + return 0; + } + + @Override + public long getLastPlayed() + { + // TODO Auto-generated method stub + return 0; + } + + @Override + public boolean hasPlayedBefore() + { + // TODO Auto-generated method stub + return false; + } + + @Override + public void playEffect(EntityEffect arg0) { + // TODO Auto-generated method stub + + } + + @Override + public Set getListeningPluginChannels() { + // TODO Auto-generated method stub + return null; + } + + @Override + public void sendPluginMessage(Plugin arg0, String arg1, byte[] arg2) { + // TODO Auto-generated method stub + + } + + //@Override + public boolean getAllowFlight() { + // TODO Auto-generated method stub + return false; + } + + //@Override + public void setAllowFlight(boolean arg0) { + // TODO Auto-generated method stub + + } + + //@Override + public void setBedSpawnLocation(Location arg0) { + // TODO Auto-generated method stub + + } + + @Override + public boolean addPotionEffect(PotionEffect arg0) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean addPotionEffect(PotionEffect arg0, boolean arg1) { + // TODO Auto-generated method stub + return false; + } + + @Override + public boolean addPotionEffects(Collection arg0) { + // TODO Auto-generated method stub + return false; + } + + @Override + public Collection getActivePotionEffects() { + // TODO Auto-generated method stub + return null; + } + + @Override + public boolean hasPotionEffect(PotionEffectType arg0) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void removePotionEffect(PotionEffectType arg0) { + // TODO Auto-generated method stub + + } + + @Override + public boolean canSee(Player arg0) { + // TODO Auto-generated method stub + return false; + } + + @Override + public void hidePlayer(Player arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void showPlayer(Player arg0) { + // TODO Auto-generated method stub + + } + } diff --git a/test/mock/mobarena/MockArena.java b/test/mock/mobarena/MockArena.java deleted file mode 100644 index 3255a90..0000000 --- a/test/mock/mobarena/MockArena.java +++ /dev/null @@ -1,540 +0,0 @@ -package mock.mobarena; - -import java.util.Collection; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.block.Block; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.entity.Wolf; -//import org.bukkit.util.config.Configuration; - -import com.garbagemule.MobArena.Arena; -import com.garbagemule.MobArena.ArenaPlayer; -import com.garbagemule.MobArena.ArenaPlayerStatistics; -import com.garbagemule.MobArena.MAUtils; -import com.garbagemule.MobArena.MobArena; -import com.garbagemule.MobArena.MobArenaPlugin; -import com.garbagemule.MobArena.Msg; -import com.garbagemule.MobArena.repairable.Repairable; -import com.garbagemule.MobArena.util.Config; -import com.garbagemule.MobArena.waves.BossWave; -import com.garbagemule.MobArena.waves.Wave; - -public class MockArena extends Arena -{ - private MobArenaPlugin plugin; - private String name; - private boolean enabled; - - public MockArena(MobArenaPlugin plugin, String name, World world) { - this.plugin = plugin; - this.name = name; - this.enabled = true; - this.setup = true; - this.running = false; - - this.arenaPlayers = new HashSet(); - this.lobbyPlayers = new HashSet(); - } - - @Override - public boolean startArena() - { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean endArena() - { - // TODO Auto-generated method stub - return false; - } - - @Override - public void forceStart() - { - // TODO Auto-generated method stub - - } - - @Override - public void forceEnd() - { - // TODO Auto-generated method stub - - } - - @Override - public void playerJoin(Player p, Location loc) { - lobbyPlayers.add(p); - } - - @Override - public void playerReady(Player p) - { - // TODO Auto-generated method stub - - } - - @Override - public void playerLeave(Player p) - { - // TODO Auto-generated method stub - - } - - @Override - public void playerDeath(Player p) - { - // TODO Auto-generated method stub - - } - - @Override - public void playerSpec(Player p, Location loc) - { - // TODO Auto-generated method stub - - } - - @Override - public void playerKill(Player p) - { - // TODO Auto-generated method stub - - } - - @Override - public void restoreInvAndGiveRewardsDelayed(Player p) - { - // TODO Auto-generated method stub - - } - - @Override - public void restoreInvAndGiveRewards(Player p) - { - // TODO Auto-generated method stub - - } - - @Override - public void storePlayerData(Player p, Location loc) - { - // TODO Auto-generated method stub - - } - - @Override - public void storeContainerContents() - { - // TODO Auto-generated method stub - - } - - @Override - public void restoreContainerContents() - { - // TODO Auto-generated method stub - - } - - @Override - public void movePlayerToLobby(Player p) - { - // TODO Auto-generated method stub - - } - - @Override - public void movePlayerToSpec(Player p) - { - // TODO Auto-generated method stub - - } - - @Override - public void movePlayerToEntry(Player p) - { - // TODO Auto-generated method stub - - } - - @Override - public void repairBlocks() - { - // TODO Auto-generated method stub - - } - - @Override - public void queueRepairable(Repairable r) - { - // TODO Auto-generated method stub - - } - - @Override - public void assignClass(Player p, String className) - { - // TODO Auto-generated method stub - - } - - @Override - public void assignRandomClass(Player p) - { - // TODO Auto-generated method stub - - } - - @Override - public void assignClassPermissions(Player p) - { - // TODO Auto-generated method stub - - } - - @Override - public void removeClassPermissions(Player p) - { - // TODO Auto-generated method stub - - } - - @Override - public void load(Config config) - { - // TODO Auto-generated method stub - - } - - @Override - public void restoreRegion() - { - // TODO Auto-generated method stub - - } - - @Override - public void serializeConfig() - { - // TODO Auto-generated method stub - - } - - @Override - public void deserializeConfig() - { - // TODO Auto-generated method stub - - } - - @Override - public boolean serializeRegion() - { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean deserializeRegion() - { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean inRegion(Location loc) - { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean inRegionRadius(Location loc, int radius) - { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean inArena(Player p) - { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean inLobby(Player p) { - return lobbyPlayers.contains(p); - } - - @Override - public boolean isEnabled() { - return enabled; - } - - @Override - public boolean isRunning() - { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isPvpEnabled() - { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isLightningEnabled() - { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean isBossWave() - { - // TODO Auto-generated method stub - return false; - } - - @Override - public String configName() { - return name; - } - - @Override - public String arenaName() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public MobArena getPlugin() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public World getWorld() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public Wave getWave() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public void setWave(Wave wave) - { - // TODO Auto-generated method stub - - } - - @Override - public void setBossWave(BossWave bossWave) - { - // TODO Auto-generated method stub - - } - - @Override - public Set getClasses() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public List getAllSpawnpoints() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public List getSpawnpoints() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public Location getBossSpawnpoint() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public int getPlayerCount() - { - // TODO Auto-generated method stub - return 0; - } - - @Override - public void addBlock(Block b) - { - // TODO Auto-generated method stub - - } - - @Override - public void addMonster(LivingEntity e) - { - // TODO Auto-generated method stub - - } - - @Override - public void addExplodingSheep(LivingEntity e) - { - // TODO Auto-generated method stub - - } - - @Override - public List getAllPlayers() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public List getLivingPlayers() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public Set getArenaPlayers() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public Collection getArenaPlayerSet() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public List getArenaPlayerStatistics( - Comparator comparator) - { - // TODO Auto-generated method stub - return null; - } - - @Override - public List getNonreadyPlayers() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public Set getMonsters() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public Set getPets() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public void resetIdleTimer() - { - // TODO Auto-generated method stub - - } - - @Override - public void addTrunkAndLeaves(Block b) - { - // TODO Auto-generated method stub - - } - - @Override - public boolean canAfford(Player p) - { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean takeFee(Player p) - { - // TODO Auto-generated method stub - return false; - } - - @Override - public boolean canJoin(Player p) { - if (!enabled) - plugin.tell(p, Msg.JOIN_ARENA_NOT_ENABLED); - else if (!setup) //|| recurrentWaves.isEmpty()) TODO: Test waves. - plugin.tell(p, Msg.JOIN_ARENA_NOT_SETUP); - else if (edit) - plugin.tell(p, Msg.JOIN_ARENA_EDIT_MODE); - else if (running && (notifyPlayers.contains(p) || notifyPlayers.add(p))) - plugin.tell(p, Msg.JOIN_ARENA_IS_RUNNING); - else if (arenaPlayers.contains(p) || lobbyPlayers.contains(p)) - plugin.tell(p, Msg.JOIN_ALREADY_PLAYING); - else if (!p.hasPermission("mobarena.arenas." + configName())) - plugin.tell(p, Msg.JOIN_ARENA_PERMISSION); - else if (maxPlayers > 0 && lobbyPlayers.size() >= maxPlayers) - plugin.tell(p, Msg.JOIN_PLAYER_LIMIT_REACHED); - else if (joinDistance > 0 && !inRegionRadius(p.getLocation(), joinDistance)) - plugin.tell(p, Msg.JOIN_TOO_FAR); - else if (emptyInvJoin && !MAUtils.hasEmptyInventory(p)) - plugin.tell(p, Msg.JOIN_EMPTY_INV); - else - return true; - - /*else if (!canAfford(p)) - plugin.tell(p, Msg.JOIN_FEE_REQUIRED, MAUtils.listToString(entryFee, plugin));*/ - return false; - } - - @Override - public boolean canSpec(Player p) - { - // TODO Auto-generated method stub - return false; - } - - @Override - public String toString() { - return name; - } -} diff --git a/test/mock/mobarena/MockArenaMaster.java b/test/mock/mobarena/MockArenaMaster.java deleted file mode 100644 index 964c901..0000000 --- a/test/mock/mobarena/MockArenaMaster.java +++ /dev/null @@ -1,232 +0,0 @@ -package mock.mobarena; - -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; - -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.entity.Entity; -import org.bukkit.entity.Player; - -import com.garbagemule.MobArena.*; - -public class MockArenaMaster extends ArenaMaster -{ - private MobArenaPlugin plugin; - private List arenas; - - public MockArenaMaster(MobArenaPlugin plugin) { - this.plugin = plugin; - this.arenas = new LinkedList(); - } - - @Override - public List getEnabledArenas() { - List result = new LinkedList(); - - for (Arena a : arenas) { - if (a.isEnabled()) - result.add(a); - } - - return result; - } - - @Override - public List getPermittedArenas(Player p) { - List result = new LinkedList(); - - for (Arena a : arenas) { - String perm = "mobarena.arenas." + a.configName(); - - if (!p.isPermissionSet(perm) || p.hasPermission(perm)) - result.add(a); - } - - return result; - } - - @Override - public List getEnabledAndPermittedArenas(Player p) { - List result = new LinkedList(); - - for (Arena a : arenas) { - // We only want enabled arenas. - if (!a.isEnabled()) - continue; - - // And the player must have permission. - String perm = "mobarena.arenas." + a.configName(); - if (!p.isPermissionSet(perm) || p.hasPermission(perm)) - result.add(a); - } - - return result; - } - - @Override - public Arena getArenaAtLocation(Location loc) - { - return null; - } - - @Override - public List getArenasInWorld(World world) - { - return null; - } - - @Override - public List getAllPlayers() - { - return null; - } - - @Override - public List getAllPlayersInArena(String arenaName) - { - return null; - } - - @Override - public List getAllLivingPlayers() - { - return null; - } - - @Override - public List getLivingPlayersInArena(String arenaName) - { - return null; - } - - @Override - public Arena getArenaWithPlayer(Player p) - { - return null; - } - - @Override - public Arena getArenaWithPlayer(String playerName) - { - return null; - } - - @Override - public Arena getArenaWithSpectator(Player p) - { - return null; - } - - @Override - public Arena getArenaWithMonster(Entity e) - { - return null; - } - - @Override - public Arena getArenaWithPet(Entity e) - { - return null; - } - - @Override - public Arena getArenaWithName(String configName) { - return getArenaWithName(this.arenas, configName); - } - - @Override - public Arena getArenaWithName(Collection arenas, String configName) { - for (Arena a : arenas) { - if (a.configName().equals(configName)) - return a; - } - return null; - } - - @Override - public void initialize() - { - - } - - @Override - public void loadSettings() - { - - } - - @Override - public void loadClasses() - { - - } - - @Override - public void loadArenas() - { - - } - - @Override - public Arena createArenaNode(String configName, World world) { - Arena a = new MockArena(plugin, configName, world); - arenas.add(a); - return a; - } - - @Override - public void removeArenaNode(String configName) - { - - } - - @Override - public void update(boolean settings, boolean classes, boolean arenalist) - { - - } - - @Override - public void serializeSettings() - { - - } - - @Override - public void serializeArenas() - { - - } - - @Override - public void deserializeArenas() - { - - } - - @Override - public void updateSettings() - { - - } - - @Override - public void updateClasses() - { - - } - - @Override - public void updateArenas() - { - - } - - @Override - public void updateAll() - { - - } -} diff --git a/test/mock/mobarena/MockMobArena.java b/test/mock/mobarena/MockMobArena.java index 42b7623..2cfc3b8 100644 --- a/test/mock/mobarena/MockMobArena.java +++ b/test/mock/mobarena/MockMobArena.java @@ -1,39 +1,47 @@ package mock.mobarena; -import org.bukkit.ChatColor; -import org.bukkit.command.CommandSender; +import mock.util.MockLogger; -import com.garbagemule.MobArena.ArenaMaster; -import com.garbagemule.MobArena.MobArenaPlugin; -import com.garbagemule.MobArena.Msg; +import com.garbagemule.MobArena.framework.ArenaMaster; +import com.garbagemule.MobArena.util.config.Config; -public class MockMobArena implements MobArenaPlugin +public class MockMobArena //extends MobArena //implements MobArenaPlugin { private ArenaMaster arenaMaster; + private MockLogger log; + private Config config; public MockMobArena() { - this.arenaMaster = new MockArenaMaster(this); + //this.arenaMaster = new MockArenaMaster(this); + this.log = MockLogger.getLogger("MobArenaTest"); + } + + //@Override + public void onEnable() { + //this.config = new Config(new File(getDataFolder(), "config.yml")); + //this.arenaMaster = new ArenaMasterImpl(this); + this.log.log("MockMobArena enabled."); + } + + //@Override + public void onDisable() { + log.log("MockMobArena disabled."); + } + + //@Override + public Config getMAConfig() { + return config; } - public MockMobArena(ArenaMaster arenaMaster) { - this.arenaMaster = arenaMaster; - } - - @Override + //@Override public ArenaMaster getArenaMaster() { return arenaMaster; } - - @Override - public void tell(CommandSender sender, String msg) { - if (sender == null || msg.equals("") || msg.equals(" ")) - return; - - sender.sendMessage(ChatColor.GREEN + "[MobArena] " + ChatColor.WHITE + msg); - } - - @Override - public void tell(CommandSender sender, Msg msg) { - tell(sender, msg.toString()); - } + + //@Override + public void info(String msg) { log.log("[MobArena] " + msg); } + //@Override + public void warning(String msg) { log.log("[MobArena] " + msg); } + //@Override + public void error(String msg) { log.log("[MobArena] " + msg); } } diff --git a/test/mock/util/MockLogger.java b/test/mock/util/MockLogger.java index c2ce56c..c6c3939 100644 --- a/test/mock/util/MockLogger.java +++ b/test/mock/util/MockLogger.java @@ -3,18 +3,38 @@ package mock.util; import java.sql.Timestamp; import java.util.*; import java.util.Map.Entry; +import java.util.logging.Logger; import org.bukkit.ChatColor; import org.bukkit.entity.Player; import com.garbagemule.MobArena.Msg; -public class MockLogger +public class MockLogger extends Logger { - private TreeMap entries; + private static Map loggers = new TreeMap(); + private TreeMap entries = new TreeMap(); - public MockLogger() { + /** + * Private constructor to ensure that all MockLoggers exist within this class as singletons. + */ + /*private MockLogger() { this.entries = new TreeMap(); + }*/ + protected MockLogger(String name, String resourceBundleName) { + super(name, resourceBundleName); + } + + /** + * All MockLogger objects are singletons. + * @param name the name of a MockLogger + * @return the MockLogger with the input name, or a new MockLogger if it didn't already exist. + */ + public static MockLogger getLogger(String name) { + if (!loggers.containsKey(name)) + loggers.put(name, new MockLogger(name, null)); + + return loggers.get(name); } public void log(String msg) {