Compare commits

...

705 Commits

Author SHA1 Message Date
Connor Monahan 7b982c2687
Merge pull request #848 from Ultra03/develop
Add an option in config to disable the 1.9 attack cooldown
2018-11-30 16:13:45 -06:00
= 3217c0a732
Only set player attack speed when in warzone 2018-11-28 15:57:53 -08:00
= 2e6466fab2
Fix NPE and reset attack speed when necessary 2018-11-27 21:33:00 -08:00
= 98afe494c1
Add option to disable combat cooldown 2018-11-27 20:01:13 -08:00
Connor Monahan 20e3e70461 Bumped version to 2.1.0-SNAPSHOT for development 2018-11-27 21:49:08 -06:00
Connor Monahan 26acfa6a53 War v2.0.0 release candidate 1 2018-11-27 18:14:21 -06:00
Connor Monahan 3470a0cc54
Merge pull request #846 from taoneill/feature/113savefiles
Zone database structure update
2018-11-27 18:10:52 -06:00
Connor Monahan 66ef1b9cc2 Fix saving zonemaker list updates
Honestly everyone should be using war.zonemaker by now.
2018-11-27 18:10:07 -06:00
Connor Monahan 0dde3acaed Save/load tile entities (chests, skulls, etc) 2018-11-27 18:03:19 -06:00
Connor Monahan 03c9ad95ee
Update development builds link 2018-11-25 11:38:04 -06:00
Connor Monahan 87cea1a1b4 Zone maker UUIDs, remove Tommy meme, make new format more backwards-compatible.
New starts of War 2.0 will now give server admins a chance to go in and
/savezone each of their warzones which will complete the conversion to
the new format. Note however that the admins must reset each zone using
War 1.9 first.
2018-11-20 01:18:56 -06:00
Connor Monahan 2af9379287 Zone database structure update
Breaks backwards compatibility, but the material changes already did that so whatever.
Replaces deprecated durability and tile entity serialisation with BlockData serialisation.
Optimises space by caching all used type/data strings.
2018-11-19 22:32:31 -06:00
Connor Monahan b24e495df7 Drop TagAPI support
TagAPI has been dead for several years. Also upgrade Java to 1.8, why not.
2018-11-19 20:06:06 -06:00
Connor Monahan 6b90371fce Drop Spoutcraft support
Spout has been dead for 5 years
2018-11-19 20:00:18 -06:00
Connor Monahan 81f839a0a2
Merge pull request #845 from Ultra03/develop
Fix a lot of errors for updating to 1.13
2018-11-19 19:49:58 -06:00
Connor Monahan 8b76d2068f Remove deprecated legacy materials
By deleting the entire unused methods
2018-11-19 14:37:06 -06:00
Connor Monahan 99b6bdb3dd Dumb WorldEdit unstable API
Now works for 7.0.0-beta-01
2018-11-19 14:16:01 -06:00
Connor Monahan a0174935fe Update WorldEdit Integration
Breaking, now requires WorldEdit newer than Oct. 18, 2018
2018-11-19 14:03:02 -06:00
Connor Monahan 5e4f0022df Fix UI glitches with WarHub and Dye color updates 2018-11-19 02:03:01 -06:00
Connor Monahan db7a7864f9 Fix wrong color for team gate 2018-11-19 02:02:44 -06:00
Connor Monahan 7f7babf104 Fix SQL bug 2018-11-19 01:25:57 -06:00
Connor Monahan bca78e5d0c Bump War major version due to breaking changes 2018-11-19 00:44:57 -06:00
Connor Monahan 4e83ffada1 Fix some deprecated stuff 2018-11-19 00:43:50 -06:00
Connor Monahan 69a148fc6a Drop all War backwards compatibility
Bukkit 1.13 removes item ID API entirely - therefore, it is impossible
to load legacy War format files that still use item IDs.
2018-11-18 23:51:05 -06:00
Connor Monahan 0a02e25f4a Fix renamed paintings 2018-11-18 23:30:01 -06:00
= 0babe82368
Fix a lot of errors in updating to 1.13 2018-10-31 17:10:51 -07:00
Connor Monahan 47be664a93 Allow editing loadouts from chest UI 2017-07-29 16:09:36 -05:00
Connor Monahan 821c66c556 Fix #790, add playercount and switching scoreboards
* Switching scoreboard jumps between all scoreboard types every minute
* Playercount scoreboard shows number of players per team
2017-07-29 02:14:18 -05:00
Connor Monahan 22cbba62b3 Fix #412, auto team balance for autoassign warzones 2017-07-29 01:26:30 -05:00
grinning eb7b600aef closes gh-365 gh-392 Preparation time
This allows a prep time to be added IN SECONDS!!!!
so /zonecfg preptime:<amount of time in secconds>
2017-07-29 01:05:37 -05:00
Connor Monahan 4f00befeb2 Add reset zone and restore defaults settings to UI
https://imgur.com/a/ZViyX
2017-07-29 00:35:21 -05:00
Connor Monahan f6b41bd015 Allow changing all config options from UI 2017-07-28 21:10:14 -05:00
Connor Monahan f1caca70f5 Merge remote-tracking branch 'jared/patch-2' into develop 2017-07-28 12:01:38 -05:00
Super0JET0 e45b0eb0bb Update TeamConfig.java 2017-07-28 17:05:59 +01:00
Super0JET0 910310aab4 Update WarzoneConfig.java 2017-07-28 16:50:14 +01:00
Connor Monahan 8ce9586b8d Capture point improvements
* Now gives one point every interval
* New setting: capturepointtime
* i18n
2017-07-28 02:17:29 -05:00
Connor Monahan 0f09410c66 Fix fire never going out 2017-07-28 02:08:32 -05:00
Connor Monahan 57d29f464c Fix issue with certain translations 2017-07-28 01:15:36 -05:00
Connor Monahan 9135e5bf22 Chest UI for War 2017-07-27 15:55:10 -05:00
Connor Monahan 994fec5a14 When using respawn timer, lock players in spawn with potions 2017-07-25 12:50:30 -05:00
Connor Monahan d3b5795dda Fix #178, allow players to sign up for games
Needs testing, @dylanhansch @kugick ? :D
2017-07-24 03:39:16 -05:00
Connor Monahan a4038c6df1 Fix #268, save/load paintings and item frames from DB
I swear this took longer than the capture points I added earlier :/
This spawns the paintings in the sky somewhere first, so kinda depends on server admins not building here :D
2017-07-24 03:32:20 -05:00
Connor Monahan 200bb5a3c0 Fix #563. Capture points in Minecraft!!!
Documentation coming soon :)
2017-07-21 02:25:21 -04:00
Connor Monahan 372576a396 Fix #74, add blacklist for items brought into zone
/teamcfg loadout:banned will define a set of item types that will be prohibited from entering a warzone when using playerInvAsDefault or otherwise.
2017-07-20 18:51:05 -04:00
Connor Monahan ddfa24f626 Fix #498, prevent wolves from teleporting into warzones 2017-07-20 18:24:19 -04:00
Connor Monahan b7cf69666c Fix #437, add team config 'borderdrop' to permit item drop near walls 2017-07-20 16:15:35 -04:00
Connor Monahan ef26173ba1 Fix #320, add permission when playing in a zone
When a player enters an example zone named "Castle_Wars", the following permissions are granted:
- war.playing (Added for any zone)
- war.playing.castle_wars (Added for this zone, formed by the lower case of the zone name)

To grant additional permissions from these, such as 'crackshot.use', you should modify Bukkit's permissions.yml to create a parent node for either war.playing or the zone-specific node with child nodes.
http://bukkit.gamepedia.com/Permissions.yml

Example:

war.playing:
       description: Allow use of gun plugins inside war zones only
       default: false
       children:
          crackshot.use: true
war.playing.castle_wars:
       description: Allow use of craft book elevators inside Castle_Wars only
       default: false
       children:
          craftbook.use: true
2017-07-20 16:10:34 -04:00
Connor Monahan b7138d65bd Fix #201, prevent opening zone edge chests if not playing
Roundabout fix but it solves the issue with smuggling items without requiring an additional setting
2017-07-20 15:51:38 -04:00
Connor Monahan b772b71803 Fix #750, rotate lobbies 2017-07-20 00:29:33 -04:00
Connor Monahan 9c3c43c4f6 Add chinese support, update other translations 2017-07-20 00:04:45 -04:00
Connor Monahan c5adfa7023 Fix #838, prevent growth from occupying structures
This prevents leaves/mushroom/etc from growing inside flags,
monuments, cakes, bombs, spawns, etc. Trees can still be grown
around the perimeter of such strucures, but all blocks generated
will be in breakable areas.
2017-07-19 18:43:22 -04:00
Connor Monahan 00ec38c739 Remove broken maven repos, bug fixes
* Fix stack trace when players click with no block selected
* Fix zone reset error caused by earlier commit
2017-07-19 18:15:38 -04:00
Connor Monahan 66445eb61d Replace deprecated Bukkit functions 2017-07-18 14:33:44 -04:00
Connor Monahan 334620e4b1 Fix #839, don't save armor slots twice 2017-07-16 19:59:32 -04:00
Connor Monahan 13e5d38277 Fix #840, keep health in bounds with attributes 2017-07-16 19:41:07 -04:00
Connor Monahan 5c992c95ee Set player max health 2016-06-14 23:02:48 -05:00
Connor Monahan 53c683abf3 Bumped version to 1.10-SNAPSHOT for development 2016-06-08 18:58:17 -04:00
Connor Monahan 8d908c1c50 Merge branch 'release/1.9' into develop 2016-06-08 18:57:54 -04:00
Connor Monahan 8ad26d51fe Bumped version to 1.9 for release 2016-06-08 18:55:49 -04:00
Connor Monahan e3c154ba7a Prevent breaking paintings in unbreakable zones
Closes #815
2016-06-08 18:23:30 -04:00
Connor Monahan f6175451ee Fix nohunger under 1.9
Closes #829
2016-06-08 17:59:45 -04:00
Connor Monahan aa41a11daf Update localizations 2016-06-08 02:27:35 -04:00
Connor Monahan dc4de5f6a5 Fix lifepool message at incorrect times 2016-06-08 00:25:36 -04:00
Connor Monahan 82741751cf Update mcstats version
Fixes errors finally
2016-06-06 23:42:24 -04:00
Connor Monahan 5b4accb707 Fix build error 2016-06-06 21:41:04 -04:00
Connor Monahan 624f278734 Ignore errors from outdated PluginMetrics 2016-06-06 18:49:35 -04:00
Connor Monahan c1ad45e555 Fix #833, fix #832 2016-06-06 18:16:00 -04:00
Connor Monahan f7aa952fb6 Remove project files
Use maven importer
2015-08-18 20:58:50 -05:00
kugick 9149b66142 Merge pull request #827 from fikry13/develop
Remove torch from WarHub Gate
2015-08-18 21:50:28 -04:00
Fikry Abdullah Aziz 2b5190434d Remove torch from WarHub Gate
There is a bug when the the gate is filled with players. the torch is
droping instead of stick to the redstone block
2015-08-18 22:58:17 +07:00
cmastudios e786c09bd0 Fix flag drop team color
Closes #798
2014-06-13 23:39:48 -05:00
cmastudios 2c529f7647 Fix fire burning after respawn
Whoever wrote the note in LoadoutResetJob about stopping fire knew what
he was talking about. Sadly `git blame` shows nothing due to a refactor.
However, this job was still being run in sync, therefore doing nothing.
So I added a new job that is ran a tick later to clean up.
2014-06-13 23:30:59 -05:00
cmastudios 7561fd8ffb Moved death message handling to warzone class
The more interesting change I made here was the removal of the so-called 're-killing' statements - e.g. setting the health of really dead players to 0 to ensure they are dead. Who knows, it might affect #796 and #778, because I have zero idea what is causing them.
2014-06-13 23:28:08 -05:00
cmastudios 4f60ebb780 Merge remote-tracking branch 'origin/rewrite/death' into develop 2014-06-13 21:42:49 -05:00
cmastudios 33add7df0d Option to drop inventory on kill
Closes #711, closes #13, closes #11.

Items only drop on kill to prevent players from farming items. Warzone
makers must design their warzone items to fit with this feature if they
choose to enable it. E.g. a warzone might include items that must be
found and then can be stolen on kill.

Thanks to @dylanhansch for testing.
2014-06-12 22:20:20 -05:00
cmastudios 9281ad5c4d Don't set a skull owner if empty
Closes #781

Another bug due to Mojang's new stupid username changing "feature".
Setting the owner requires a web lookup or cache hit for the name in
order to target the correct player. It apparently doesn't like looking
up a blank name.
2014-06-12 21:09:58 -05:00
cmastudios df1e5a56df Fix respawn after game end with realdeaths
Closes #793

Please note this is not a simple fix and applies it through a large
series of changes that may need to be noted in case of further troubles
in the future.

To accomplish this correctly, if a player is a really dead fighter, his
state and position will not be updated in a number of places. This is
all handled by the respawn hook for really dead fighters, which by the
way I rewrote because yolo. It makes a (potentially incorrect)
assumption that there is no reason a zone should hold a previous player
state when they join, so it is deleted for safety purposes. If not, and
the player leaves the zone, they may lose items. This may fix other
related inventory reset issues.
2014-06-12 20:59:01 -05:00
cmastudios bdc961c7e1 Prevent trees from extending out of warzone
Closes #799
2014-06-12 19:12:42 -05:00
cmastudios 382261eb83 Killstreak effects
Closes #776
Customizable effects on killstreak
2014-06-07 12:38:51 -05:00
cmastudios d4976ecbb4 #790 Add top kills scoreboard
This new scoreboard displays each person's total amount of kills for the
battle in the warzone.
2014-06-07 12:23:57 -05:00
cmastudios 92002a06a2 Rewrote Warzone#handleDeath
NEEDS TESTING
2014-05-19 19:31:21 -05:00
taoneill 5e93ab6bc4 Merge branch 'hotfix/1.8.1' into develop
Conflicts:
	war/pom.xml
	war/src/main/resources/plugin.yml
2014-05-04 17:39:31 -04:00
cmastudios 463d51d41b Print error if the world was deleted
Warzones created in worlds that are then deleted can cause a stack
trace to dump in the error log. This replaces the stack trace with
an informative error message.

Closes #774
2014-04-28 19:03:05 -05:00
cmastudios aeda124c1c Max health can be changed somehow
Give the player the maximum amount of health on respawn.

Closes #766
2014-04-23 22:08:49 -05:00
cmastudios 9bd9f76b9e Some skulls don't have owners
Bukkit 1.7.9 functionality change now throws an exception rather
than returning null.

Closes #768
2014-04-23 21:59:42 -05:00
cmastudios 14054454af Prevent emptying buckets on important blocks
Closes #775
2014-04-23 21:45:23 -05:00
cmastudios 181fb64c50 break Statement referenced the wrong loop
At least I think. Any comments @taoneill ?

Closes #773
2014-04-20 14:56:45 -05:00
cmastudios 7ed33e8965 Don't send blank messages to the client
Closes #742
2014-04-10 18:58:21 -05:00
cmastudios a529e0c1fe Reset player fall damage when respawned
Potentially fixes #757.
2014-04-10 18:40:58 -05:00
cmastudios e229f9fc4e Correct spelling and grammar
* Fix unescaped quotes causing resourcebundle message breakage.
* Fix verb tense of 'loses'
* Fix spelling of 'monument'

Closes #761
2014-03-21 19:39:44 -05:00
Master-chan 367f5d1a73 Fixes NPE when deadly adjectives is empty
For example with russian translation
2014-03-04 23:54:08 -06:00
cmastudios 1ad05dd5f3 Bump version to 1.8.1 2014-03-04 23:49:41 -06:00
cmastudios 0a80198084 Economy support!
Supports any economy supported by Vault. Requires Vault plugin
installed on server.

Closes #98, ping #132, #294, #12
2014-02-26 20:00:29 -06:00
cmastudios 09e0919042 Exemption by-permission for command warm-up
Permission node: war.warmupexempt
2014-02-26 19:07:00 -06:00
cmastudios 8bf6d6047d Literally none of those new features worked
I better test before commit next time :)
2014-02-26 19:02:32 -06:00
cmastudios f00ed85c4b Add economy reward for winning team 2014-02-26 18:51:39 -06:00
cmastudios 43bbb24dd5 Initial Vault support for economy
I personally dislike forcing our users to use a separate plugin
just to abstract different economy plugins, but sadly we live in a
hell world where there are 20 competing economy plugins and
counting so I don't want to deal with that.
2014-02-26 17:07:44 -06:00
cmastudios 64ae4c617f Teleport 'warmup' time - delay before teleport
Closes #507.

War now includes a configuration option "TPWARMUP" to add delays
before teleporting players to a war. This can be used on full-world
PvP servers to prevent players from running away from a fight.

The configuration option is specified in ticks - 20/sec.

The delay is activated for /zone and /warhub.

@taoneill @cmastudios documentate for 1.9 release.
2014-02-22 19:46:53 -06:00
cmastudios 72a2f08d70 Config to apply potions on spawn.
Closes #615.

The new APPLYPOTION configuration option allows warzone makers to
give potion effects ot players every time they spawn.

Use case: Resistance 5 for a few seconds on player spawn to prevent
them from being "spawn camped" - killed when they step out by other
players waiting nearby.

Format of APPLYPOTION: effect_type:duration:amplification

 effect_type:
  For a valid list of values that can be used for this type param,
  please see http://jd.bukkit.org/rb/apidocs/org/bukkit/potion/PotionEffectType.html

 duration:
  Time in ticks (1/20 sec) that the potion will apply for.

 amplification:
  Amplifier to the potion's power.

@taoneill @cmastudios documentate how to tune this option before
 1.9 release on the wiki. Also please test use of this option in
 game (pulling a @grinning here).
2014-02-22 18:12:11 -06:00
cmastudios 4106dd887f Autojoin zone on connect
Closes #698. #733.

@taoneill please test.
2014-02-22 01:17:20 -06:00
cmastudios 1d6ffcea7e Bump version to 1.9-SNAPSHOT for development
@taoneill @grinning we need a new name for War 1.9. Maybe Bob can have his
chance again after all?

@taoneill also please update main war branch to 'develop'.
2014-02-22 01:15:42 -06:00
taoneill 6294922225 Bumped up version to 1.8. Congrats! 2014-02-01 22:21:20 -05:00
taoneill bed0385476 Instead of small redstone torch to highlight active zones, now we have two big redstone blocks and two torches.
- Less subtle, but really gets the point accross (and doesn't have the won't-work-on-glass problem). :)
2014-02-01 21:31:19 -05:00
taoneill 0e481bb5d5 Changed all gate signs to be wall signs instead of sign posts.
- Also, now highlighting active warzones with a redstone torch on its warhub gate
2014-02-01 17:08:46 -05:00
taoneill b17e38cfd2 Closes #746. OnEntityCombust event handler was firing for non-fire events and cancelling regular damage events for players within spawn.
- This fixes players being able to profit from spawn damage protection even if they already left the spawn once
2014-01-26 17:20:56 -05:00
cmastudios 5146a7c9c8 Send "English" instead of an empty string 2014-01-19 15:09:41 -06:00
cmastudios 20223d1c12 Fix lobby width issue with auto assign
Fixed by moving calculateLobbyWidth logic into constructors.

@taoneill this is to fix the issue zac encountered on war hub.
2014-01-19 14:38:25 -06:00
taoneill 4fde95ee7b Merge branch 'master' of https://github.com/taoneill/war 2014-01-12 22:16:50 -05:00
taoneill 7ee243e20d Prevent players from leaving spawn while zone is resetting.
- Closes #738
2014-01-12 22:16:36 -05:00
Connor Monahan 82267764e1 OMG I COMMITTED SPACES 2014-01-12 18:31:31 -06:00
taoneill 0c9ed4b238 Merge branch 'master' of https://github.com/taoneill/war 2014-01-12 18:32:34 -05:00
taoneill 95ee0c1972 Closes #739. Respawning doesn't wipe your chat anymore.
- We just take care of wiping top inventory slots in CRAFTING-type inventory views (container inventories weren't causing the same issue)
- End-of-game teleport and state restoration shouldn't wipe your chat anymore either
2014-01-12 18:32:19 -05:00
Connor Monahan 95cc2c7a34 Update team spawns for TXT files. Closes #717 2014-01-11 22:13:11 -06:00
Connor Monahan 2ef0f3e324 Remove java 1.7 locale methods 2014-01-11 21:09:17 -06:00
Connor Monahan 076e8ce9bd Update locales KO PL
PL has been completed, KO corrections.
There needed to be a trailing newline on the warhub sign localization or the plugin crashed when loading a lobby.
2014-01-07 20:57:14 -06:00
Connor Monahan ce1b60b85f Make country-specific localizations work properly
Language tags such as pt_BR and ko_KR now work correctly
2014-01-07 20:51:52 -06:00
Connor Monahan a92b2ea4ae Magic wool block appears when hat clicked 2014-01-07 20:18:32 -06:00
Connor Monahan c6c93ba44f Set helmets on players instead of blocks 2014-01-07 19:49:22 -06:00
Connor Monahan 20068cbb15 Fix player list spacing issue 2014-01-07 18:37:33 -06:00
Connor Monahan b011d3a46f New active sign, gets random warzone with players 2014-01-07 17:59:08 -06:00
Connor Monahan bc07a60b51 Only randomly teleport to zones that are enabled 2014-01-07 17:51:49 -06:00
Connor Monahan dc764de258 Restore maven2 compatibility
Adding metrics support via shading caused a unexpected break due to versions of shade being incompatible with older versions of maven. In theory, everyone should update to maven3 if possible. However, I would like to retain compatiblity for our older CI servers.
2014-01-04 17:40:49 -06:00
Connor Monahan a45a833e68 Merge branch 'metrics' 2014-01-04 17:08:41 -06:00
Connor Monahan fdc4e90635 [Lang] Add FR HU KO NO PL PT localizations
This commit adds localizations for the languages French, Korean, and Norwegian. Portuguese, Hungarian, and Polish are still a work-in-progress but they have been added. The languages German, Spanish, and Russian have been updated also.
2014-01-03 20:16:28 -06:00
Connor Monahan 0805a04cad Collect metrics statistics from servers
War now collects statistics from servers running the plugin. The statistics are minimal. The goal is so the developers of the plugin can tell what areas they need to do more work in.
In addition to the default statistics collected by PluginMetrics, War sends the number of warzones and if certain plugins that War interfaces with are enabled.
To prevent your server from sending statistical data, set "opt-out" to "true" in plugins/PluginMetrics/config.yml.
Closes #716.
2013-12-27 18:13:30 -06:00
Connor Monahan ca03c96173 [Behavior] Blockheads:true now gives leather hat
Warzones that previously used blockheads:false during the preview to get a properly colored hat now need to switch to blockheads:true for a hat. Old warzones that have blockheads:true will now have colored helmets instead of block heads.
Closes #528.
2013-12-27 15:31:11 -06:00
Connor 59779eb0e5 Merge pull request #718 from taoneill/nimitz-v2
Optimize nimitz file store

Tested on bukkit server 1.7.2 with a warzone originally created with war 1.7.4, therefore upgrade works properly.
2013-12-26 17:11:11 -08:00
cmastudios 0af348f2cb Merge branch 'master' into nimitz-v2
Conflicts:
	war/src/main/java/com/tommytony/war/Warzone.java
2013-12-24 20:40:35 -06:00
grinning c16bc6ca5f Maybe closes gh-517
returns the code after the leaving of the zone. Not sure if it works.
Don't think it returns under all cases

Conflicts:
	war/src/main/java/com/tommytony/war/Warzone.java
2013-12-24 20:31:40 -06:00
cmastudios 228ec2299b Prevent block duplication
Closes #722, closes #723. War prevents thieves from messing with their inventory and anyone from messing with their block head.
2013-12-24 17:11:29 -06:00
cmastudios a120393060 Fix unbreakable regression
Closes #721. Zonemakers can modify blocks in an unbreakable zone when outside of it again.
2013-12-24 16:31:51 -06:00
cmastudios 84a5750063 Store warzone structures in main zone database
Instead of storing strutures in /dat/warzone-x/volume-y.sl3 anymore, they are stored in the main database file created for the warzone in /dat/warzone-x/volume-x.sl3. Tables is created for each structure, with the prefix being structure_HASH_. The HASH is a string hashCode run through a bitwise AND with Integer.MAX_VALUE, to prevent negative values from showing.

This is a step on the road to storing everything in a single database for the warzone. My plan is to eventually store warzone configuration in the database as well. In the ideal setup, there would be a table for teams, structure definitions, loadouts, and materials. Sadly, for configuration, we would most likely have to store teamcfg & zonecfg rules in a key-value table, unless @taoneill or @grinning has another idea.

I still need to do testing to make sure everything is backward-compatible. This conversion happens properly for nimitz-format zones and zones in the process of converting from degaulle format. When messing around earlier, I found that .txt configurations were broken due to numbered teams. I need to take a look at that. Most likely it is due to WarzoneTxtMapper not being maintained. The loader will probably have to be modified to load the new volumes and teams properly.
2013-12-08 01:46:26 -06:00
cmastudios 034b51ae03 Prevent using chests while capturing flag
Stops duplication of wool.
2013-12-07 20:49:25 -06:00
cmastudios 300f2e383b Don't reopen the file during a batch reset
Connections to the SQLite warzones are now kept open when iterating a batch reset.
2013-12-07 20:34:59 -06:00
cmastudios 346fd25955 Prevent joining zone during reset 2013-12-07 19:23:12 -06:00
cmastudios df871c1c5b Allow disabling of automatic warzone block reset
Configuration key: RESETBLOCKS
2013-12-07 16:38:48 -06:00
cmastudios 67bb509735 Stop saving Air blocks to the database
War now skips over saving Air blocks. Instead, the plugin loads all solid blocks back into the world and then sets each block to air that was not changed.

Benchmarks:
Warzone molecule
Block count 2,487,555
Speed 50,000 blocks per tick
Intel Core i7 @ 3.6 GHz * 8

Before:
File size 70 MB
Reset 23 seconds
Save 16 seconds

After:
File size 54 MB
Save 5 seconds
(no changes)
Reset 4.9 seconds
(set to air)
Reset 31.17 seconds
(set to stone)
Reset 18.23 seconds
2013-12-07 16:22:50 -06:00
cmastudios 7ef61af277 Fix logger format arguments not being applied 2013-12-07 16:15:41 -06:00
cmastudios 78ef1dd4fc Merge branch 'no-save-air' into nimitz-v2
Conflicts:
	war/src/main/java/com/tommytony/war/mapper/ZoneVolumeMapper.java
2013-12-07 03:19:36 -06:00
cmastudios 60b62c8b71 Merge branch 'master' into nimitz-v2 2013-12-07 02:44:01 -06:00
cmastudios d040edcc4e Attempt at some slight saver speed ups 2013-12-07 02:31:11 -06:00
cmastudios 21f91a00fc Configuration setting to allow ender chests 2013-12-07 00:48:03 -06:00
taoneill 6eed5bbe19 Coalesce many metadata columns in warzone blocks table into one.
- Container, sign, skulls, and more are not just a single column
- Compacting each warzone database after migration from schema v1 to v2 (to get disk space savings, but might take a while for large zones)
- Showing a few decimals on time value in zone reset messages instead of just showing "Reset in 0 seconds" all the time
2013-12-01 00:48:11 -05:00
cmastudios 5c2474cb70 Don't modify block type/data if it has not changed 2013-11-24 16:41:26 -06:00
cmastudios cc2b13633c Only update twice if we are changing tile data
War originally modified each block twice when loading, even if there was no metadata. Now it will only update once if there is no metadata.
2013-11-24 16:35:56 -06:00
taoneill 99bfbc5e58 Allow for concurrent zone resets without breaking reset notification.
- I'm an idiot I should've thought of this on the first go around, thanks @cmastudios
- Used a synchronized map, just in case
2013-11-19 19:26:55 -05:00
cmastudios 77b943ce5e German&Spanish translations. Thanks GatuCrafter, McServerExpertDe 2013-11-19 17:00:01 -06:00
cmastudios 2926387ee4 Add warcfg language parameter. Closes #686.
Allows for dynamic language switching.
2013-11-19 16:55:40 -06:00
cmastudios 0f35c4dc4c I have sinned a great sin.
Forgot to switch IntelliJ to use tabs.
2013-11-19 15:53:30 -06:00
cmastudios 66158ae44b Toggleable team chat. Closes gh-317.
Sorry @grinning, I tried to cherry pick your stuff but it did not work _at all_.
2013-11-19 15:47:01 -06:00
taoneill d4d5778175 Don't notify the command sender twice if he's in the lobby or on a team while resetting zone. 2013-11-19 00:01:38 -05:00
taoneill 31a2deef0f Add zone reset complete message.
- Also, notify command sender with progress report, not just people in teams or in lobby
2013-11-18 23:53:43 -05:00
taoneill df85b176b7 Remove broken getZoneByTeam logic
- Replaced with warzone getter on Team objects
- Should close #704
2013-11-17 23:34:31 -05:00
taoneill 97646becc3 Prevent ConcurrentModificationException while deleting a loadout.
- Closes #703
- Don't loop on an array while deleting items from it
2013-11-17 22:49:09 -05:00
Connor b0fadd4459 Fix null string bug
Thanks @smurfofsmurf
2013-11-04 21:20:08 -06:00
cmastudios c7e33dd1ca Fix message formatting and CS problems. Closes #700 2013-11-03 18:58:14 -06:00
cmastudios c6d2c6cbcc Configurable war zone max size
This war config option, MAXSIZE, can be used to change the limit on war zone size. Some reasons for using this could be to have a very long war zone or to limit the size from being abused by your zone makers. Thanks to @Delgado804 for the idea.
2013-11-03 15:58:27 -06:00
cmastudios ceeea15794 Subroutines for join/leave zone boilerplate & thief removal
Warzone now contains a few new methods to make adding and removing players from the zone easier. This was made in response to every join mechanism having to rewrite the same ~25 lines of code to handle adding players to a team. This was also done to replace the even more bulky code used to return stolen structures.

This also removes a few unused jobs as I am trying to transition away from them, as they don't really help if they are not being used for async tasks, batches, or timers.

A better way of managing teleports at the end of a game or when leaving normally has been added.
2013-11-01 18:05:02 -05:00
cmastudios 3791a027a0 Clear import warnings 2013-11-01 16:15:57 -05:00
cmastudios 13a6f8ba79 Warzone teleport signs 2013-10-27 17:23:43 -05:00
cmastudios a4e8a4be83 Make sure output health is in bounds. 2013-10-27 16:59:53 -05:00
cmastudios c44d18f8f8 Ends war in middle east. Closes #693. 2013-10-27 16:15:45 -05:00
cmastudios 215551ec15 Don't allow non-entites to damage players in spawn. Fixes #696 2013-10-27 16:10:34 -05:00
cmastudios a039e65a8a Don't burn important blocks. Fixes #697 2013-10-27 16:03:28 -05:00
cmastudios 9e6b0d9f17 Fix color after custom item names 2013-10-27 15:59:39 -05:00
taoneill df6f47907f Merge pull request #684 from taoneill/nimitz-file-format-r3
Nimitz file format. Support for custom blocks. Old warzone volume files get converted to .sl3 when you first run your server with these changes - this may take a while if you have many warzones.

Thanks @cmastudios for all the hard work on these changes.
2013-10-23 21:45:41 -07:00
cmastudios f814f71cf3 Updated russian localization from @AlexMerser21.
Closes #692. Had to add manually because I have to convert the messages to a encoded format or they do not work in game.
Cyrillic diff: http://paste.ubuntu.com/6254326/
English diff (google translate 'rough'): http://paste.ubuntu.com/6254303/
2013-10-17 20:20:21 -05:00
cmastudios dd6f425368 Fix for infinite exploding TNT near warzone edges. 2013-10-16 19:43:23 -05:00
cmastudios 7621bdd321 Fix some issues uncovered in review, add block features.
This fixes some issues found during @taoneill's review of the code. It
also adds a few features with blocks, such as a modify block whitelist.
KDR updates are now stored at the end of each battle in a warzone.
Closes #681, closes #672, closes #682, closes #683, closes #689, ping
#688.
2013-10-16 18:55:07 -05:00
cmastudios f44c2528e7 Fix war format speed regression with metadata
Found you could still get the raw data value by converting to an ItemStack, so I am using that now to reduce the lag caused by reading the serialized form of the metadata class.
2013-10-12 21:58:38 -05:00
cmastudios ac12c2af29 Fix nasty mass destruction volume bug when volume is moved
Have to experience it first hand yourself with your own work. Bugs suck.
2013-10-09 23:15:07 -05:00
cmastudios 60e74eff99 Load war zone blocks in batches to prevent server hangs
War zone blocks are now loaded from the database at a configurable speed of blocks per tick. This prevents an entire server from hanging whenever a war zone is reset. The speed can be increased or decreased based on your server's performance.
2013-10-06 13:31:56 -05:00
cmastudios aacd93b960 Add new volume format. Closes #527, closes #510, closes #500, closes #255
Block items are stored as their Material name. Block data is stored with the bukkit configuration serializer. This supports custom blocks. Tested with MCPC-Plus server.
Currently supports saving some tile entity data, such as sign text, all containers, note blocks, juke boxes, skulls/heads, command blocks, and basic mob spawners. The database is easily extensible for future blocks.
2013-10-05 16:21:25 -05:00
cmastudios 1722c86a71 Remove deprecated BlockInfo in favor of Location/BlockState
BlockInfo kept making me cringe every time I had to look at the code. More importantly it only had support for storing item IDs and no data. It was way obsolete versus new API.
2013-10-05 02:04:28 -05:00
cmastudios 6e9efc7a8a Closes gh-679 - Load chest data for trapped chests 2013-10-04 23:38:07 -05:00
cmastudios 3c80815428 Fixes gh-677 - Fix for bukkit chest inventory change 2013-10-02 15:57:46 -05:00
cmastudios 5913f73fcb Internationalized player interface, Russian locale
Most player-interfaced features such as event responders, signs, and
some player commands now have their messages stored externally in a
resource bundle. This allows for easy localization of the plugin by
copying the main messages.properties file and translating all the
messages into the language of choice.

Also thanks to @AlexMerser21 for the partial russian localization of the
plugin. This means that War servers can now show messages in the russian
language simply by starting the minecraft server with the flag
-Duser.language=ru.
2013-09-29 00:42:35 -05:00
cmastudios a7458bf261 Fixes gh-640 - Glassify a list of block types
Other block types than AIR and WATER are now automatically "glassified" by
the warzone wall guard.
2013-09-27 18:12:18 -05:00
cmastudios 39b0ead3bd Using more bukkit interfaces rather than IDs
Item/damage/anything ID's have now become deprecated in bukkit presumedly
in preparation for any sort of official server modding API. This switches
war from using IDs in most cases to bukkit-provided classes such as
ItemStack.
2013-09-27 18:11:09 -05:00
cmastudios e38b2aa62b Add event when battle ends
Actually no, I just forgot to stage this.
2013-09-20 16:15:05 -05:00
cmastudios a4f1b29922 Properly implement War event API, some cleaning.
I changed some of the new event API code from @BenMenking to use more
Bukkit provided frameworks like Player and use basic java structures
instead of checking integers.
2013-09-20 16:11:44 -05:00
Ben Menking e2f6e02ae7 Added events for various gameplay events
Added the following events for other plugins to hook into:
WarPlayerDeathEvent, WarPlayerKillEvent, WarPlayerLeaveEvent,
WarPlayerThiefEvent, WarScoreCapEvent, WarTeamWinEvent,
WarThiefDeathEvent
2013-09-16 11:47:37 -04:00
cmastudios 2bddae16a2 Restore saturation and tweak some soup pvp actions 2013-09-10 19:14:39 -05:00
Nicholasntp d94b7b3e78 Soup PvP Added
Soup PvP is now a part of warzone config.
Refer to Issue 651.
2013-09-10 19:12:02 -05:00
cmastudios f1ce78907e Fix issues with joining a team.
Players are no longer silently kicked out of their team if they try to join
a non-existant team with /join. Fix an inconsistency with the format of the
team join notification message.
2013-09-10 18:57:58 -05:00
cmastudios 12b5f8350f Handle deaths after they have been counted and rewarded.
This prevents a problem where players could be rewarded after the game ends
2013-09-10 18:11:21 -05:00
cmastudios dbac21aa44 Add MySQL kill/death logging support. Closes gh-658
War now logs kills and deaths to a MySQL database. Records are created for
every player at the end of each round with the current date and amount of
times the player killed and was killed for the entire round. It has built
in support for automatic & configurable log clearing past a certain date
(default is 1 week).
2013-09-10 17:51:30 -05:00
cmastudios 0dc7ac837f Added configurable airstrikes, based on work from @grinning. 2013-09-10 17:51:03 -05:00
cmastudios 26ec11f46c Allow the use of multiple items in rewards.
This also allows the use of XP and points as rewards.
2013-09-10 17:51:02 -05:00
cmastudios 17aef5e162 Add base for configurable KS rewards. Fixes gh-506
Killstreak rewards can be configured in the set.war.killstreak section of
war.yml. Rewards will only be applied to players if the team/warzone has
KILLSTREAK set to true.

The configuration section will get populated on generation of war.yml, or
may be manually added to older configurations.

Currently the system supports messaging the entire warzone and just the
attacker. It only supports rewards of items and health at the moment; more
are expected to arrive.

This commit also moves XPKILLMETER into the team-specific section of the
config.
2013-09-10 17:51:02 -05:00
cmastudios c66120c4fa Fixes gh-611, gh-612 - Add kill count system and kill meters with XP.
The killstreak counter shows a message if the player has more than 5
kills. I have also added an example reward system with points, but did not
enable it yet (needs discussion).

Through the warzone option xpkillmeter the XP level will get updated with
your current kill streak amount. This gets reset every time you die and
is added to every time you kill a player. If this option is enabled,
players cannot gain XP in the warzone.
2013-09-10 17:50:40 -05:00
cmastudios 2738d2e358 Add scoreboard features and configuration options. Fixes gh-623, gh-45
With the new warzone configuration property "scoreboard", zone makers can
set the type of scoreboard to be used. This may be "none", "points", or
"lifepool". If the scoreboard type is not "none", then a scoreboard will
be shown on the right side of the screen in the warzone. The shown
scoreboard will display the configured option.

Also, 3-year-old feature request COMPLETED! Use the command
/zone <warzone-name> scoreboard to view a scoreboard from anywhere.
2013-09-10 17:27:05 -05:00
cmastudios b367cc53ad Add ability to bypass warzone lobby. Fixes gh-669
If a zone has the property autojoin & autoassign set to true, then
players will be directly assigned to a team when they go through the
Warhub portal for the zone and brought back to the Warhub when they
leave the zone.
2013-09-07 18:10:23 -05:00
cmastudios 890e78fd5d TeamKind cleanup, warning fixes, closes gh-631
TeamKind has been changed to store colors in a DyeColor object instead
of using a byte value store. This improves readability and makes the
code future-proof.

All listeners are now unregistered when the plugin gets unloaded. This
removes the need for listeners to check if War is loaded and prevents
duplicate registration. I would prefer if the ability to unload and load
the War plugin was completely removed, however, as there are plugins out
there such as PlugMan that are dedicated to cleanly reloading plugins.

The main purpose of this was to clean up all issues and problems
reported by the eclipse java IDE. 0 warnings are shown by the IDE now.
2013-09-04 23:27:27 -05:00
cmastudios ea0df4f22b Store loadouts using bukkit stack seriliazer. 2013-08-09 18:45:27 -05:00
cmastudios 5a571e7329 Add support for multiple spawn points. Closes gh-628.
/setteam <color> now will add an additional spawn point if the team already
exists.

When a player joins a team in a warzone, they will be sent to any one of
their teams spawn points, picked at random.

This change required major modifications to the underlying teams subsystem
in order to support multiple spawn points for the team.
2013-08-08 23:27:09 -05:00
cmastudios 200ae92e0f Remove "Can't re-enter spawn" task.
This test task is incompatible with additions to War regarding teams.

This method of preventing players of receiving spawn protection is
currently extremely buggy and there has to be a better way to fix the issue
at hand.

@taoneill please email me if there is any serious reason this task is
needed, otherwise it just deteoriates from the War experience. Numerous
times I have played War, I have been bumped out of a warzone even due to
this. There seems to be no need for it. I can revert this commit if needed.

One possible solution could be disabling all protections for anyone who
returns to their spawn, such as like how loadout switching is prevented
after leaving spawn. Another solution could be preventing multiple teams
from taking a flag while another flag is on the run.

Please leave your ideas in the comments or email me.
2013-08-08 23:19:00 -05:00
cmastudios c56fac6c34 Make invisible spawns hidden. Closes gh-627 2013-08-08 17:25:15 -05:00
cmastudios bf3795ded1 Minecraft 1.6 compatibility.
Update health references to use double-precision floating point numbers instead
of integers due to minecraft spec change. Update Java to 1.6. Update bukkit
version.
2013-07-26 22:22:27 -10:00
cmastudios fb375002de Fixes gh-239. Add joinmidbattle zonecfg option.
With this option set to false, new players cannot join the zone if the
zone already has enough players on all teams necessary to play.
2013-07-13 17:00:56 -05:00
cmastudios ebd95a4e16 Fixes gh-410. Prevent /join in autoassign zones. 2013-07-13 16:32:21 -05:00
taoneill 756ca37a82 Merge pull request #641 from cmastudios/weselection
Create zones with WorldEdit cuboid selections. Closes #411. Thanks @cmastudios!
2013-07-01 10:41:54 -07:00
taoneill bf7e1a9847 Merge pull request #638 from cmastudios/hotfix-cslotsteal
Fix item smuggling and game end bugs. Thanks @cmastudios!
2013-07-01 10:31:00 -07:00
cmastudios 13396f85a4 Fixes gh-645, gh-643 - Load player armor when using playerloadoutasdefault 2013-06-29 23:31:01 -05:00
cmastudios c4b268910b Refresh player tags anytime players leave a zone
This fixes a bug where player tags are not reset when a zone ends normally
or when the zone is reset.
2013-06-11 23:28:26 -05:00
cmastudios 5c954a19b4 Make sure the selection is a cuboid 2013-06-11 23:11:25 -05:00
cmastudios 21688ba4d0 Create zones with WorldEdit cuboid selections
The WorldEdit API is utilized to allow the use of WorldEdit selections
when creating or modifying a warzone. If the current player has a
WorldEdit selection when the /setzone command is used, this selection will
be used for the zone's corners.
2013-06-08 22:55:35 -05:00
cmastudios 728111217e Fix game end TP bugs caused by a5cd846
Remove players from team before teleporting them back to lobby or
rallypoint.
2013-05-31 17:03:36 -05:00
cmastudios 3b0b0c6720 Fixes gh-630. Close open inventories before reset.
This fixes issues with item smuggling via crafting inventories. The
player's inventory is closed before they are kicked from the zone or a
respawn.
2013-05-30 19:09:10 -05:00
taoneill da14a8fc4d Merge pull request #635 from cmastudios/multiworld-loadout-hotfix
Fix incompabilities with per-world inventories.
2013-05-20 15:24:23 -07:00
cmastudios a5cd846b2a Fixes gh-533
Prevents players from teleporting or moving out of a warzone in play.
2013-05-18 16:49:53 -05:00
cmastudios 423654d21e Fix incompabilities with per-world inventories.
War saved a player's state before they were teleported into the warzone.
This causes issues if the lobby is in another world and the server is
using plugins to manage per-world inventories. Essentially, the player is
getting their inventory from world A saved, teleported to warzone in world
B, their state being restored in B, then teleported to A. Per-world
inventory plugins save and restore inventories on every
cross-world-teleport. This causes blank inventories when a player joins a
warzone and the player gets the items from the zone when they leave.

This issue is easily fixed by teleporting players to the warzone's world
before saving their state. This is merely a standardization of state
save/restore order.
2013-05-18 16:47:21 -05:00
taoneill e3e20fc704 Merge pull request #610 from cmastudios/colored-names
Add TagAPI support to War
2013-05-04 10:07:47 -07:00
taoneill 856d697d79 Merge pull request #587 from cmastudios/fix-colored-armor
Fix loadout issues + permission-restricted loadouts, thanks @cmastudios!!!
2013-05-04 10:02:49 -07:00
taoneill 4317b2fc8c Merge pull request #579 from cmastudios/zone-permissions
Add team-based permission requirement
2013-05-04 09:53:39 -07:00
taoneill 2d91b3cf90 Updating version to 1.8-PREVIEW (Nimitz) 2013-05-04 12:48:56 -04:00
cmastudios d724f5a382 Closes gh-617, gh-609, gh-514, gh-319, tag gh-589. Add support for
permission specific loadouts.

Loadouts can be defined with a permission which can limit who can access
the loadout, in mostly the same manner as I did in the zone-permissions
commits. The permission can be used to only allow say VIP and above to get
a certain loadout (for donation benefits) or to allow the server's lower
ranks a class only (to allow lower ranks to survive faced with the server's
experienced players).

This is controlled by an additional argument to /zonecfg.
Example: /zonecfg loadout:vip:server.ranks.VIP - allow only VIP players
access to the vip loadout.
To remove the permission, re-make the loadout without the permission
parameter.
Example: /zonecfg loadout:vip - remove the permission requirement for the
vip loadout.

To allow a lower rank access to a loadout only, you can use your permission
manager's feature of negating a permission (if supported by the plugin).
Example: /pex group recruit add server.loadout.noob, /pex group builder add
-server.loadout.noob - allow only recruits to have access to a loadout
which requires the permission "server.loadout.noob" (with PermissionsEX).
2013-03-22 22:33:38 -05:00
cmastudios e6c1e64fef Add support for new loadout system to base classes and configuration
subsystem.
2013-03-22 22:09:29 -05:00
cmastudios dd88a5ccbe Add new loadout class support to the existing loadout subsystem. 2013-03-22 22:01:02 -05:00
cmastudios 0955df7503 Added new classes to manage loadouts instead of the hashmap method. 2013-03-22 21:59:03 -05:00
cmastudios ce72ba36fa Add permission based access to warzones
Adds a team default permission configuration option. Default is
war.player. It is modifiable at the zone level and the team level. In
autoassign zones where there is a mix of teams that some players have
access to and some that they don't, the player will only ever be placed
in a team he can access. You can't /join a team you don't have
permission to join.
2013-03-21 17:15:45 -05:00
taoneill e83c53061d Update version to 1.7.4.
Updated Bukkit dependency to 1.4.7-R1.0.
2013-03-12 22:41:14 -04:00
taoneill 101bff45c5 Merge pull request #586 from cmastudios/patch-1
Fixed inability to download spout from maven. Thanks @cmastudios.
2013-03-12 19:32:11 -07:00
cmastudios 8dac3f4ea9 Fixes gh-608 - loadout "first" will be given on join and each battle after
When a player joins a warzone for the first time, they will be given a
loadout called "first" instead of the default loadout. After they have died
once, they will receive the default loadout. Players will also be assigned
the "first" loadout every battle if they are on the default loadout when
the battle ends.

I do not know how servers will deal with players who might constantly leave
and rejoin the zone in order to get the loadout back. This could be fixed
with a war change if it becomes necessary (maybe remember the player until
the battle ends). But, as always, if a server does not want to have a
"first" loadout in a warzone, they do not have to create one.
2013-03-07 18:13:39 -06:00
cmastudios 6b35645150 Prevent players from smuggling items into warzones with ender chests.
This is mainly for servers such as the Warhub, where most players can make
their own warzones. Inexperienced zone makers may place ender chests in
zones which makes their zone susceptible to smuggling items.

This may also apply for zones which would like to use ender chests for
aesthetics.

Hopefully this change shouldn't be a problem. I cannot think of any way
that an ender chest would be used inside of a warzone.
2013-03-07 17:17:06 -06:00
cmastudios 0fbf381748 gh-604 Add TagAPI support to War.
Used for changing color of player names while playing a match of War.
http://dev.bukkit.org/server-mods/tag/
2013-03-06 16:50:11 -06:00
cmastudios a3f73b5fe7 Fixes gh-594 - blockheads:off now results in a colored helmet 2013-02-09 12:47:11 -06:00
cmastudios 9ca2ed1f46 Fixed anvil names not being saved to loadout.
I also fixed "lore" too, but I do not know what it is.
2013-01-29 22:21:41 -06:00
cmastudios c3d7b74109 Fixed colored armor not working at all in loadouts 2013-01-25 19:17:20 -06:00
cmastudios c87799c03d Fixed inability to download spout from maven
Spout changed the format of their repository again. @tommytony probably didn't notice because it was cached in his local maven repositoy.
2013-01-25 17:29:29 -06:00
taoneill bff034a299 Fixed rotating warhub at restart after /warcfg.
Stops the warhub from rotating upon restart after a call to /warcfg -
sorry for the mess.  Still have to convert config files and fix
commands.
2013-01-10 22:29:26 -05:00
taoneill 0245476130 Basic support for RB 1.4.5-R1.0.
Backward compatible with 1.4.5-R0.2 and previous. Switched version to
War v1.7.4-PREVIEW. Lobbies and warhubs should line up properly now, at
least. Commands such as '/setzonelobby east' still use the wrong
directions.
2012-12-20 00:10:40 -05:00
taoneill 381047f915 Finally releasing v1.7.3.
No real improvement. Just targeting 1.4.5-R0.2 now instead of
1.2.5-R4.0. BlockFace compatibility with 1.4.5-R0.3 will come later.
2012-12-08 15:07:24 -05:00
taoneill 666f604133 Removed console warning. 2012-09-04 23:20:50 -04:00
taoneill d71adaa8ab Stopgag patch: support block IDs from 128 to 255
Got my head out of my butt and figured how I was casting bytes to ints
all wrong. War map format can support block ids up to 255 now with this
ugly patch. This is just to tide people over until a format switch to
something that will supports custom blocks and items.
2012-09-04 23:16:47 -04:00
taoneill 39a8becdfe Now handling negative block types
Closes gh-530. Weirdly, it seems that some new blocks (e.g. emerald
block) get saved with negative block type ids. For the time being, the
absolute value of the negative type id is used instead. The console spam
should be lessened as well - leading to less crashes. Still gotta find
the reason for the weird block ids, though.
2012-08-14 19:29:12 -04:00
taoneill 00af397929 Merge pull request #531 from MegaMinerJon/patch-1
Fix for (some of) the map reset crashes. Thanks @MegaMinerJon.
2012-08-13 19:04:54 -07:00
MegaMinerJon f14d21a35f Update war/src/main/java/com/tommytony/war/mapper/ZoneVolumeMapper.java 2012-08-09 11:29:43 -07:00
taoneill cd47e28e9f Removed kick prevention when flying in warzones.
Closes gh-526. Restoring a user's inventory when geting kicked. This
should technically solve an inventory reset problem. I've always found
the kick-prevention pretty hacky, anyway. Hopefully, the accidental
flying in warzones caused by War's teleporting people around has been
fixed upstream by the Bukkit folks since back in the day when this was
an issue.
2012-07-22 13:28:46 -04:00
taoneill e6d2bd0950 This sword feels wodden
I just don't see these mistakes anymore after seeing them for 1000s of
times, but they are so obvious! Thanks @revo96.
2012-07-22 13:16:06 -04:00
taoneill 411021fc35 Smoother spawn re-entry protection
Closes gh-503. Now letting players just walk through their own spawn
really fast (instead of just getting them stuck blindly), and being a
bit smarter about where I teleport them (i.e. mostly not in walls
anymore). Much less brutal than in v1.7.2.
2012-06-25 17:41:13 -04:00
taoneill 120af8e817 Updated version numbers to 1.7.3-PREVIEW 2012-06-25 14:55:14 -04:00
taoneill 5aaf25c1c7 Removed the game-end thread safety
The inventory reset bug was caused by a concurrency issue, but all this
sychronization added some now unnecessary weight. Hopefully this should
help with the lock ups that have been happenning with v1.7.2.
2012-06-25 13:50:14 -04:00
taoneill ff5318c8f6 War v1.7.2 release
Removed PREVIEW snapshot tag.
2012-06-23 17:27:47 -04:00
taoneill 41ecb512ed Unsafe/illegal enchantments are now supported
Closes gh-461. Closes gh-429. Items enchanted with Time the Enchanter to
high levels now get managed and persisted by War properly.
2012-06-23 17:08:45 -04:00
taoneill bdc8b4057c Fixed broken zonemaker command permissions.
Closes gh-501. Build 77 broke all zonemaker command while allowing
public access to /zonecfg -p. Sorry!
2012-06-23 10:43:49 -04:00
taoneill b6d1ea2c90 Highest priority for death event handler
Just to see if this can help @shankomaster's problem with missing
loadouts upon respawn.
2012-06-23 02:20:59 -04:00
taoneill 6304b39fc8 Everyone can /warcfg -p, /zonecfg -p, /teamcfg -p
Closes gh-499. Now all players have read access to the game rules and
settings. Awesome!
2012-06-23 02:12:52 -04:00
taoneill afa82ce13f Updated plugin.yml documentation.
Prettified the /warcfg, /zonecfg, /teamcfg and other usage outputs.
Removed duplication by using command aliases. Grouped War, warzone and
team settings together for more clarity. /setteam and /setteamflag now
have pretty colors.
2012-06-23 01:32:51 -04:00
taoneill 1b1c74ed26 Lobby and warhub clear a bit more air by default
Also tweaked how gates make space for the players to navigate around the
structure.
2012-06-22 23:05:06 -04:00
taoneill b2d0a5c355 Accidentally exiting a warzone != flag/cake cap
Closes gh-497. Before, getting warpped or dropping out of a warzone
could cause you to auto-cap the flag or the cake. Bad. Players now
simply drop their payload, get respawned and the structures get reset.
Bomb carriers are forced to drop their bomb as well.
2012-06-22 20:43:49 -04:00
taoneill 06d6ae9bdb Check minplayers/teams only upon respawn.
Closes gh-496. New can't-re-enter-spawn protection was conflicting with
the minplayers/minteams check that used to bring back everyone to spawn
as soon as the limit was hit. From now on, you will only be stopped from
exiting the spawn after your next death. This is how it probably should
have been implemented from the start - much less brutal when a player
leaves the match suddenly. :)
2012-06-22 19:53:53 -04:00
taoneill 9139f9df45 Merge pull request #494 from cmastudios/patch-3
Allow players in the same faction to PVP. Thanks @cmastudios!
2012-06-21 20:06:50 -07:00
Connor 6056ff0c87 Allow players in factions to PVP 2012-06-21 19:55:21 -05:00
taoneill 14d4efea9d Cake thief can now come back to spawn.
New can't-re-enter-spawn bump was preventing them from scoring. Oops!
2012-06-21 19:59:30 -04:00
taoneill 53aa9cda52 Nicer messages with words unbroken at end-of-line
Closes gh-493. Looks much better. Just had to drop an old ChatFixUtil
from the olden days before Bukkit at all that fancy end-of-word line
breaks built in. Should have done this much earlier. Thanks for
reminding me to remove this @cmastudios.
2012-06-21 19:51:14 -04:00
taoneill c6e98769e5 Let flag carrier into the spawn when we should
Broke this two commits ago.
2012-06-20 23:58:47 -04:00
taoneill 4835d0f37d Startup warning when War files take over 100MB
Temp files tend to accumulate rapidly if some zonemakers are
particularly trigger happy with /savezone. Added a warning. Should
probably add a real limit on number of oldversions that can be saved.
2012-06-20 22:56:08 -04:00
taoneill 7a90119c97 Spawn protection is back. Can't re-enter spawn.
- Players are now technically invincible while in spawn. Closes gh-492.
- More air cleared around warhub tp and moved the warhub sign by one
block.
2012-06-20 21:32:44 -04:00
taoneill b504b5b014 New playerloadoutasdefault:true/false setting
Closes gh-491. Players can now safely bring their own inventories in the
warzone. They still get it back after leaving, but now thei own items
can be used to replace the default loadout. You *need* to have a loadout
named "default" available in your warzone.
2012-06-19 23:00:37 -04:00
taoneill 520bac05da Less complicated file numbering system
Closes gh-486. There will still be duplicate numbers when old versions
are deleted, as the version only takes into account the number of old
versions in the /temp/oldversion/warzone-x/ folder.
2012-06-19 00:37:18 -04:00
taoneill 0557d94911 Logging code back in 2012-06-19 00:19:02 -04:00
taoneill a1634b8b94 Merge pull request #483 from cmastudios/patch-2
POM update. Couldn't compile with old one (spout changed their repo addr...
2012-06-18 21:17:56 -07:00
taoneill 2dc7d4aa75 Test build without custom War logger
For @shankomaster who is having trouble with crashes with the newest War
builds. This build removes the new War-specific file logger.
2012-06-18 23:42:14 -04:00
taoneill 60e4eafc13 Customizable warzone structure materials
Change flag, monument, bomb, cake and spawn look by typing "/zonecfg
material:<main/stand/light>" while holding the block of your choosing.
Complements the lobbymaterial and warhubmaterial settings.

Brought back synchronization.
2012-06-18 23:36:06 -04:00
Connor 623af5d16a POM update. Couldn't compile with old one (spout changed their repo address) 2012-06-18 18:36:16 -05:00
taoneill 9f657c4a59 Test build with no game-end synchronization
For @shankomaster. This has the newer features but no endgame lock
around player deaths and flag/cake/bomb thief movements.

I'm not sure I really want to remove this, since a lock shouldn't cost
much usually and I thought through the threadsafe logic so it would work
properly.
2012-06-18 19:24:01 -04:00
taoneill 6c33314288 Warhub and lobby materials settable by commands
First, make sure you have a block (or air) in you hand.  Then use
/warcfg warhubmaterial:<floor/outline/gate/light> or /zonecfg
lobbymaterial:<floor/outline/gate/light>.

This is from a previous commit but: when you have AIR in your hand and
you change the floor or the floor's outline, that tells War to leave the
user-build or natural original floor in place.

New and cool: setting down the warhub now only clears the blocks needed
for players to find the gates, letting you build a nice warhub that
won't get wiped. Lobbies now also clear only a small path for players
instead of the whole volume.
2012-06-18 13:30:02 -04:00
taoneill e80bdc9e2a Updated link to Jenkins in readme. 2012-06-18 02:53:28 -03:00
taoneill 4dfead7ec8 Players can't be trapped in spawn anymore
Closes gh-472. The periphery of opponents' spawns can't be built on. In
other words, all teams have a "no other team can build right next to my
spawn" protection 1 block wide all around their spawn. This should let
people exit the spawn with their loadout select, then use their items to
dig themselves out of any now-harmless trap.
2012-06-18 01:28:49 -04:00
taoneill c6b04faa55 Custom lobby materials + hub and lobby outline
Closes gh-63. Warhub and lobby materials can be customized. Warzones
take warhub materials as default. Customizable materials: floor, outline
(of floor - NEW), gate, light. Only changeable through the war.yml or
warzone-x.yml file.
2012-06-18 01:07:06 -04:00
taoneill 4bebb2d50e Customizable warhub floor/gate/light materials
Just changeable through the war.yml file for now, since it's a pretty
advanced option. Still missing warzone lobby materials.
2012-06-17 23:59:01 -04:00
taoneill 4867b8cf03 New readme file
Added a proper license file as well, about time.
2012-06-17 22:36:53 -04:00
taoneill 68b5ca755b Fixes in zone and team-specific loadout creation
Closes gh-480. When you add a new loadout to a warzone, you now inherit
the default loadouts automatically - they are copied from War's default
inventories. Similarly, when you add a new loadout to a team, the
warzone's (or War's default) loadouts are copied and the new loadout is
added to that collection. This was the intended behavior.
2012-06-17 19:05:20 -04:00
taoneill b7ae19a439 Make sure War log file gets created. 2012-06-17 01:53:12 -04:00
taoneill a258bd8995 Big changes. /renamezone fix, zone backups, logs.
Closes gh-444. Fixed hopelessly broken /renamezone command. Now making
backup copy of renamed and deleted warzone to temp folder. Also,
/savezone now makes backups of old versions before saving if the
keepoldzoneversion:true setting. No more will you have to suffer the
pain of a mistakenly overwritten warzone. Hurray! New standalone War
logger and log file in same temp folder. More logging added to every
command to make tracking down history easier.
2012-06-17 01:26:00 -04:00
cmastudios 380025f147 Closes #452. Enchantments are re-added to the item. 2012-06-16 16:16:14 -04:00
taoneill 1d6fdbe126 Inventory reset bug fix. Closes gh-436.
Closes gh-407. Closes gh-323. Inventory reset bug was due to the
combination of the respawn timer and a badly coded loadout-equip timed
job. The end-of-game events are now synchronized to prevent simultaneous
game-end and one game from bleeding into the other.
2012-06-16 15:53:06 -04:00
taoneill 894791215c Spawn protection now only when using respawntimer
Closes gh-469. CTF stalemates cause by buggy spawn protection are gone.
Woohoo!
2012-06-03 23:04:05 -04:00
taoneill af9d4db788 Synchronous game end inventory resets
Still trying to fix the inventory reset bug. :( Trying out Github for
Windows. :)
2012-05-29 23:18:03 -04:00
taoneill 7f36e6991f Attempt at fixing missing warzones bug. Seems that the Bukkit Yml writer finally properly lowercases each yml node around 1.2.3, which broke the warzone yml mapping since warzone names (which can be any case) are used as yml nodes. 2012-04-24 22:18:59 -04:00
taoneill ae190ed315 Zonemakers can't circumvent commandwhitelist anymore. Only war.admin perms lets you do that. Version v1.7.2-PREVEW. 2012-04-09 23:15:04 -04:00
taoneill 33117b9db0 War v1.7.1 release. Compatible with Craftbukkit 1.1-R6, 1.2.3, 1.2.4 and 1.2.5. 2012-04-07 01:05:38 -04:00
taoneill 1d47f79eca Hitting the bomb carrier could still make him explode blocks while unbreakable:true. From now on unbreakable:true means bomb carrier really can't make any damage. 2012-04-06 22:32:31 -04:00
taoneill 305b2454c7 Closes gh-406. The inventory reset fix seems to not have broken anything important - good. Fixed lobby disappearing with new /teamcfg and /zonecfg that dont reset the zone anymore. 2012-04-06 22:19:44 -04:00
taoneill 2c773710ba First attempt at fixing no-inv-reset/over-maxscore bug. When a battle or the game ends, extra simultaneous deaths or scorers shouldn't cause duplicate warzone resets anymore. Knock on wood, i.e. needs testing. Also, added RESETONCONFIGCHANGED setting that is false by default - i.e. /zonecfg and /teamcfg won't cause a zone reset automatically anymore. 2012-04-06 21:35:30 -04:00
taoneill 6b29226004 Reverting back to old bukkit dependencies in pom. 2012-04-01 12:45:48 -04:00
taoneill d0c1878c30 Reverting back to old mockito dependency in pom. 2012-04-01 12:42:08 -04:00
taoneill 2afc40fb00 Closes gh-426. Closes gh-341. Bomb carrier doesn't blow up if warzone is unbreakable:true. Helmets can now be part of loadout if blockheads:false. When realdeaths:true, players don't get -Use /leave to exit- message spam when dying anymore. 2012-04-01 12:38:07 -04:00
taoneill bdae9df6b7 Updated pom.xml dependencies to 1.2.4-R1.0. 2012-04-01 11:11:02 -04:00
taoneill 59b9b3078c Merge branch 'master' of github.com:taoneill/war 2012-04-01 10:57:21 -04:00
taoneill eea3af9c1c Closes gh-425. Block head restoration job shouldn't break anymore. Updated plugin.yml to reflect v1.7.1-PREVIEW version - sorry about confusion. 2012-04-01 10:56:51 -04:00
taoneill 5d9b654240 Merge pull request #424 from ryansch/on-player-interact-fix
Fixed a missing RIGHT_CLICK_AIR action.
2012-04-01 07:09:58 -07:00
Ryan Schlesinger 37f68d4716 Fixed a missing RIGHT_CLICK_AIR action. 2012-03-25 15:45:21 -07:00
taoneill fc03a0cf74 Closes gh-417. Potion effects are cleared properly again at warzone exit and at death - that part of the bukkit API is broken in 1.2.3-R0.1 and R0.2, at least. 2012-03-21 23:43:21 -04:00
taoneill f8e771c9e0 Compatibility fixes for 1.1-R6. War doesn't use any Craftbukkit or net.minecraft classes anymore. Removed getLogger override which was breaking Bukkit's calls to the plugin's logger accessor - weird. 2012-03-03 13:21:41 -05:00
taoneill 61d691c1dd Updated pom.xml to 1.1-R3. This is the War v1.7 release. 2012-02-01 21:54:56 -05:00
taoneill d7a6bf9e53 Little renaming of the Spout ui classes. 2012-01-29 21:31:54 -05:00
taoneill 9ea65c051f Changed version to War v1.7. 2012-01-29 12:15:14 -05:00
taoneill a4d8075ad1 Much less glitchy lobbies: proper handling of team adding, deleting and of autoassign mode switching. Win. 2012-01-29 11:58:08 -05:00
taoneill ea454e3027 Fixed War Spout feed and stats text not scaling with Spout settings (Small, Normal, Large, Auto). Much better now. 2012-01-29 11:28:31 -05:00
taoneill 4b69b14e10 Made potion effects less frequent when stealing flag or cake, because they got on my nerves. Wish I could disable the sound for an effect from the server. 2012-01-28 12:27:33 -05:00
taoneill a9c09c3f16 Closes gh-367. Using flint and steel on enemy spawn doesn't give you a fire block anymore. :) 2012-01-27 20:34:37 -05:00
taoneill a4a3ced0e5 Closes gh-348. Levels and exp are stored at warzone entry and restored at exit, like the rest of the player's state. 2012-01-26 23:18:49 -05:00
taoneill 668285ac97 Updated pom to Bukkit 1.1-R1, which broke the Events API again. Guess they never heard of backward compatibility. Oh well. 2012-01-26 20:40:12 -05:00
taoneill 13067f35ad Back to Bukkit 1.1-R1-SNAPSHOT until they publish to their repo, so I don't have to mvn-install it on my ci server - lazy. 2012-01-25 23:22:39 -05:00
taoneill 445aae7f8f Closes gh-344. Updated pom for Bukkit 1.1-R1. Fixed compatibility with Heroes and other plugins by introducing new config REALDEATHS. If you turn it on, there no longer fast respawns (i.e. the player actually dies, letting other plugins register the death). Now you can also turn off death messages with DEATHMESSAGES. Fixed bug in inventory checking job. 2012-01-25 23:17:34 -05:00
taoneill d027a53e02 First pass at REALDEATHS and DEATHMESSAGES config settings. Hopelessly broken, of course. :( 2012-01-25 00:30:11 -05:00
taoneill c54e893e41 Closes gh-364. Smoke effect for bomb thieves and potion effect for cake and flag thieves (with proper thief-team color). Also made thieves' hands get filled with their stolen item automatically to prevent them from picking up other items and from hiding their identity. 2012-01-24 02:24:16 -05:00
taoneill f06afb5aa3 My local craftbukkit got out of sync with the build server's. Re-adding event names until they get deprecated on the bukkit SNAPSHOT build. 2012-01-22 22:28:59 -05:00
taoneill ee7dab194a Just moving classes around again. 2012-01-22 22:05:34 -05:00
taoneill 9019b4f780 Closes gh-361. Closes gh-363. Finally fixed the stupid issue with maxscore being used as teamsize when on autoassign - it was staring me right in the face. Adjusted new Events API annotations. Prevented a mysterious NPE when a loadout config section fails to get created. 2012-01-22 17:36:22 -05:00
taoneill 4ffaadf3da Fixing the pom.xml so plugin.yml - which I moved a couple of commits ago - makes it into the final jar in the maven build. Still messing around with namespaces while everything is broken. 2012-01-20 23:01:43 -05:00
Thomas-Antoine O'Neill e8e2c0c472 Forgot to delete the rename-namespace files. 2012-01-20 21:28:19 -05:00
Thomas-Antoine O'Neill 06272803f1 Renamed namespaces for consistency moving forward. Sorry to everyone who's references to War are going to break because of this. It's for the greater good... the greater gooood. 2012-01-20 20:53:50 -05:00
Thomas-Antoine O'Neill bbdfef0ca6 Closes gh-358. Update for compatibility with the new Bukkit Events system (i.e. CB #1782+). 2012-01-20 20:40:30 -05:00
Thomas-Antoine O'Neill 4e1b5670a4 Closes gh-357. Bombs and cakes now get saved properly when there are no monuments in the zone. Autoedits to project and classpath for standalone build by m2eclipse. 2012-01-20 19:56:37 -05:00
taoneill 6ff3cbe0c3 Fixed NPE on PLAYER_INTERACT when player's hand is empty and still in spawn. 2012-01-18 17:48:41 -05:00
taoneill 1eed5ca366 Closes gh-355. Prevented use of items when still in spawn, including potions (which could be abused by switching between loadouts). 2012-01-17 23:36:49 -05:00
taoneill a86683a98a Bug hunting. When you get prevented from placing an item, you get item back in your hand. Actually preventing you from placing cake now. Resetting Bomb block if it gets exploded by nearby TNT. Preventing Bomb block ignition. Nerfed player-hit explosion of suicide bomber. Made spawn-hit explosion a bit bigger (same as player-hit). 2012-01-17 23:20:28 -05:00
taoneill 934292df88 Closes gh-353. Closes gh-354. Finally some new gameplay elements. Added Bomb and Cake structures. Use /setbomb <name>, /setcake <name>, /deletebomb and /deletecake. Grab the bomb and blow up your enemy's spawn for a point. Don't get touched or you blow up. Return the cake to your spawn to get a point and a replenished lifepool. 2012-01-16 23:57:59 -05:00
taoneill 940ad072d4 Using EnumMap since enum's hashCode isn't stable from one VM to another. Fixed ConcurrentModificationException when clearing SpoutPlugin widgets and players. 2012-01-16 18:07:06 -05:00
taoneill a610181954 Changed pom.xml references to 1.1-R1-SNAPSHOT until RB hits. 2012-01-15 22:34:56 -05:00
taoneill 92b949343c Fixed Spout-less server being broken at zone entry and exit. 2012-01-14 17:58:46 -05:00
taoneill 80fd939922 Corrected plugin.yml format to add PREVIEW tag. 2012-01-14 15:15:46 -05:00
taoneill 25f93ab26c Added PREVIEW tag to version until real release. 2012-01-14 13:50:35 -05:00
taoneill e53eb7965e Removed Permissions from dependencies since everything works just fine with SuperPerms API. Restoring Spout player title color upon leaving warzone. 2012-01-14 12:52:26 -05:00
taoneill 4d04f39e3b Updated pom.xml. Trying to fix jenkins build. 2012-01-14 11:19:09 -05:00
taoneill 6a452ebb8f Fixed Spout stats header alignment and font display in fullscreen. Made notifications and text stick longer because you can't re-read it through chat. Add 5 message limit in War message feed to counter large message inflows. 2012-01-12 22:41:52 -05:00
taoneill ad1c591acd Fixed NPE. Something's off in stats display reset at game-end, though. 2012-01-10 01:45:26 -05:00
taoneill 2745803050 Closes gh-280. (Even basic) Spout integration is so totally awesome. Thanks @SuperYoshi for pushing me into doing this. Just made it a bit more pretty with gradients in this rev. 2012-01-10 00:55:03 -05:00
taoneill 38c91b5623 Fixed War without Spout being broken. Made 'monument freed' notification use owner team wool block. 2012-01-09 23:44:40 -05:00
taoneill 25bbf5b185 Updating stats more often just like @SuperYoshi did originally during teams spawn reset. Tweaked message colors. 2012-01-09 00:21:02 -05:00
taoneill 2adb328115 Re-added Spout stats board in a more compact format, with messages now coming underneath the stats board at the top left of the screen. Added notification when flag is dropped. 2012-01-08 23:45:45 -05:00
taoneill 9ff98d0bbf Fixed mapping bug where FLAGMUSTBEHOME and LIFEPOOL would get mixed up, causing chaos. 2012-01-08 21:02:57 -05:00
taoneill fb7ceaec55 Merge pull request #350 from cmastudios/master
Added spout and its repo to pom.xml
2012-01-08 17:36:29 -08:00
taoneill 0d7f2feef4 Added Spout notifications for battle and match end as well as monument captures (and tweaked the flag capture ones). Turns out ChatColors work great OOTB with GenericLabel - yay. The War message feed at top left + notifications look awesome. 2012-01-08 20:34:15 -05:00
Connor M 576993f97e Added spout and its repo 2012-01-07 17:09:54 -06:00
taoneill 5c3fca5001 Playing around with Spoutcraft notifications at the top left of the screen, so that War messages don't spam the chat anymore. 2012-01-07 17:26:27 -05:00
taoneill 6eeb5be673 Cleared team color in Spout player name display when leaving warzone. 2012-01-07 12:30:03 -05:00
taoneill 589d197bf1 Server reload isn't broken anymore: now removing Spout widgets at Spout plugin disable-time, since Spout was already gone by the time War was getting disabled and tried to remove them. 2012-01-07 00:36:29 -05:00
taoneill 1bae53670e Fixed Yaml loader and another ton of bugs related to cascading configs and the /teamcfg command. Also tweaked /zonecfg so that you can change another warzone's config while standing in another warzone (the one you were in always took over). Made printing of configs more pretty and now printing loadouts. 2012-01-07 00:20:02 -05:00
taoneill 143afa4473 Closes gh-6. Closes gh-39. Team specific settings. New YAML file format and working converter. You can delete a setting to restore config inheritance with, for example, /zonecfg delete:maxscore. New colors for /war-zone-teamcfg. Fixed a bunch of bugs introduced by mega-changes - there are probably a few more lurking around. 2012-01-06 02:01:08 -05:00
taoneill 983e90ca38 Huge (albiet still broken) changes. - Switched to Yaml config (stupid API). - Added team-specific settings. - Reworked entire configuration architechture and mechanic. War holds the War settings, the warzones defaults and the team defaults. Warzones hold their own config items which override the War default if they please (instead of being copied). Team settings add another level of defaults (unless specified, team settings are taken from the Warzone team defaults, or if absent, from the War team defaults). - Added /teamcfg command. - No more difference between default/extra loadouts. 2012-01-05 01:17:02 -05:00
taoneill dd6beb3b82 Fixed disablebuildmessage setting which broke block placement protection by buildinzonesonly and didn't work for block breaking. 2012-01-03 22:07:18 -05:00
taoneill e1c6397f22 Removed 'Equiped x loadout' message at every respawn. Message only appears at first respawn or during a sneak-toggle. 2011-12-27 18:32:14 -05:00
taoneill 0b1d428266 Fixed respawn timer and made it changeable through /zonecfg and /warcfg. 2011-12-27 17:51:34 -05:00
taoneill bd872be244 Fixing merge conflicts with pull request from @Superyoshi. Mostly untested. Isolated Spout code behind checks for spout so War doesn't completely fall over if Spout isn't available on the server. 2011-12-27 16:29:39 -05:00
taoneill b196618515 Closes gh-340. Doors should now reset properly (no more glass instead of doors). 2011-12-21 11:18:18 -05:00
taoneill b6f9afb745 Fixed always-on war.pvp permission for War admins in GroupManager/Permissions context by adding specific war.admin permission node and by removing war.pvp from the children. Also removed war.warp from the children. 2011-12-20 15:28:12 -05:00
taoneill f7e0b73465 Now checking if War is laoded in entity_death. 2011-12-20 02:34:39 -05:00
taoneill b057cac73d Closes gh-338. Deaths that weren't prevented properly (e.g. potion of harming) by EntityDamage are now better handled. 2011-12-20 02:32:58 -05:00
taoneill a532bbaf93 Cleared logging code. 2011-12-20 02:00:46 -05:00
taoneill 0cf0024e55 Closes gh-326. Potion effects are cleared at respawn and saved with player state so, for example, you get re-poisonned when you exit a warzone if you entered with the effect. Thanks @mahoutsukaii for the MobEffect trick. 2011-12-20 01:59:13 -05:00
taoneill 007344a63e Updated pom.xml for Craftbukkit RB 1597. Corrected permissions bug where War admins couldn't change the corners of other zonemakers' zones. 2011-12-20 00:51:37 -05:00
taoneill 60356e56ab Closes gh-337. Players now respawn with the loadout they selected at their last respawn. 2011-12-20 00:16:03 -05:00
taoneill 177543ad20 Closes gh-336. Enchanted items can now be reliably saved in loadouts and chests/dispensers. Consolidated inventory string building and parsing. 2011-12-19 23:48:09 -05:00
taoneill a37766d31b Closes gh-254. Closes gh-321. Closes gh-312. Closes gh-322. Truns out I wasn't saving inventory item damge or data values, which led to potions not working and items sometimes breaking on first use randomly. Instant damage (splash harming) potions now work properly when you are hitting yourself at the same time with splash damage. Self-inflicted damage is now properly recorded. Fixed one or two NPEs. 2011-12-19 16:01:33 -05:00
Chris Sp cd158cc9a9 Spout Integration! 2011-12-11 20:32:53 +01:00
taoneill ccd6649d06 Closes gh-316. Warzone lobbies can now be moved to another world than their warzone's. Bit tricky this lobby resetting... 2011-12-07 23:40:30 -05:00
taoneill 4996a7457d Closes gh-315. Warhub can now be moved from one world to another properly. 2011-12-07 22:26:05 -05:00
taoneill 1325611775 Updated pom.xml to new Bukkit/Craftbukkit version numbers. 2011-12-07 21:48:42 -05:00
taoneill 1b9f06e3ca Closes gh-300. Closes gh-314. Fixed NPE in explosion handling. Lobby doesn't flash at game end anymore (no more dropping to the ground). Meddled with monument healing - it's still wonky although at least it wont give max hp all the time anymore. Added error handling of bad team name. 2011-12-06 20:58:33 -05:00
Chris Sp d9701b910d Piston Exploit Fix, and removal of deprecated functions
- Fixed an exploit where it would be possible to move the flag with pistons, rendering it unstealable. You cannot move any important blocks with pistons now, and can't push them into protected zones. Reported here: http://forums.bukkit.org/threads/mech-fun-war-v1-6-de-gaulle-final-minecraft-tdm-ctf-1337.250/page-67#post-831054 Special thanks to TerXIII!
- Changed all calls of the deprecated getRelative() to getRelative()
2011-12-04 12:40:10 +01:00
Chris Sp 1061c24c5b Added respawn timer and immunity, fixe join loadout, fixed a bug
- You will not get the loadout as soon you join
- Fixed a bug where you would be kicked out of the zone if you walk into the glass walls above a team gate on a block layer equal with the roof of the gate
- Made respawn timer configurable ("respawntimer", defaults to 10)
- Can't attack/be attacked while respawning (this is already done by the spawn protection already, so this is something for an upcoming feature)
2011-12-02 17:44:05 +01:00
Chris Sp 856da8cc77 Close gh-282. Players cannot leave spawn for 10 seconds after respawning.
- [gh-282] Added a "Respawn" timer, players cannot leave spawn while it is
  active. Loadout will be given to the player at the end of the timer as a
  visual cue.
- TODO: configurable timer, cannot attack/be attacked while respawning
2011-12-02 00:17:10 +01:00
Chris Sp ff04f24a85 Removed "debug" message 2011-12-01 21:27:23 +01:00
chris 9f828fe790 Closes gh-304. Adds "flagmustbehome" setting for warzones.
- Fixed a mistake where changing "pvpinzonesonly" would display "flagpointsonly changed to..." (and the respective value)
- [gh-304] Added a setting for the plugin to not show the "No Building" message ("disablebuildmessage", like "disablepvpmessage", defaults to false). Untested.
- Added a setting for warzones to allow flag capture when the flag is not home ("flagmustbehome", defaults to true)
2011-12-01 19:47:29 +01:00
taoneill 95308c8bc9 Closes gh-305. Added maxzones setting to prevent zonesmakers from making too many zones. Default is 12 - hopefully not many servers have that many warzones. 2011-10-23 14:45:13 -04:00
taoneill 82c8397547 Closes gh-113. Zonemakers are now exclusive authors of their zones. New author setting for warzones. E.g. /zonecfg author:tommytony,someotherguy or /zonecfg deleteauthor:tommytony,someotherguy. New war.zonemaker permission for zonemakers. The war.* permission is now meant for War admins who can edit all zones and who can access server settings and warhub placement commands. Old warzones have no author, which means all zonemakers can edit it. Added nice colors to /zonecfg -p and /warcfg print. 2011-10-16 14:13:28 -04:00
taoneill 8913f7ae5c Closes gh-298. Adding an extra loadout doesn't cause an error on the first attemp anymore. 2011-10-16 10:16:45 -04:00
taoneill d327c34b10 Remove stray logging code and cancel SATIATED RegainReason as well when nohunger is on. 2011-10-01 15:35:06 -04:00
taoneill 73f7dbe8a2 Updated docs in plugin.yml for v1.6 final release. 2011-10-01 14:36:20 -04:00
taoneill 9f9d6ba7c1 Closes gh-196. Closes gh-295. Closes gh-296. Closes gh-297. Players can't drop items inside zones when nodrops is true. For 1.8, added nohunger setting that prevents food regen and saturation setting (0-20) that controls how fast your food bar starts depleting. 0 saturation means your bar starts depleting right away. Instead of teleporting back to spawn, people that wander out of zone are bumped back in. 2011-10-01 13:57:12 -04:00
taoneill 06427445b7 Fixed NPE on PLAYER_SNEAK. 2011-09-30 23:24:09 -04:00
taoneill 00c6397df4 Closes gh-260. Added tntinzonesonly setting. Re-made explosion protection to let everything blow up except important stuff. Warhub, lobbies, spawns, flags and zone walls are protected. Stuff that is near the warzone wall but outside gets rolled back (because the explosion was inside the warzone, those outside blocks really explode, but get rolled back with a new fancy DeferredBlockResetJob which handles chests et al. on top of signs). If tntinzonesonly is on, tnt explosions outside warzones are cancelled (this makes sure any projected tnt block doesn't cause damage). Only bad thing here is that tntinzonesonly is server-wide, not world specific. Also, explosion handling is much more heavy. 2011-09-30 22:35:34 -04:00
taoneill 0811431b0a Closes gh-73. Closes gh-292. Easy spleef with two new settings: pvpinzone (default true) and instabreak (default false). Former off, latter on makes for spleef. Killing by arrows now can't be done through spawn protection. I got carried away and prettied up the kill messages. Also added check in mappers so that default values don't get overridden by 0 or false from the config file reader. 2011-09-26 22:08:34 -04:00
taoneill 599e6b11d5 Closes gh-289. Closes gh-290. Along with inventory, now saving full player state: health, foodLevel, saturation, exhaustion and gamemode. Switching creative people to survival. Full state is restored when player leaves the zone. 2011-09-24 14:14:40 -04:00
taoneill 1266462635 Closes gh-262. 98% better door resets. Iron and wooden door should reset a lot more reliably now that I'm setting the proper block data in all but tiny edge cases. 2011-09-20 00:59:35 -04:00
taoneill f947f204b9 Closes gh-46. Added long missing /deleteteamflag command. Requested since forever (February 12th, actually). 2011-09-19 23:05:29 -04:00
taoneill 23893c60da Merging /renameZone. Maybe I would've liked this better under /zonecfg to keep the command count as low as possible, but this will do. There's too many settings already anyway. I'm keeping plugin.yml in classes because it lets me build in a snap in eclipse instead of through mvn. I know: it's lame. 2011-09-19 22:19:38 -04:00
taoneill 095b073051 Merge branch 'classes' 2011-09-18 16:19:03 -04:00
taoneill dc4b770aaa Closes gh-17. (Wow, War finally has classes) You can now delete extra loadouts. Can't shoot arrows when still standing inside spawn (to prevent arrow spam by class switchers). 2011-09-18 16:18:55 -04:00
taoneill 9cc39281d7 Closes gh-287. Closes gh-288. flagpoints only setting now properly saved. autoassign:true setting at War level doesn't override the warzone-specific settings anymore. Can't drop items while still in spawn. 2011-09-18 15:35:43 -04:00
taoneill 66df711006 Closes gh-284. Now attributing arrow kills to the shooter. 2011-09-17 00:39:25 -04:00
taoneill 48311e4d95 Working extraLoadouts/classes system. Do /zonecfg loadout:warrior, etc. Simply sneak while in spawn to switch between the available loadouts/classes. 2011-09-17 00:21:26 -04:00
taoneill 1ba2fa2e06 Missing extraLoadouts stuff. Kind of broken. Need more testing. 2011-09-16 00:27:04 -04:00
taoneill c6a8bc555c First pass at extraLoadouts/class system. Needs testing. 2011-09-16 00:07:07 -04:00
taoneill e0a2d6092b Closes gh-271. Added SuperPerms/PermissionsBukkit support, and everything still works properly when no Perms plugin is present, thanks to SuperPerms/built-in perms. Made /warcfg give feedback as well. 2011-09-15 00:09:39 -04:00
taoneill 5abdf43986 Closes gh-96. Two new settings. Players can leave the spawn on when there is at least minplayers in at least minteams. E.g. with minplayer:1 and minteams:1 no one gets stuck in spawn; with minplayers:1 and minteams:2 you need at least one player on at least two separate teams (1+1=2 players total). Also, updating with savezone, zonecfg or warcfg now prompts you back to confirm your changes. 2011-09-14 00:18:06 -04:00
taoneill b62e8ffd53 Closes gh-267. Glass walls can be turned off with glasswalls:off. Clearing the latest locations at unload - hello big leak. 2011-09-13 00:13:59 -04:00
taoneill 3277491c64 Merge pull request #286 from taoneill/flagPointsOnly
New flagpointsonly setting for true CTF.
2011-09-12 20:22:05 -07:00
taoneill bceda1932e Added missing parts for flagpointsonly setting. 2011-09-12 23:20:11 -04:00
taoneill 880f7ce528 Quick and dirty attempt to reduce hits on PLAYER_MOVE. Beginnings of a glasswalls setting. 2011-09-12 22:52:08 -04:00
Tim Düsterhus 0518fd0be4 Adding flagPoints only setting
When this setting is true you can only score via flagreturn
Closes gh-283
2011-09-10 18:06:17 +02:00
Tim Düsterhus 8788c9c4b6 Code-Style 2011-09-10 17:49:12 +02:00
Tim Düsterhus bcfa109944 HelmetProtectionTask Code-Format
Return directly, so we have to indent one time less
2011-09-10 17:44:00 +02:00
Tim Düsterhus 1e8b1b8193 Removing unused imports 2011-09-10 17:43:00 +02:00
taoneill f20b275ba9 Closes gh-226. Respawn now stops fire properly. 2011-09-09 23:54:32 -04:00
taoneill 25e034965d Closes gh-242. If you remove your blockhead/helmet, it gets reset, but you can't carry more than one. Incremented preview number. 2011-09-09 23:33:28 -04:00
taoneill cb9a34f5bd Closes gh-272. Made flagreturn into an enum. Adding missing flag capture mode tidbits (setting wasn't being saved, made flag capture broadcast reflect the current mode). 2011-09-06 21:29:02 -04:00
Tim Düsterhus c7af5843fb Removing merge boundaries 2011-09-01 19:12:14 +02:00
taoneill e8776d3d74 Closes gh-277. Resolving conflicts while merging Tim's realEnums. 2011-08-31 20:20:32 -04:00
taoneill fa2be3d357 Resolving conflicts while merging Tim's printConfig. 2011-08-31 20:14:00 -04:00
taoneill 3b0518ece0 Resolving conflicts while merging Tim's style cleanup. 2011-08-31 20:11:35 -04:00
taoneill aeeb458408 Merge pull request #278 from taoneill/helmetProtection
Closes gh-242. Adding task to protect the helmet
2011-08-31 17:00:20 -07:00
taoneill 73e29c2025 Merge pull request #276 from taoneill/clearDrops
Closes gh-269. Removing drops at initializing
2011-08-31 16:57:37 -07:00
taoneill 3e452e9e21 Merge pull request #275 from taoneill/flagReturn
Closing gh-272 Implemented a way to specify how to return a flag
2011-08-31 16:55:11 -07:00
Tim Düsterhus 6871c76a70 Adding task to protect the helmet 2011-08-26 23:17:51 +02:00
Tim Düsterhus 082d89ec08 Using real enums here 2011-08-26 23:12:36 +02:00
Tim Düsterhus 2c25017b40 Removing drops at initializing
Closes gh-269
2011-08-21 23:00:03 +02:00
Tim Düsterhus 49376848ff Closing gh-272 Implemented a way to specify how to return a flag 2011-08-21 22:34:17 +02:00
Tim Düsterhus 174126209b Forcing the code style we agreed on
- Trimming whitespace
- Using qualifier whenever possible
- Space between if/for/while/switch and (
2011-08-14 13:19:22 +02:00
Tim Düsterhus e9f56967cb A switch is more nice here 2011-08-14 13:07:25 +02:00
Tim Düsterhus 5f0bc9f2b8 Merge branch 'javaDoc' 2011-08-14 12:57:58 +02:00
Tim Düsterhus 0019e7e107 JavaDoc for commands and War 2011-08-14 12:57:16 +02:00
Tim Düsterhus e1b895a966 We don't have to invent the wheel twice 2011-08-13 19:58:54 +02:00
Tim Düsterhus ae13d93da1 Removed unused import 2011-08-13 19:30:24 +02:00
Tim Düsterhus f013c209a8 Removed some pieces left from refactor 2011-08-13 19:29:42 +02:00
Tim Düsterhus 44df6a3f62 Adding Renamezone command
Closes gh-43
2011-08-13 18:56:41 +02:00
Tim Düsterhus 7e6a2988a6 Removed unused var, "corrected" if 2011-08-13 18:12:48 +02:00
taoneill 7fef7c9649 Removed spammy forgotten logging code when pvpinzonesonly:off. War v1.6 PREVIEW 5. 2011-08-08 23:00:18 -04:00
taoneill 66b4af4d1a Fixed broken setteamflag. PREVIEW 4. 2011-08-07 21:49:34 -04:00
taoneill 8fcd24da2c Fixed load/unload re-registering listeners. This is War v1.6 PREVIEW 3. 2011-08-07 17:37:55 -04:00
taoneill f56c5571dd Added '/war leave' to zone join message so that even people with HeroChat get some guidance on how to leave. 2011-08-07 16:28:46 -04:00
taoneill 27584c51bb Fixed pvp being broken. Tim's refactor prevented attackers from being registered, messing up all of the damage checks. 2011-08-07 16:20:38 -04:00
taoneill 5dcaac9351 Added -p or print option to zonecfg and warcfg. Ex: /zonecfg test -p autoassign:true, /warcfg print autoassign:false, /zonecfg -p. Trying to nail down pvp issue and I was dying for this. 2011-08-07 13:27:50 -04:00
taoneill ec35b6088a Added /savezone and /zonecfg commands that work from outside the zone. Better matching to support exact matches when looking for a warzone by name. Invisible spawn setting can be set as default spawn style now. Rallypoint stays with /warcfg. Whew. 2011-08-06 19:04:18 -04:00
taoneill 6dfb485ec2 Fixed setzonelobby not working for detaching lobbies: copy-pasta = bad. Hooked up warhub command. 2011-08-06 17:00:51 -04:00
taoneill 05b827d265 Changed command handling so that we print the command usage string ourselves. Cleaned up plugin.yml so usage help doesn't look awful. Brought back 'bad' messages formatted in red which where torn out by Tim. Added warning when console tries to use player-only command. Now matching the start of the name of a warzone instead of the exact name, because that's how it worked and how it should continue to work. 2011-08-06 16:14:21 -04:00
Tim Düsterhus 8891b97a9d Documentation 2011-07-28 18:54:53 +02:00
Tim Düsterhus 9dae88a5fc Updated plugin.yml 2011-07-28 16:43:02 +02:00
Tim Düsterhus 5d19aec2b3 Bugfix 2011-07-28 16:38:34 +02:00
Tim Düsterhus 22e79c51f4 Removed the dropLootonDeath member 2011-07-28 14:26:37 +02:00
Tim Düsterhus b303e8e540 Moved getters / setters to the end of class 2011-07-28 14:22:49 +02:00
Tim Düsterhus 00e8349b40 Adding SetZoneLobbyCommand 2011-07-28 14:11:06 +02:00
Tim Düsterhus ef75e5a323 Adding ZoneMakerCommand
Everything else needed refactoring because of this
2011-07-28 13:56:34 +02:00
Tim Düsterhus a0c8e1eb7e Adding SetZoneCommand 2011-07-28 13:28:24 +02:00
Tim Düsterhus d59dfd09e1 Code-Cleanup 2011-07-28 13:18:09 +02:00
Tim Düsterhus 8f6c895d05 Merge branch 'master' into commandHandler 2011-07-28 13:08:35 +02:00
Tim Düsterhus 14050f11d9 Using proper camelcase now :) 2011-07-28 13:05:37 +02:00
taoneill af381857b7 Fixed zonemakers string being saved as command whitelist string. 2011-07-27 21:17:05 -04:00
Tim Düsterhus be469fc663 Adding SetwarconfigCommand 2011-07-27 22:55:13 +02:00
Tim Düsterhus 65aff76af1 Added Setteam, setteamflag and setmonument command 2011-07-27 22:43:33 +02:00
Tim Düsterhus 15c3fadbb3 Validate argument-count 2011-07-27 22:43:22 +02:00
Tim Düsterhus bc77ce5892 Bugfixes 2011-07-27 22:23:10 +02:00
Tim Düsterhus 84d4f35c2f DeleteteamCommand 2011-07-27 22:21:58 +02:00
Tim Düsterhus 2c8498fec4 Adding DeletemonumentCommand 2011-07-27 22:19:05 +02:00
Tim Düsterhus 4a26f437ba Adding Setwarhub command 2011-07-27 22:13:37 +02:00
Tim Düsterhus bb300cf372 Adding Nextbattle command 2011-07-27 22:06:27 +02:00
Tim Düsterhus 45716af6b8 More commands :) 2011-07-27 22:01:27 +02:00
Tim Düsterhus 736f270a4a Use this.msg 2011-07-27 21:14:26 +02:00
Tim Düsterhus 50ebc9ad0c Why was bin in repo?!
General reorganizin
2011-07-27 21:10:05 +02:00
Tim Düsterhus f743ddeb15 Updated plugin.yml 2011-07-27 20:11:46 +02:00
Tim Düsterhus 38bcafae01 Removed AbstractWarzoneCommand and moved methods into War 2011-07-27 17:34:56 +02:00
Tim Düsterhus 92bd84da75 Some bugfixes 2011-07-27 17:34:56 +02:00
Tim Düsterhus b1724b3fe3 Added Warhub Command 2011-07-27 17:34:56 +02:00
Tim Düsterhus 7b838272ae Added TeamCommand 2011-07-27 17:34:56 +02:00
Tim Düsterhus 135d1856cc Added Leave-Command 2011-07-27 17:34:56 +02:00
Tim Düsterhus 42d4491b2e Some changes to join-command 2011-07-27 17:34:56 +02:00
Tim Düsterhus 6206df0c41 Implemented JoinCommand 2011-07-27 17:34:55 +02:00
Tim Düsterhus 554335b6bd Half implementation of /teams 2011-07-27 17:34:55 +02:00
Tim Düsterhus 1bf770d340 Added Warzone-Command 2011-07-27 17:34:55 +02:00
Tim Düsterhus a1f1b65d6e First implemented command 2011-07-27 17:34:55 +02:00
Tim Düsterhus 5565024a7c Some more change 2011-07-27 17:34:55 +02:00
Tim Düsterhus d0c2cc6078 First pieces of CommandHandler 2011-07-27 17:34:55 +02:00
Tim Düsterhus e7d8a33d3b Found the issue of the NPEs, so reverting Tommys revert, sorry, i hope you won't kill me for that :)
This one was seriously tested before, every function of War
2011-07-27 15:06:51 +02:00
Tim Düsterhus af3e0f08b3 Revert "Reverting e9193565f3 (the War singleton) because it caused unpredictable behavior. For example, doubly nested scheduler calls would cause NPEs when accessing the somehow null singleton. Sorry Tim."
This reverts commit 797ca9246b.
2011-07-27 15:04:16 +02:00
taoneill 797ca9246b Reverting e9193565f3 (the War singleton) because it caused unpredictable behavior. For example, doubly nested scheduler calls would cause NPEs when accessing the somehow null singleton. Sorry Tim. 2011-07-17 20:36:44 -04:00
taoneill 354955c04e Fix for uninitialized War singleton when using reload when switching over to new War version. 2011-07-17 19:42:20 -04:00
taoneill b1c09b564e No more portal blocks set in warhub. Crazy, this has been in forever and I never saw the portal blocks come up on my server. But on some servers they did and caused problems. Weird. 2011-07-17 19:26:43 -04:00
taoneill b205feb937 Damn, I thought I'd pulled from origin. Oh well, fixing pull merge. 2011-07-17 19:23:03 -04:00
taoneill 423304bb9d Closes gh-198. Auto-assign gates now have the proper colors. Fixed warhub orientation not being applied to player warp location. Using the autoassign setting with lots of team now makes sure the lobby won't be wider than for one team. 2011-07-17 19:16:28 -04:00
Tim Düsterhus e9193565f3 Moved War out of Parameter but into a kind of Singleton 2011-07-17 11:06:38 +02:00
Tim Düsterhus 57f81479fe Cleanup of War class 2011-07-17 10:59:31 +02:00
Tim Düsterhus 38b93ce16d Removing unused wars 2011-07-17 10:59:31 +02:00
Tim Düsterhus ba1a0fef3a Some javaDoc 2011-07-17 10:59:31 +02:00
taoneill 0e48e6539f Closes gh-250. Death by TNT and by dispenser now properly registered. 2011-07-16 19:30:07 -04:00
taoneill b910d9e640 Closes gh-243. Added basic kill/death messages. Colored team player names in War chatter. 2011-07-16 18:55:15 -04:00
taoneill 5a03b6c50d Merge branch 'warhub' 2011-07-16 17:56:36 -04:00
taoneill 54ab0d72f3 Closes gh-26. Warhub orientation can now be selected. 2011-07-16 17:55:40 -04:00
Tim Düsterhus 4c561a79dc Merge branch 'master' of github.com:taoneill/war 2011-07-16 23:25:36 +02:00
Tim Düsterhus a00081ace7 Updated commands in plugin.yml 2011-07-16 23:25:00 +02:00
taoneill e03365cff6 Closes gh-244. Changing spawn style doesn't mess up the surroundings anymore. 2011-07-16 16:38:33 -04:00
Tim Düsterhus 654841c81d Implemented command whitelist
Closes #80
2011-07-16 22:03:11 +02:00
Tim Düsterhus 6361e4e92e Removed the long unneeded comment 2011-07-16 20:21:50 +02:00
Tim Düsterhus 47adca43c4 removed the hard parameter of resetzone 2011-07-16 20:10:46 +02:00
taoneill 3c3a172de4 Merge branch 'fruehjahrsputz' of github.com:taoneill/war into tim 2011-07-16 13:54:33 -04:00
taoneill 66d9aaddc5 Merge remote branch 'remotes/origin/fruehjahrsputz' into tim 2011-07-16 13:45:57 -04:00
Tim Düsterhus 2edcb2d302 More reformatting 2011-07-16 19:38:28 +02:00
Tim Düsterhus 1d9dcb8a00 Added { } around single returns too 2011-07-16 19:12:05 +02:00
Tim Düsterhus 88b2e5051d Removing trailing whitespace
Adding this everywhere
Adding annotations
Use the block-style for if and consorts
2011-07-16 19:07:00 +02:00
Tim Düsterhus ba30e6ca42 if( -> if (
for( -> for (
2011-07-16 19:04:02 +02:00
taoneill 0132699d0e Merge pull request #249 from Evil-Code/opsAreZonemakers
Improved code a bit :)
2011-07-16 09:41:49 -07:00
Tim Düsterhus 41b84280c8 Improved code a bit :) 2011-07-16 18:34:43 +02:00
taoneill ccf78bd951 Closes gh-189. Closes gh-245. Closes gh-248. New on/off settings for /warcfg and /zonecfg: resetOnEmpty, resetOnLoad, resetOnUnload. Use resetonempty to for a warzone reset when the last player leaves. All default to false. Nice thing I should've done from the start: Op is zonemaker by default. 2011-07-16 12:27:13 -04:00
taoneill f4c1eca815 Closes gh-238. Lobbies are back after /reload or startup even if you don't have a warhub. 2011-07-16 11:35:37 -04:00
taoneill 4447cb8344 Closes gh-132. Added war.pvp permission, which works like war.build to override the pvpinzonesonly setting. Added disablePvpMessage to /warcfg named parameters. 2011-07-16 10:57:36 -04:00
taoneill 067dffb3a1 Merge branch 'tim' 2011-07-14 19:55:56 -04:00
taoneill daaa3ba7c0 Fixing merge of PVP message disabling. 2011-07-14 19:54:22 -04:00
taoneill f211d43689 Merge remote branch 'Evil-Code/resetInventoryOnZoneDelete' into tim 2011-07-14 19:52:39 -04:00
taoneill 311a5ea4e8 Merge remote branch 'Evil-Code/fixMonumentHeal' into tim 2011-07-14 19:52:29 -04:00
taoneill 6bf848967e Merge pull request #232 from Evil-Code/master
General cleanup.

You are awesome Tim, and I am messy. Thanks.
2011-07-14 16:45:24 -07:00
TimWolla 0869d30911 Fixed the saving of the monument-heal 2011-07-11 17:51:44 +02:00
TimWolla bd6d02ba76 Uncancels damage event first (Disabling of /god) 2011-07-10 18:21:12 +02:00
TimWolla 6c0212d405 General cleanup (Removed unneeded code) 2011-07-10 14:51:04 +02:00
TimWolla 15d4497c5e Removed the SY as they are worthless now 2011-07-10 14:36:56 +02:00
TimWolla cbf11a704e Reset the inventory on zone delete 2011-07-08 22:43:37 +02:00
TimWolla d57d181f68 PVP Message can now be disabled
Closes https://github.com/taoneill/war/issues/138
2011-07-08 22:35:47 +02:00
TimWolla 84452d6654 Maven automatically executes the tests now 2011-07-08 22:35:04 +02:00
TimWolla 771547f622 Added missing dependencies 2011-07-08 22:29:40 +02:00
TimWolla c2f027b7b2 Removed random whitespace and the EOF 2011-07-08 22:19:01 +02:00
TimWolla 2f22b039a9 Updated version 2011-07-08 22:04:52 +02:00
taoneill 06653e6633 Closes gh-227. Emtpy chests and dispenser don't crash teh zone reset (or the server) anymore. Sorry. 2011-07-03 16:42:18 -04:00
taoneill 6929b81dc4 Closes gh-225. Finally compatible with RB935 with PLAYER_MOVE changes that prevent teleport loops that broke the plugin from CB888 on. Now only using event.setTo(). Adjusted some messages. 2011-07-03 01:11:30 -04:00
taoneill 5bad6a26cc Merge branch 'master' of github.com:taoneill/war 2011-07-02 22:45:21 -04:00
taoneill 22239e712e Closes gh-44. Closes gh-153. Closes gh-120. Integrated more of Tim Wolla's changes: invisible spawn setting, flag carriers not protected in spawns anymore to avoid stalemates, warzones can be deleted by name. 2011-07-02 22:44:24 -04:00
taoneill e3918180fc Merge branch 'tim' 2011-07-02 22:40:54 -04:00
taoneill 9f8e3ce575 Merge branch 'master' of https://github.com/Evil-Code/war into tim 2011-07-02 22:40:07 -04:00
taoneill 9c78c0787d Merge pull request #206 from Evil-Code/6fa2d9113
Thieves can also be attacked in spawn
2011-07-02 19:33:52 -07:00
taoneill 4d12279ca7 Closes gh-223. New zone file format. Reduced RAM usage for resets. Conversion happens during the first reset. Also, zones are not reset at startup or shutdown anymore (may add new setting for that). 2011-07-02 22:23:31 -04:00
taoneill 7fae2a22ff Zones now save and reset to-from disk only. This not giving me the boost I hoped for though. Nuts. 2011-06-05 11:06:59 -04:00
taoneill ab576e09da Merge branch 'perms' into perf 2011-06-05 00:59:39 -04:00
taoneill 1975cce13b Closes gh-217. Now building against Permissions. Tested with GroupManager and Permissions 3.1.4. 2011-06-05 00:58:27 -04:00
taoneill 5b1ec9d994 First draft of new no-blocks-in-memory zone volumes. Also changed how magic glass walls work. This is going to be so broken. 2011-06-04 23:59:41 -04:00
TimWolla aaef9f9915 Implemented invisible spawn-style
Closes https://github.com/taoneill/war/issues/153
2011-05-23 18:41:28 +02:00
TimWolla 55b5ecfdbf Closes https://github.com/taoneill/war/issues/44, warzones can be deleted by name now 2011-05-23 18:22:33 +02:00
TimWolla 6fa2d91130 Thieves can also be attacked in spawn 2011-05-23 17:47:18 +02:00
taoneill dbf5995337 Integrated TimWolla's changes. Commented out the health-regen hook stuff. 2011-05-22 22:49:36 -04:00
TimWolla f475aa0fc9 Fixed indentation https://github.com/taoneill/war/issues/191 2011-05-22 22:53:20 +02:00
TimWolla 338e8eb338 Implemented https://github.com/taoneill/war/issues/197 2011-05-22 22:45:14 +02:00
TimWolla 9e7ec98789 Finished regain-health-prevention 2011-05-22 22:34:18 +02:00
TimWolla 7cafc2dde5 Merge git://github.com/taoneill/war 2011-05-22 22:19:41 +02:00
TimWolla daa2431362 Fixed pom.xml, added targets to gitignore. Implemented first pieces of onregainhealth 2011-05-22 22:19:01 +02:00
taoneill ad85404786 Oops. This is War v1.5.1. You can create zones now, at least. 2011-05-22 13:59:53 -04:00
taoneill 297ac1e460 Closes gh-188. Closes gh-192. Closes gh-193. It seems I fixed the right-click-itme-disappear bug earlier. Updated /join usage. Added /zm as alias for /zonemaker. This is War v1.5. 2011-05-21 10:53:10 -04:00
taoneill e1417811cf Closes gh-162. Lobby can now be detached from warzone with /setzonelobby zoneName. War v1.5 is almost ready. 2011-05-20 17:46:13 -04:00
taoneill c5290030bf Closes gh-190. Closes gh-107. /reload works now. Added /unloadwar and /loadwar. Bit of tweaking here and there. 2011-05-18 21:56:18 -04:00
taoneill 9c3c722645 Closing disconnected inventory reset problems. This is a bit of dead code that may be useful in the future (i.e. the save-player-inventories-to-disk fix I should have tried to reproduce before coding). 2011-05-15 13:08:42 -04:00
taoneill 04b917807c Closes gh-97. Closes gh-171. Closes gh-108. Closes gh-85. Closes gh-67. Zonemakers see magic walls when on a team, which should work instead of forcing zonemakers to use /zonemaker to enable zonemaker mode. Friendly fire setting should now get persisted properly. When a bouncing arrow hits you you shouldn't get a friendly fire message anymore. No scoring can occur if other teams are empty. 2011-05-15 11:35:08 -04:00
taoneill eb2e7ed91c Closes gh-79. Closes gh-185. You can now use a wand to set the warzone corners. Use /setzone X wand. Zonemakers can now destroy blocks on walls of warzones. 2011-05-14 23:40:51 -04:00
taoneill e1d5602830 Closes gh-173. Closes gh-146. Worked around moved-too-quickly check by preventing players from getting kicked. Really closing gh-144. Lobbies should reset properly now (even though it's not perfect yet). 2011-05-14 19:51:59 -04:00
taoneill 12109175c0 Closes gh-21. Closes gh-114. Wandless cuboid zones are in. Lobbies now reset properly (their save was getting overwritten). Lobbies now always appear at mid-height of the zone. Can't resize warzones if structures end up outside. Zonemaker can now place blocks in important places (walls, monuments, etc) but these blocks will still get reset. No more warzone-ready message when no warzones to load. No more zone outlines, yay. 2011-05-10 00:16:20 -04:00
taoneill e81ba0faae Switch from depending on Permissions to Essentials GroupManagerBridge. Cuboid zone walls are working and resetting properly. Resizing is still a problem though. 2011-05-09 02:05:27 -04:00
taoneill 21f7547766 Added ZoneWallGuards for UP and DOWN walls, and changed related Warzone methods. Fixed warnings. 2011-05-09 00:12:49 -04:00
taoneill b652d12849 Plugged in ZoneVolume for cuboid support. Added ZoneSetter to encapsulate the performSetZone operations and error handling. Still probably broken and missing wand support. 2011-05-08 23:34:26 -04:00
taoneill 6efbf2f62d Added UP and DOWN wall checks and resets to ZoneVolume. 2011-05-08 16:17:22 -04:00
taoneill dd244b7f32 First commit for War v1.5, finally. Created a new ZoneVolume that will replace the VerticalVolume of warzones. Also added unit tests with dependency on mockito. 2011-05-08 15:37:00 -04:00
taoneill 50872d6802 Merged pull request #141 from Superyoshi/master.
Configurable Monument Heal Rate + ignoring 0 player teams
Thanks Superyoshi
Sorry for taking forever to merge this. I'm finally back.
2011-04-29 18:04:43 -07:00
taoneill 628c33778e Closes gh-149. Forgot to fix all reward and loadout-related item NPEs. This is War v1.4.2. 2011-04-11 11:10:53 -04:00
taoneill b9c0030e3c Closes gh-148. Closes gh-147. Updated to CB670. Fixed NPE when restoring inventory and now handling warhub reset attemps on missing world. This is War v1.4.1 (Slim). 2011-04-10 14:16:00 -04:00
Superyoshi 3032c6a0fc Teams without any players won't get listed in the scoring, can't steal flags from teams without players 2011-04-05 15:15:01 +02:00
Superyoshi 55ac717f89 Teams without any players won't score 2011-04-05 14:04:21 +02:00
Superyoshi 568833b1bf Closes gh-8. Monument Heal Rate is now configurable (monumentheal:X), also the Monument Heal Message now shows by how many hearts the player was healed 2011-04-03 11:34:21 +02:00
taoneill d84ed6e410 1.4 hotfix - removed nag on PlayerQuitEvent 2011-04-02 18:34:10 -04:00
taoneill 4f6f67bd92 Closes gh-130. The /war prefixed commands should work inside and outside warzones now. Updated to CB617/MC1.4. THis is War 1.4. 2011-04-02 16:50:39 -04:00
taoneill 498eb1e80a Closes gh-112. Forgot to update dispenser save-to-file code, which broke with the new item data and durability saving. This corrupted warzones for people everywhere. I'm so sorry. :( This is going out as War v.1.3.2 2011-03-23 14:51:02 -04:00
taoneill 3aad54cefe Closes gh-109. Closes gh-110. Warzones are now REALLY loaded with a delay, giving time to Multiverse to load its worlds. HeroicDeath compatibility should fix all respawn inventory issues. This is v1.3.1. 2011-03-22 15:21:56 -04:00
taoneill e32745662b Last little useless item handling change before 1.3 release. 2011-03-21 02:19:52 -04:00
taoneill 1c7bf3c7f2 v1.3. Added plugin.yml usage entry for rally point. 2011-03-21 02:08:42 -04:00
taoneill 362f625871 Closes gh-101. Closes gh-106. Added warzone rally point that can be set with .warcfg rallypoint:warzone-name. Hp now reset when player leaves. Cleaned up battle end and game end messages. 2011-03-21 01:05:38 -04:00
taoneill d81a198feb Closes gh-89. Closes gh-90. Couldn't reproduce warhub and lobby reset bugs. Closing for now. Did fix a few exceptions that might have been at the root of this, though improbable. 2011-03-21 00:06:31 -04:00
taoneill b8fba72f2d Closes gh-88. Ladders, torches, levers, wall signs, stone buttons and rails that were facing north (i.e. hanging on a block to the south) now reset properly by making sure their south-face block is already reset. 2011-03-20 23:36:29 -04:00
taoneill 02cd9ad28d Closes gh-93. Closes gh-104. Closes gh-105. Placing a team spawn over signs doens't cause sign spam anymore. Fixed player remaining on fire after score cap reached. Made wall trigger distance 6 blocks instead of 5 in last commit. 2011-03-20 21:54:06 -04:00
taoneill df68687092 Closes gh-92. Closes gh-103. Corner markers should reset wool properly and stay a bit longer, but disappear properly. Chest and dispenser item durability and data are now saved to disk (minor change of file format). 2011-03-20 20:54:03 -04:00
taoneill a5988c242c Closes gh-91. Closes gh-102. Warzones min size is now 10x10 and max size 750x750. Use large warzones at your own risk. NPE fixed when checking for important blocks in unfinished warzone. 2011-03-20 19:41:23 -04:00
taoneill e1fa801664 Closes gh-49. Nether lobbies dont look like chunk errors anymore. Not perfect, but better. The outlines are still weird. 2011-03-20 18:56:51 -04:00
taoneill 4b9c0d0a1c Lobby gates in other NORMAL worlds should now work. Nether lobbies are still broken, though. 2011-03-20 18:01:06 -04:00
taoneill c9d3a9867d Closes gh-83. Closes gh-94. Warzones are now loaded with a delay, which should prevent conflicts with Multiverse. Also, warzones should work accross many worlds now: I fixed the broken 'am I in a warzone' check. On a side note, since the last commit you can use .zonecfg and .warcfg instead of .setzoneconfig and .setwarconfig. 2011-03-20 16:36:13 -04:00
taoneill 08ca02cbad Closes gh-81. Closes gh-77. Closes gh-87. Temporarily closing these issue because volume resets and some player respawns are now delayed tasks handed off to the scheduler, which makes everything faster for the person who just died. There's a short delay to the zone reset now, though. Sign spam should be fixed in the same swoop. 2011-03-20 14:25:01 -04:00
taoneill 07ad330083 Closes gh-84. NPE on player_move in lobby when warhub did not exists. Up to v1.2.1. 2011-03-15 09:24:37 -04:00
taoneill a3509bd3f4 v1.2, updated plugin.yml with team colors. 2011-03-15 00:00:19 -04:00
taoneill fc70b78040 A start on gh-83. Won't completely break when MultiVerse isn't finished loading. Will handle this better later. 2011-03-14 23:52:24 -04:00
taoneill 1cf30f18b8 Closes gh-76. Stopping item drop near zone borders to prevent item duping exploit at lobby gates. Better zone name matching. Updated plugin.yml to War v1.2 (Bradley). 2011-03-14 23:34:11 -04:00
taoneill e3f7dd1989 Added substing matching for zones. 2011-03-06 23:20:45 -05:00
taoneill 13955e1ca0 Closes gh-50. Big changes. Dropped precious blocks in favor of colored wool for team material: new TeamKind abstraction. Substring searching team names. Trying to get rid of references to Block objects. 2011-03-06 21:12:53 -05:00
taoneill 091c237406 Updated to CB 386. Finally fixed the signs issue thanks to Grums help. Turns out the resetzone bug solves itself after a few minutes .. huh. 2011-03-03 15:28:38 -05:00
taoneill a184ff4bf1 Lot's of no good ideas in trying to fix the zone-freeze bug. 2011-02-28 20:31:52 -05:00
taoneill aba1e25569 Can't get rid of block freeze bug. Going back to CB 432 (RB2) from CB 439 didnt help. Swallowing sign exceptions until I figure out how to do it properly. I need you guy's help to find a way to reproduc ethe block freeze bug. :( 2011-02-25 10:26:53 -05:00
taoneill 58e59c75c2 Closes gh-72. Prevent players form using any commands but War ones inside warzones. Cant place flag or spawn block anymore. Not getting killed when sneaking out of a warzone anymore. Reward gets saved properly. Auto-assign join message fixed. Cant pickup more than one precious block. Updated to 439 to get rid of pesky reset bugs. Still getting block freeze bugs. :( 2011-02-24 13:18:26 -05:00
taoneill 29353f9c73 Closes gh-61. Resetting zone when last player leaves (joining when a zone has been deserted for a while kinda sucks). 2011-02-23 12:58:50 -05:00
taoneill b775997046 First v1.1 commit. Minecraft 1.3 and craftbukkit 431 fixes. Cant drop blocks and cant pickup more than one precious block. Also move to not use BLOCK_DAMAGED. Using BLOCK_BREAK instead: Grum says it's more reliable. 2011-02-23 12:40:37 -05:00
taoneill 01b86036dd Closes gh-48. Corner cursors dissapear after a second or two now. Got rid of /setzonelaodout in favor of /setzoneconfig loadout:default reward:default. Nicer no? 2011-02-22 02:36:07 -05:00
taoneill fc1621f4c6 Closes gh-69. Damn this was a bitch to fix. /setzone code is much clearer and less crazy now. 2011-02-22 00:54:51 -05:00
taoneill 31e4f3cb38 Closes gh-37. If you death causes score cap to be eached, you finallyu get your inv back. Still getting chunk errors though. Not good. Closes gh-60. Rewards work on my end. 2011-02-21 01:24:56 -05:00
taoneill ccb9d45305 Closes gh-14. Closes gh-66. Added noCreatures setting to stop mods and animals from spawning in zones. Block heads is the default now. Fixed typos. The zone-leaving area is more forgiving. 2011-02-20 23:47:45 -05:00
taoneill f9beef2073 Closes gh-65. Can now set zone loadout with /setzoneloadout and change default with /setwarloadout instead of having to reboot the server. 2011-02-20 23:03:23 -05:00
taoneill 89d7509b0c Closes gh-64. Players can't drop their precious blocks anymore. Flag bearers can't drop their flag either. Also, flag bearers are prevented from picking anything up. Temporary onOpenInventory code - its not in crafbukkit yet. 2011-02-20 21:08:15 -05:00
taoneill 4f1be9cb78 Made unbreakable zone setting also mean no-build. 2011-02-20 19:59:04 -05:00
taoneill e1c33a2fef Closes gh-62. Fixed DrawZoneOutline setting not getting read from war and warzone config files. Updated to Craftbukkit 361 and empty ctor signature. 2011-02-20 03:02:47 -05:00
taoneill f197a7d60d Now that wall signs reset, I found a bug where empty signs would cause a NPE upon volume reset. Fixed. 2011-02-15 22:34:43 -05:00
taoneill 46fd5ff1bb Closes gh-25. Closes gh-60. Order of zone creation (or order in war.txt) dictates the order of the zone on the warhub. Can now disable/enable a warzone so that is dissapears form the warhub and players cant join. This lets the zone maker work in peace. 2011-02-15 18:04:10 -05:00
taoneill 109b513600 Closes gh-53. No more client crash when using /team when not on a team. Whew. 2011-02-15 14:08:02 -05:00
taoneill 37c9084e85 Closes gh-20. Closes gh-59. Doors should reset properly now. Wall signs should also be fixed. Also in: zonemakers that join a team in and unbreakable-blocks zone cannot break the blocks anymore. 2011-02-15 13:59:06 -05:00
taoneill 10ae82999b Closes gh-58. Added unbreakableZoneBlocks setting. Zone makers are not affected. 2011-02-15 09:44:16 -05:00
taoneill bb66feab2d Closes gh-57. New buildInZonesOnly setting for griefer control on almost-only-War servers. Can be overridden by the war.build permission node. 2011-02-15 09:19:06 -05:00
taoneill 03b987ee37 Closes gh-42. No more unfinished warzones at the warhub. Warzone files don't get deleted though. 2011-02-14 16:37:51 -05:00
taoneill 6b3d55f563 Closes gh-40. First v1.0 commit. Updated plugin.yml. Fixed client crash caused by inventory reset when reconnecting after disconnecting from within a zone. 2011-02-12 12:01:32 -05:00
taoneill 62503d353c Last commit for v0.9 I think. Small fixes. Found a bug and created 37. Won't fix for this release tho. 2011-02-10 02:22:09 -05:00
taoneill 5298e5c87c Merge branch 'master' of github.com:taoneill/war 2011-02-10 01:34:34 -05:00
taoneill 00a6743370 Closes gh-36. Team members that sneak out of the warzone are killed (should prevent people from warping out with their zone goodies as well). Huge refactor of how I send messages to players to accomodate the chat color fix for client crashes. Woot. 2011-02-10 01:34:13 -05:00
taoneill 3b7f308fba Closes 36. Team members that sneak out of the warzone are killed (should prevent people from warping out with their zone goodies as well). Huge refactor of how I send messages to players to accomodate the chat color fix for client crashes. Woot. 2011-02-10 01:32:40 -05:00
taoneill 662c0622a0 Closes gh-12. Added rewards. Default reward when score cap is reach is one cake. Rewards can be customized just like loadouts. Added runnable task that will help to make loot drops configurable in the future. Added defaultSpawnStyle to War config. 2011-02-09 23:50:35 -05:00
taoneill f9d33cf803 Closes gh-10. Team spawn look is now configurable for each warzone. Hopefully go rid of NPE in BlockListener as well. 2011-02-09 22:35:17 -05:00
taoneill 9221582e2a Closes gh-34. Flag orientation is now saved (like the spawn). Made sure multi-line error messages are colored red also. 2011-02-09 18:38:53 -05:00
taoneill 6e8c06ee30 Merge branch 'master' of github.com:taoneill/war 2011-02-08 17:47:41 -05:00
taoneill 466fbf7692 Closes gh-35. Closes gh-29. Added color to chat (team chat, team names, red for errors). Added message when teams life pool is empty. Added war.warp permission node (must have to use zone and warhub). Now lowercasing named arguments. 2011-02-08 17:47:03 -05:00
taoneill 82663da3f7 Closes gh-35. Added color to chat (team chat, team names, red for errors). Added message when teams life pool is empty. 2011-02-08 17:42:50 -05:00
taoneill 5ad5f26084 Long needed refactoring of onCommand into many performXCommand methods. Readability ftw. 2011-02-08 15:16:23 -05:00
taoneill eea1771605 Closes 31. Removed login message. Updated to new version v0.9 (Simonds). 2011-02-08 14:52:41 -05:00
taoneill e8d4f02059 Closes gh-32. Closes gh-33. Now supports the new craftbukkit with many worlds. No more client crash when leaving a zone and opening inventory. 2011-02-08 14:11:53 -05:00
taoneill 23cb281a15 Closes gh-3. Signs, chests and dispensers and saved to disk. Everything reloads properly. 2011-02-06 18:26:18 -05:00
taoneill 0accca079a Chest and dispenser contents and now saved in memory. Just need to save them to disk now. Woot. 2011-02-06 17:22:28 -05:00
taoneill 00edf1e344 Merge branch 'master' of github.com:taoneill/war 2011-02-06 12:52:49 -05:00
taoneill 3aca473cc9 Closes gh-23. Closes gh-24. Closes gh-30. Death by lava seems to work ok on my side. Inventories get reset and signs as well. Fixed tp error with drowning deaths - weird workaround. Fire is extinguished back at the player spawn. 2011-02-06 12:51:37 -05:00
taoneill 18c1b498fb Closes 23. Closes 24. Closes 30. Death by lava seems to work ok on my side. Inventories get reset and signs as well. Fixed tp error with drowning deaths - weird workaround. Fire is extinguished back at the player spawn. 2011-02-06 12:49:22 -05:00
taoneill 7251ed06e3 Closes gh-16. Enemies can now be attacked be respawning players when stepping inside another team's spawn. Respawning players still can't attack enemy players ouside their spawn. 2011-02-06 09:15:39 -05:00
taoneill b91e2174a6 Closes gh-4. Warhub signs now update when players join by entering the gates. Finally. 2011-02-06 00:49:40 -05:00
taoneill 1ec9f0178c Closes gh-22. Warzone-specific loadouts never worked, until now. Oops, sorry. 2011-02-06 00:35:20 -05:00
taoneill c68f864be9 Closes gh-2. No more dropping precious blocks out the lobby gates. Leaving is now detecting in a much bigger volume. 2011-02-05 23:23:39 -05:00
taoneill 9a58dad30f Closes gh-7. Now saving, clearing and restoring player armor when joining/leaving/disconnecting. 2011-02-05 22:41:49 -05:00
taoneill 7dd4572d77 Closes gh-1. When a player disconnects, their inventory is stored in memory and restored when/if they reconnect - as a workaround for player state not being affect onPlayerQuit. Nice. 2011-02-05 22:04:42 -05:00
taoneill 0c987ddad3 Closes gh-27. Closes gh-28. Fixed old bug where I stored 129 vertical blocks in all zones. Fixing this is was a bit tricky but I found and fixed a cool slanted landscape bug and also an infinite loop related to glass walls near the sky or very bottom of the map. 2011-02-05 21:08:03 -05:00
taoneill be0c6fd57d Cleanup of old hmod files. New readme. Updated plugin.yml. First v0.8 (Yamamoto) commit. 2011-02-05 10:20:48 -05:00
taoneill 816067f76d v0.7 Manstein release. 2011-02-02 23:02:00 -05:00
taoneill b4d0e89ec8 First v0.7 (Manstein) commit. Updated to craftbukkit 201. Using on death hook for no death screen and to block loot drops. Sign update troubles seemed fix now that I use the state exclusively. 2011-02-01 15:17:14 -05:00
taoneill 9eec0b92e8 Fix for negative yaw values. v0.6 release. 2011-01-30 02:20:51 -05:00
taoneill bd472264e8 Spawns that turn. Better inventory reset. v0.6 Zhukov is ready. 2011-01-30 01:49:28 -05:00
taoneill 28d2e90ee0 Tested that zone maker can play all games. 2011-01-29 20:10:03 -05:00
taoneill eaf713fb1e Massaging the death handling into maybe creating less chunk errors and bugs. Zone makers now shouldnt be able to mess with important blocks. 2011-01-29 19:00:19 -05:00
taoneill ce625ee4b1 Added death detection for the flag thief. Also now detecting max score reached by capturing a flag. Changed the look of the team flags. CTF will be awesome. Too bad I can do anything about players dropping the flag. 2011-01-27 16:38:31 -05:00
taoneill 82367f22e6 First v0.6 (Zhukov) commit. Adding CTF with setteamflag command. Works great. 2011-01-27 11:36:20 -05:00
taoneill 4d8179c8fd War v0.5 (Rommel) 2011-01-23 18:57:03 -05:00
taoneill 41f7bc881b Last tests for v0.4. 2011-01-22 15:37:31 -05:00
taoneill 81495be56b Reverted to player_move death. Works great. Projectile events are fixed too. Spawns are protected. This is much better and snappy. Great. 2011-01-22 13:51:19 -05:00
taoneill 9704598f39 Finally got a handle on reliably teleportation at gates. Death sucks though. I'm going to revert back to the old system until player_death event makes it in. 2011-01-22 12:50:46 -05:00
taoneill 06ba048797 Added Permissions support. Trying everything to get gates and teleports in player_move working again to no avail. 2011-01-22 02:05:04 -05:00
taoneill b45af8cad0 Inventory and death detection are a pain in the butt. 2011-01-21 13:31:46 -05:00
taoneill 7c5aefaade Lots changed in how the PlayerMoveEvent is handled. Now cancellign and teleporting because event.setTo sucks. Resetting team spawns at every respawn because signs are broken. 2011-01-21 12:35:27 -05:00
taoneill 4187c59aa7 Made walls larger. Better handling of death through Entity events instead of player move. Still some lil bugs. 0.4 tomorrow. 2011-01-21 02:07:19 -05:00
taoneill 897048e90f Found the damn lobby + zone resize bug. 2011-01-21 01:02:06 -05:00
taoneill 5d5f2ada5e Updated to new command args for #107+. Fixed rezising messing up the world, except for that damn row of glass for the lobbies. Lobby set down with outline now. 2011-01-21 00:54:04 -05:00
taoneill 88d8632931 v0.3 Patton tested with Bukkit snapshot of build #87. 2011-01-19 02:49:14 -05:00
taoneill 3f164f60c5 Fixed leaving zone that was glitchy. Just approaching the gates now makes you leave. Fixed lifepool decrement by one too many bug with a dirty workaround for now. Ready to release v0.3 of next short test goes well. 2011-01-19 02:30:28 -05:00
taoneill 003b89f904 Shot a vid for 0.3. Assorted bugs. 2011-01-18 23:31:34 -05:00
taoneill 55046e7895 Fixed improper link between lobby and warhub sign resetting. Little bugs. 2011-01-18 21:08:02 -05:00
taoneill ccedb36138 Added warzone signs. Tryign to line up lobby teleport but ohwell. 2011-01-18 18:03:10 -05:00
taoneill d24709bbd6 Less memory usage for zone block storage. savezone and setzoneconfig fixes for named params. Resetting lobby more often. v0.3 finish line is getting much closer. 2011-01-18 16:57:25 -05:00
taoneill 6f2b7c92c4 Changed the file hierarchy - much cleaner now. Not storing block pos in memory anymore in the BlockInfo, which saves a couple tens of megs. Fixing late night mistakes. 2011-01-18 14:52:06 -05:00
taoneill 0ac179bb89 Auto assign gate exemptions for wall guard. 2011-01-18 11:05:38 -05:00
taoneill 33bebcd928 Added player impersonation for zonemakers cause i wanted it. Enough now. :S 2011-01-18 03:23:24 -05:00
taoneill 6a7fad99db Updated to new Command signature. Added /setzoneconfig, named parmas also for /savezone, /deletewarhub, /setwarconfig. Other fixes here and there. Memory usage is aweful. 2011-01-18 01:41:35 -05:00
taoneill 6dfb261c05 Playtesting v0.3. Bugs everywhere getting fixed. No more spamming anything. Weird crash occured twice. Scary. Otherwise monuments work great and its a lot of fun. 2011-01-17 22:58:46 -05:00
taoneill 6cc5ee64bc Bunch of litte fixes. Setting helmet instead of boots so everything works when it's patched. No more spammy signs. Added sign to war hub. Monuments are broken. 2011-01-17 19:01:55 -05:00
taoneill fbf4dc26fc Working signs on lobbies and the warhub. They spam-destroy a lot though. 2011-01-17 01:13:50 -05:00
taoneill 72afd7068d Added teamCap and scoreCap. Also mapped autoAssign and drawOutiline in warzone file. 2011-01-16 22:46:38 -05:00
taoneill efa3b63ea9 Loadouts and inventory storage works. :D 2011-01-16 21:47:15 -05:00
taoneill b1ceaa3f46 Tweaking checks around wall so players can get in zones by the gates reliably. 2011-01-16 21:26:53 -05:00
taoneill 317b813c4f Warhub and lobby link gates are working and pretty. 2011-01-16 20:35:53 -05:00
taoneill 2692f7ec8e Warhub works. For one zone at least. 2011-01-16 19:23:43 -05:00
taoneill 8e74abb69a Team dev explained to me how to us the new Plugin.onCommand instead of onPlayerCommand. This works now. Also fixed glitchy /deleteteam. Removed old version of commands for the most part. 2011-01-16 18:50:58 -05:00
taoneill c866f17a3c Commenting out ocmmans in plugin.yml until its implemented correctly in bukkit. 2011-01-16 14:04:10 -05:00
taoneill 3b137a76b6 plugin.yml with commands. /setwarhub and /warhub commands separated. Should now be able to delete everything from a lobby. 2011-01-16 13:34:18 -05:00
taoneill f099539e39 Not using the CenteredVolume anymore. Monuments reset properly. Lit up the lobby. Adding a team resets the lobby correctly, but not deleting. Hmm. 2011-01-16 02:41:57 -05:00
taoneill 05d5a8d8be Updated to new craftbukkit build. is that 48? 2011-01-16 00:15:16 -05:00
taoneill 567718662a Added zone maker exceptions. Got to nail down the spammy death problem. 2011-01-15 23:22:55 -05:00
taoneill 8bafd9f372 Found that damn gates bug oh yeah. 2011-01-15 22:07:30 -05:00
taoneill c9680d7556 Found a way to mimmick onDeath. Some tp errors not not systematic anymore. 2011-01-15 21:16:31 -05:00
taoneill 64dbaaa00d Fixing wall outline. Poor trees would get massacred by glass. 2011-01-15 16:03:09 -05:00
taoneill 317eaa6c35 Better nw and se corner cursors that should reset properly. Warning people that they don't have the zonemaker permission if they try a zone maker command. 2011-01-15 15:37:00 -05:00
taoneill 5a16e08c7a Fixed plugin class ctor to add folder for Configuration. Fixed from-disk lobby initialization so its positon doesnt change. 2011-01-15 13:54:42 -05:00
taoneill 1e6d8d1e1d Just missing death tp, better lobby height management and a non buggy way to let normal players thru the gate and the wall guard. 2011-01-15 02:03:04 -05:00
taoneill 5cd2d90173 Working lobby portals - dont use player.teleportTo but event.setTo instead instead a PlayerMoveEvent. Fixed lobby door bug. 2011-01-14 23:58:32 -05:00
taoneill 78eafe7ba8 Lobby realigned but still broken. Teleport to team spawn is spammy. Giving up on the monuments for now heh. 2011-01-14 17:49:45 -05:00
taoneill 1723aae771 Mapping bugs. Monument bugs still ongoing. Lobby is borked. 2011-01-14 17:04:06 -05:00
taoneill 40f14a7bb0 Finally saving blocks correctly. Load is still a problem. 2011-01-14 14:56:38 -05:00
taoneill f3f596db3c Give zone maker the right to destroy and place blocks in a warzone. Technically this shouldnt break his ability to be part of a team. 2011-01-14 14:28:30 -05:00
taoneill 0abd111f72 Now saving zone blocks as soon as second corner is set. Also now saving blocks when changing corners. Now saving team lobby and monument blocks at all times. 2011-01-14 14:14:21 -05:00
taoneill 0753f76350 Started testing with beta 1.2_01. Warzone makers dont get bothered wiht zone wall blocks anymore. Fixed config file names. 2011-01-14 10:31:16 -05:00
taoneill 4222b2eedf Hopefully better looking and working monuments. Finished up missing parts of lobby mapping. Something else I forget. Ready for the new CraftBukkit a a hell of a lot of testing. 2011-01-14 01:51:19 -05:00
taoneill 81ce4627f0 Warzone lobbies and warhub, related commands, teleports for gates in both. Auto-assign. 2011-01-14 01:21:18 -05:00
taoneill 6c39559c04 Zone lobby well under way. Updated to new bukkit with capitalized materials. Craftbukkit is still broken so all of this is untested. 2011-01-13 22:50:29 -05:00
taoneill e5497786f3 Fixed broken build. Volume mapping is much cleaner now. Getting started on WarHub and ZoneLobby. 2011-01-13 18:34:26 -05:00
unknown e33a19cc4f Totally broken. Factoring out the volume mapping and adding warhubs 2011-01-13 17:19:27 -05:00
taoneill f2be251106 Rewriting the file read-writing. 2011-01-13 01:34:51 -05:00
taoneill d598c921d5 Zone wall guard works. Yahoo 2011-01-12 02:16:34 -05:00
taoneill 894bbaca43 Zone wall guards to keep player from entering or exiting a warzone 2011-01-11 23:03:48 -05:00
taoneill 31bd3523e1 Warzone is not outlined in glass. Moved Plugin and Listener classes to bukkit.tommytony.war package. 2011-01-11 17:25:46 -05:00
taoneill 61ecb3b7ba Brought back all inventory code. Everything should be ported now. Needs more testing. 2011-01-10 01:52:22 -05:00
taoneill 9f53f0265e Brought back inventory code. 2011-01-10 01:21:04 -05:00
taoneill 631ff256c1 Taking ownership of the /war prefix 2011-01-10 00:52:24 -05:00
taoneill 6f3b4c8275 New rule, only 3 teams available - diamond, iron and gold. Updated the commands and merged some. Old commands should still work. 2011-01-10 00:27:34 -05:00
taoneill 84f6abb0d5 Fixed team spawns 2011-01-09 20:39:59 -05:00
taoneill 07b3b21077 Lots of bugs in my volumes stuff. Still somewhat broken. 2011-01-09 02:15:51 -05:00
taoneill 9204df2dc2 Remaining volumes mapping to files. Cleanup of old block state handling. 2011-01-09 00:13:54 -05:00
taoneill 20032dddbf Volumes - a sort of self made cuboid abstraction. Refactored warzones, monuments and team spawns into volumes. Can finally start adding new features again soon. 2011-01-08 23:40:13 -05:00
taoneill dbe7fdfc11 Rolling my on sortof-Cuboid 2011-01-08 03:03:14 -05:00
taoneill 7de2886f19 v0.3 shaping up.. 2011-01-06 21:01:41 -05:00
taoneill cd6c4fc10a More resetwarzone madness. 2011-01-06 20:40:44 -05:00
taoneill f76419a4b9 Bugs bugs... 2011-01-06 20:34:08 -05:00
taoneill 546fe01d6a First commit towards v0.3, the Bukkit port. Warzone definition and saving works. 2011-01-06 19:18:54 -05:00
taoneill 7c0484063a Storage in text files works except sometimes files can't be deleted. Lots of bug fixes. 2011-01-05 03:43:23 -05:00
taoneill 1c9c3f40a4 Better persistence, still some bugs in there. Protected spawns and monuments. Delete commands. Sign posts that give the score. 2011-01-04 21:12:02 -05:00
taoneill f2079ddae7 Persisting zone blocks in a ghetto text file. Friendly fire settings and should now allow regular PVP, technically. Leaving-entering warzone warnings 2011-01-04 18:17:57 -05:00
taoneill 4349c7fd17 Added config files. One file per warzone. Defaults and warzone names in war.txt. 2011-01-04 16:52:38 -05:00
177 changed files with 22548 additions and 1305 deletions

11
.gitignore vendored
View File

@ -2,12 +2,15 @@
.*
# except for .gitignore
!.gitignore
!.classpath
!.project
.classpath
.project
# Ignore all classfiles
*.class
# Ignore bin
*/bin/*
*/lib/*
bin
*/lib/*
*/target/*
dependency-reduced-pom.xml

20
MIT-LICENSE.txt Normal file
View File

@ -0,0 +1,20 @@
Copyright (c) 2012 Thomas-Antoine O'Neill aka tommytony, http://war.tommytony.com
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

36
README.md Normal file
View File

@ -0,0 +1,36 @@
![War logo](http://i.imgur.com/LFdiF.png "War - Minecraft PVP Arenas - TDM, CTF and more!")
War - Minecraft PVP Arenas (TDM, CTF and more!)
===============================================
War is a plugin for Bukkit that adds PVP arenas and team deathmatch gamemodes to Minecraft servers.
Official website
----------------
Visit http://war.tommytony.com for more info, videos and links.
Features
--------
- Built on the popular Bukkit mod API (http://bukkit.org)
- Capture-the-flag and team deathmatch arenas, called warzones
- Warzone blocks are saved and reset at the end of every game, for safely destructible maps
- Other game types: capture points and explosive-based objectives
- Up to 16 teams!
- Tons of customizable game rules, item loadouts and options (see [Instructions](http://war.tommytony.com/instructions))
Downloads
---------
All official releases are at https://github.com/taoneill/war/downloads.
Dev Builds
----------
Development builds are available at https://cmastudios.me/cgi-bin/war.py.
Author
------
tommytony started the plugin in December 2010 on hMod and has been maintaining it since with the help of contributors.
Reach him at taoneill@tommytony.com.
License
-------
War is licensed loosely under the MIT License (but still comes with the weird baggage of Bukkit licensing)

View File

@ -1,3 +0,0 @@
War, a simple hmod plugin that adds team deathmatch to minecraft multiplayer.
All credit goes to Mojang and the hey0 team for being so awesome.

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>minecraft.hmod.war.test</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -1,12 +0,0 @@
#Thu Dec 16 22:49:21 EST 2010
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="lib" path="C:/dev/war/minecraft.hmod.war/lib/Minecraft_Mod133.jar" sourcepath="/hmod"/>
<classpathentry kind="lib" path="C:/dev/war/minecraft.hmod.war/lib/minecraft_server-beta1.1_02.jar"/>
<classpathentry kind="lib" path="C:/dev/war/minecraft.hmod.war/lib/mysql-connector-java-bin133.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>minecraft.hmod.war</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -1,12 +0,0 @@
#Sat Dec 11 12:21:43 EST 2010
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

View File

@ -1,5 +0,0 @@
public class Battle {
}

View File

@ -1,29 +0,0 @@
public class BlockColumnSetter implements Runnable {
private final int x;
private final int z;
private final Server server;
private final int[][][] initialState;
private final int i;
private final int k;
public BlockColumnSetter(Server server, int[][][] initialState, int x, int z, int i, int k) {
this.server = server;
this.initialState = initialState;
this.x = x;
this.z = z;
this.i = i;
this.k = k;
}
@Override
public void run() {
for(int j = 0; j < 128; j++) {
server.setBlockAt(initialState[i][j][k], x, j, z);
}
server.messageAll("Reset x=" + x + " z=" + z);
}
}

View File

@ -1,112 +0,0 @@
public class Monument {
private Location location;
private int[] initialState = new int[10];
private War war = null;
private Team ownerTeam = null;
private final String name;
public Monument(String name, War war, Location location) {
this.name = name;
this.location = location;
this.war = war;
int x = (int)location.x;
int y = (int)location.y;
int z = (int)location.z;
initialState[0] = war.getServer().getBlockIdAt(x+1, y-1, z+1);
initialState[1] = war.getServer().getBlockIdAt(x+1, y-1, z);
initialState[2] = war.getServer().getBlockIdAt(x+1, y-1, z-1);
initialState[3] = war.getServer().getBlockIdAt(x, y-1, z+1);
initialState[4] = war.getServer().getBlockIdAt(x, y-1, z);
initialState[5] = war.getServer().getBlockIdAt(x, y-1, z-1);
initialState[6] = war.getServer().getBlockIdAt(x-1, y-1, z+1);
initialState[7] = war.getServer().getBlockIdAt(x-1, y-1, z);
initialState[8] = war.getServer().getBlockIdAt(x-1, y-1, z-1);
initialState[9] = war.getServer().getBlockIdAt(x, y, z);
this.reset();
}
public boolean isNear(Location playerLocation) {
int x = (int)getLocation().x;
int y = (int)getLocation().y;
int z = (int)getLocation().z;
int playerX = (int)playerLocation.x;
int playerY = (int)playerLocation.y;
int playerZ = (int)playerLocation.z;
int diffX = Math.abs(playerX - x);
int diffY = Math.abs(playerY - y);
int diffZ = Math.abs(playerZ - z);
if(diffX < 6 && diffY < 6 && diffZ < 6) {
return true;
}
return false;
}
public boolean isOwner(Team team) {
if(team == ownerTeam) {
return true;
}
return false;
}
public boolean hasOwner() {
return ownerTeam != null;
}
public void ignite(Team team) {
ownerTeam = team;
}
public void smother() {
ownerTeam = null;
}
public void reset() {
this.ownerTeam = null;
int x = (int)getLocation().x;
int y = (int)getLocation().y;
int z = (int)getLocation().z;
war.getServer().setBlockAt(49, x+1, y-1, z+1);
war.getServer().setBlockAt(49, x+1, y-1, z);
war.getServer().setBlockAt(49, x+1, y-1, z-1);
war.getServer().setBlockAt(49, x, y-1, z+1);
war.getServer().setBlockAt(87, x, y-1, z);
war.getServer().setBlockAt(49, x, y-1, z-1);
war.getServer().setBlockAt(49, x-1, y-1, z+1);
war.getServer().setBlockAt(49, x-1, y-1, z);
war.getServer().setBlockAt(49, x-1, y-1, z-1);
war.getServer().setBlockAt(0, x, y, z);
}
public void remove() {
int x = (int)getLocation().x;
int y = (int)getLocation().y;
int z = (int)getLocation().z;
war.getServer().setBlockAt(initialState[0], x+1, y-1, z+1);
war.getServer().setBlockAt(initialState[1], x+1, y-1, z);
war.getServer().setBlockAt(initialState[2], x+1, y-1, z-1);
war.getServer().setBlockAt(initialState[3], x, y-1, z+1);
war.getServer().setBlockAt(initialState[4], x, y-1, z);
war.getServer().setBlockAt(initialState[5], x, y-1, z-1);
war.getServer().setBlockAt(initialState[6], x-1, y-1, z+1);
war.getServer().setBlockAt(initialState[7], x-1, y-1, z);
war.getServer().setBlockAt(initialState[8], x-1, y-1, z-1);
war.getServer().setBlockAt(initialState[9], x, y, z);
}
public Location getLocation() {
return location;
}
public void setOwnerTeam(Team team) {
this.ownerTeam = team;
}
public String getName() {
return name;
}
}

View File

@ -1,4 +0,0 @@
public class NotReadyException extends Exception {
}

View File

@ -1,86 +0,0 @@
import java.util.ArrayList;
import java.util.List;
public class Team {
private List<Player> players = new ArrayList<Player>();
private Location teamSpawn = null;
private String name;
private int remainingTickets;
private int[] oldSpawnState = new int[10];
private int points = 0;
public Team(String name, Location teamSpawn) {
this.setName(name);
this.teamSpawn = teamSpawn;
this.remainingTickets = War.LIFEPOOL;
}
public void setTeamSpawn(Location teamSpawn) {
this.teamSpawn = teamSpawn;
}
public Location getTeamSpawn() {
return teamSpawn;
}
public void addPlayer(Player player) {
this.players.add(player);
}
public List<Player> getPlayers() {
return players;
}
public void teamcast(String message) {
for(Player player : players) {
player.sendMessage(message);
}
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public boolean removePlayer(String name) {
Player thePlayer = null;
for(Player player : players) {
if(player.getName().equals(name)) {
thePlayer = player;
}
}
if(thePlayer != null) {
players.remove(thePlayer);
return true;
}
return false;
}
public void setRemainingTickets(int remainingTickets) {
this.remainingTickets = remainingTickets;
}
public int getRemainingTickets() {
return remainingTickets;
}
public int[] getOldSpawnState() {
return oldSpawnState;
}
public void setOldSpawnState(int[] oldSpawnState) {
this.oldSpawnState = oldSpawnState;
}
public void addPoint() {
points++;
}
public int getPoints() {
return points;
}
}

View File

@ -1,150 +0,0 @@
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
public class War extends Plugin {
public static final int LIFEPOOL = 5;
private WarListener listener = new WarListener(this);
private Logger log;
String name = "War";
String version = "0.1";
private final List<Warzone> warzones = new ArrayList<Warzone>();
public void initialize() {
this.log = Logger.getLogger("Minecraft");
getLogger().info(name + " " + version + " initialized");
etc.getLoader().addListener(
PluginLoader.Hook.COMMAND,
listener,
this,
PluginListener.Priority.MEDIUM);
etc.getLoader().addListener( PluginLoader.Hook.LOGIN,
listener,
this,
PluginListener.Priority.MEDIUM);
etc.getLoader().addListener( PluginLoader.Hook.HEALTH_CHANGE,
listener,
this,
PluginListener.Priority.MEDIUM);
etc.getLoader().addListener( PluginLoader.Hook.DAMAGE,
listener,
this,
PluginListener.Priority.HIGH);
etc.getLoader().addListener( PluginLoader.Hook.PLAYER_MOVE,
listener,
this,
PluginListener.Priority.MEDIUM);
etc.getLoader().addListener( PluginLoader.Hook.DISCONNECT,
listener,
this,
PluginListener.Priority.MEDIUM);
etc.getLoader().addListener( PluginLoader.Hook.IGNITE,
listener,
this,
PluginListener.Priority.MEDIUM);
etc.getLoader().addListener( PluginLoader.Hook.FLOW,
listener,
this,
PluginListener.Priority.MEDIUM);
// etc.getLoader().addListener(
// PluginLoader.Hook.BLOCK_CREATED,
// listener,
// this,
// PluginListener.Priority.MEDIUM);
}
@Override
public void disable() {
// TODO Auto-generated method stub
}
@Override
public void enable() {
// TODO Auto-generated method stub
}
public Team getPlayerTeam(String playerName) {
for(Warzone warzone : warzones) {
Team team = warzone.getPlayerTeam(playerName);
if(team != null) return team;
}
return null;
}
public Warzone getPlayerWarzone(String playerName) {
for(Warzone warzone : warzones) {
Team team = warzone.getPlayerTeam(playerName);
if(team != null) return warzone;
}
return null;
}
public Logger getLogger() {
return log;
}
public Warzone warzone(Location location) {
for(Warzone warzone : warzones) {
if(warzone.contains(location)) return warzone;
}
return null;
}
public boolean inAnyWarzone(Location location) {
if(warzone(location) == null) {
return false;
}
return true;
}
public boolean inWarzone(String warzoneName, Location location) {
Warzone currentZone = warzone(location);
if(currentZone == null) {
return false;
} else if (warzoneName.equals(currentZone.getName())){
return true;
}
return false;
}
public void addWarzone(Warzone zone) {
warzones.add(zone);
}
public Server getServer() {
// TODO Auto-generated method stub
return etc.getServer();
}
public List<Warzone> getWarzones() {
return warzones;
}
public String str(String str) {
String out = Colors.LightGray + "[war] " + Colors.White + str;
return out;
}
public Warzone findWarzone(String warzoneName) {
for(Warzone warzone : warzones) {
if(warzone.getName().equals(warzoneName)) {
return warzone;
}
}
return null;
}
}

View File

@ -1,558 +0,0 @@
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
public class WarListener extends PluginListener {
private final War war;
private Random random = null;
public WarListener(War war) {
this.war = war;
random = new Random(war.getServer().getTime());
}
public void onLogin(Player player) {
player.sendMessage(war.str("War is on! Pick your battle (try /warzones)."));
}
public boolean onCommand(Player player, java.lang.String[] split) {
String command = split[0];
// Player commands: /warzones, /warzone, /teams, /join, /leave
// warzones
if(command.equals("/warzones")){
String warzonesMessage = "Warzones: ";
if(war.getWarzones().isEmpty()){
warzonesMessage += "none.";
}
for(Warzone warzone : war.getWarzones()) {
warzonesMessage += warzone.getName() + " ("
+ warzone.getTeams().size() + " teams, ";
int playerTotal = 0;
for(Team team : warzone.getTeams()) {
playerTotal += team.getPlayers().size();
}
warzonesMessage += playerTotal + " players) ";
}
player.sendMessage(war.str(warzonesMessage + " Use /warzone <zone-name> to " +
"teleport to a warzone, " +
"then use /teams and /join <team-name>."));
return true;
}
// warzone
else if(command.equals("/warzone")) {
if(split.length < 2) {
player.sendMessage(war.str("Usage: /warzone <warzone-name>."));
} else {
for(Warzone warzone : war.getWarzones()) {
if(warzone.getName().equals(split[1])){
player.teleportTo(warzone.getTeleport());
player.sendMessage(war.str("You've landed in warzone " + warzone.getName() +
". Use the /join command. " + getAllTeamsMsg(player)));
return true;
}
}
player.sendMessage("No such warzone.");
}
return true;
}
// /teams
else if(command.equals("/teams")){
if(!war.inAnyWarzone(player.getLocation())) {
player.sendMessage(war.str("Usage: /teams. " +
"Must be in a warzone (try /warzones and /warzone)."));
} else {
player.sendMessage(war.str("" + getAllTeamsMsg(player)));
}
return true;
}
// /join <teamname>
else if(command.equals("/join")) {
if(split.length < 2 || !war.inAnyWarzone(player.getLocation())) {
player.sendMessage(war.str("Usage: /join <team-name>." +
" Teams are warzone specific." +
" You must be inside a warzone to join a team."));
} else {
// drop from old team if any
Team previousTeam = war.getPlayerTeam(player.getName());
if(previousTeam != null) {
if(!previousTeam.removePlayer(player.getName())){
war.getLogger().log(Level.WARNING, "Could not remove player " + player.getName() + " from team " + previousTeam.getName());
}
}
// join new team
String name = split[1];
List<Team> teams = war.warzone(player.getLocation()).getTeams();
boolean foundTeam = false;
for(Team team : teams) {
if(team.getName().equals(name)) {
team.addPlayer(player);
Warzone zone = war.warzone(player.getLocation());
zone.respawnPlayer(team, player);
foundTeam = true;
}
}
if(foundTeam) {
for(Team team : teams){
team.teamcast(war.str("" + player.getName() + " joined " + name));
}
} else {
player.sendMessage(war.str("No such team. Try /teams."));
}
}
return true;
}
// /leave
else if(command.equals("/leave")) {
if(!war.inAnyWarzone(player.getLocation()) || war.getPlayerTeam(player.getName()) == null) {
player.sendMessage(war.str("Usage: /leave. " +
"Must be in a team already."));
} else {
Team playerTeam = war.getPlayerTeam(player.getName());
playerTeam.removePlayer(player.getName());
player.sendMessage(war.str("Left the team. You can now exit the warzone."));
}
return true;
}
// /team <msg>
else if(command.equals("/team")) {
if(!war.inAnyWarzone(player.getLocation())) {
player.sendMessage(war.str("Usage: /team <message>. " +
"Sends a message only to your teammates."));
} else {
Team playerTeam = war.getPlayerTeam(player.getName());
String teamMessage = player.getName();
for(int j = 1 ; j<split.length; j++) {
String part = split[j];
teamMessage += part + " ";
}
playerTeam.teamcast(war.str(teamMessage));
}
return true;
}
// Mod commands : /restartbattle
// /restartbattle
else if(command.equals("/restartbattle")) {
if(!war.inAnyWarzone(player.getLocation())) {
player.sendMessage(war.str("Usage: /restartbattle. Must be in warzone."));
} else {
Warzone warzone = war.warzone(player.getLocation());
for(Team team: warzone.getTeams()) {
team.teamcast(war.str("The battle has ended. " + getAllTeamsMsg(player) + " Resetting warzone " + warzone.getName() + "..."));
}
int resetBlocks = warzone.resetState();
player.sendMessage(war.str("Warzone reset. " + resetBlocks + " blocks reset."));
}
return true;
}
// Warzone maker commands: /setwarzone, /setwarzonestart, /resetwarzone, /newteam, /setteamspawn, .. /setmonument?
// /newteam <teamname>
else if(command.equals("/newteam")) {
if(split.length < 2 || !war.inAnyWarzone(player.getLocation())) {
player.sendMessage(war.str("Usage: /newteam <team-name>." +
" Sets the team spawn to the current location. " +
"Must be in a warzone (try /warzones and /warzone). "));
} else {
String name = split[1];
Team newTeam = new Team(name, player.getLocation());
war.warzone(player.getLocation()).getTeams().add(newTeam);
addSpawnArea(newTeam, player.getLocation(), 41);
player.sendMessage(war.str("Team " + name + " created with spawn here."));
}
return true;
}
// /setteamspawn
else if(command.equals("/setteamspawn")) {
if(split.length < 2 || !war.inAnyWarzone(player.getLocation())) {
player.sendMessage(war.str("Usage: /setteamspawn <team-name>. " +
"Sets the team spawn. " +
"Must be in warzone and team must already exist."));
} else {
List<Team> teams = war.warzone(player.getLocation()).getTeams();
Team team = null;
for(Team t : teams) {
if(t.getName().equals(split[1])) {
team = t;
}
}
if(team != null) {
removeSpawnArea(team);
addSpawnArea(team, player.getLocation(), 41);
team.setTeamSpawn(player.getLocation());
player.sendMessage(war.str("Team " + team.getName() + " spawn relocated."));
} else {
player.sendMessage(war.str("Usage: /setteamspawn <team-name>. " +
"Sets the team spawn. " +
"Must be in warzone and team must already exist."));
}
}
return true;
}
// /setwarzone
else if(command.equals("/setwarzone")) {
if(split.length < 3 || (split.length == 3 && (!split[2].equals("southeast") && !split[2].equals("northwest")
&& !split[2].equals("se") && !split[2].equals("nw")))) {
player.sendMessage(war.str("Usage: /setwarzone <warzone-name> <'southeast'/'northwest'>. " +
"Defines the battleground boundary. " +
"The warzone is reset at the start of every battle. " +
"This command overwrites any previously saved blocks " +
"(i.e. make sure you reset with /restartbattle " +
"or /resetwarzone before changing the boundary). "));
} else {
Warzone warzone = war.findWarzone(split[1]);
if(warzone == null) {
// create the warzone
Warzone newZone = new Warzone(war.getServer(), split[1]);
war.addWarzone(newZone);
if(split[2].equals("northwest") || split[2].equals("nw")) {
newZone.setNorthwest(player.getLocation());
player.sendMessage(war.str("Warzone " + newZone.getName() + " added. Northwesternmost point set at x=" + (int)newZone.getNorthwest().x + " z=" + (int)newZone.getNorthwest().z + "."));
} else {
newZone.setSoutheast(player.getLocation());
player.sendMessage(war.str("Warzone " + newZone.getName() + " added. Southeasternmost point set at x=" + (int)newZone.getSoutheast().x + " z=" + (int)newZone.getSoutheast().z + "."));
}
} else {
String message = "";
if(split[2].equals("northwest") || split[2].equals("nw")) {
warzone.setNorthwest(player.getLocation());
message += "Northwesternmost point set at x=" + (int)warzone.getNorthwest().x + " z=" + (int)warzone.getNorthwest().z + " on warzone " + warzone.getName() + ".";
} else {
warzone.setSoutheast(player.getLocation());
message += "Southeasternmost point set at x=" + (int)warzone.getSoutheast().x + " z=" + (int)warzone.getSoutheast().z + " on warzone " + warzone.getName() + ".";
}
if(warzone.getNorthwest() == null) {
message += " Still missing northwesternmost point.";
}
if(warzone.getSoutheast() == null) {
message += " Still missing southeasternmost point.";
}
if(warzone.getNorthwest() != null && warzone.getSoutheast() != null) {
if(warzone.ready()) {
message += " Warzone " + warzone.getName() + " almost ready. Use /newteam while inside the warzone to create new teams. Make sure to use /setwarzonestart to " +
"set the warzone teleport point and initial state.";
} else if (warzone.tooSmall()) {
message += " Warzone " + warzone.getName() + " is too small. Min north-south size: 20. Min east-west size: 20.";
} else if (warzone.tooBig()) {
message += " Warzone " + warzone.getName() + " is too Big. Max north-south size: 1000. Max east-west size: 1000.";
}
}
player.sendMessage(war.str(message));
}
}
return true;
}
// /setwarzonestart
else if(command.equals("/setwarzonestart")) {
if(!war.inAnyWarzone(player.getLocation())) {
player.sendMessage(war.str("Usage: /setwarzonestart. Must be in warzone. " +
"Changes the warzone state at the beginning of every battle. " +
"Also sets the teleport point for this warzone " +
"(i.e. make sure to use /warzone or the warzone tp point will change). " +
"Just like /setwarzone, this command overwrites any previously saved blocks " +
"(i.e. make sure you reset with /restartbattle " +
"or /resetwarzone before changing start state). "));
} else {
Warzone warzone = war.warzone(player.getLocation());
int savedBlocks = warzone.saveState();
warzone.setTeleport(player.getLocation());
player.sendMessage(war.str("Warzone " + warzone.getName() + " initial state and teleport location changed. Saved " + savedBlocks + " blocks."));
}
return true;
}
// /resetwarzone
else if(command.equals("/resetwarzone")) {
if(!war.inAnyWarzone(player.getLocation())) {
player.sendMessage(war.str("Usage: /resetwarzone. Must be in warzone."));
} else {
Warzone warzone = war.warzone(player.getLocation());
for(Team team: warzone.getTeams()) {
team.teamcast(war.str("Resetting warzone " + warzone.getName() + "..."));
}
int resetBlocks = warzone.resetState();
Location playerLoc = player.getLocation();
player.sendMessage(war.str("Warzone reset. " + resetBlocks + " blocks reset."));
}
return true;
}
// /monument
else if(command.equals("/monument")) {
if(!war.inAnyWarzone(player.getLocation())) {
player.sendMessage(war.str("Usage: /monument <name>. Must be in warzone."));
} else {
Warzone warzone = war.warzone(player.getLocation());
Monument monument = new Monument(split[1], war, player.getLocation());
warzone.getMomuments().add(monument);
player.sendMessage(war.str("Monument " + monument.getName() + " created."));
}
return true;
}
return false;
}
private void removeSpawnArea(Team team) {
// Reset spawn to what it was before the gold blocks
int[] spawnState = team.getOldSpawnState();
int x = (int)team.getTeamSpawn().x;
int y = (int)team.getTeamSpawn().y;
int z = (int)team.getTeamSpawn().z;
war.getServer().setBlockAt(spawnState[0], x+1, y-1, z+1);
war.getServer().setBlockAt(spawnState[1], x+1, y-1, z);
war.getServer().setBlockAt(spawnState[2], x+1, y-1, z-1);
war.getServer().setBlockAt(spawnState[3], x, y-1, z+1);
war.getServer().setBlockAt(spawnState[4], x, y-1, z);
war.getServer().setBlockAt(spawnState[5], x, y-1, z-1);
war.getServer().setBlockAt(spawnState[6], x-1, y-1, z+1);
war.getServer().setBlockAt(spawnState[7], x-1, y-1, z);
war.getServer().setBlockAt(spawnState[8], x-1, y-1, z-1);
war.getServer().setBlockAt(spawnState[9], x, y, z);
}
private void addSpawnArea(Team team, Location location, int blockType) {
// Save the spawn state (i.e. the nine block under the player spawn)
int[] spawnState = new int[10];
int x = (int)location.x;
int y = (int)location.y;
int z = (int)location.z;
spawnState[0] = war.getServer().getBlockIdAt(x+1, y-1, z+1);
spawnState[1] = war.getServer().getBlockIdAt(x+1, y-1, z);
spawnState[2] = war.getServer().getBlockIdAt(x+1, y-1, z-1);
spawnState[3] = war.getServer().getBlockIdAt(x, y-1, z+1);
spawnState[4] = war.getServer().getBlockIdAt(x, y-1, z);
spawnState[5] = war.getServer().getBlockIdAt(x, y-1, z-1);
spawnState[6] = war.getServer().getBlockIdAt(x-1, y-1, z+1);
spawnState[7] = war.getServer().getBlockIdAt(x-1, y-1, z);
spawnState[8] = war.getServer().getBlockIdAt(x-1, y-1, z-1);
spawnState[9] = war.getServer().getBlockIdAt(x, y, z);
team.setTeamSpawn(location);
team.setOldSpawnState(spawnState);
// Set the spawn as gold blocks
war.getServer().setBlockAt(blockType, x+1, y-1, z+1);
war.getServer().setBlockAt(blockType, x+1, y-1, z);
war.getServer().setBlockAt(blockType, x+1, y-1, z-1);
war.getServer().setBlockAt(blockType, x, y-1, z+1);
war.getServer().setBlockAt(blockType, x, y-1, z);
war.getServer().setBlockAt(blockType, x, y-1, z-1);
war.getServer().setBlockAt(blockType, x-1, y-1, z+1);
war.getServer().setBlockAt(blockType, x-1, y-1, z);
war.getServer().setBlockAt(blockType, x-1, y-1, z-1);
Block block = new Block(63, x, y, z, 8);
war.getServer().setBlock(block);
block = war.getServer().getBlockAt(x, y, z);
ComplexBlock complexBlock = war.getServer().getComplexBlock(x, y, z);
Sign sign = (Sign)complexBlock;
sign.setText(0, "Team");
sign.setText(1, team.getName());
sign.setText(2, "spawn");
sign.update();
}
public boolean onDamage(PluginLoader.DamageType damageType, BaseEntity attacker, BaseEntity defender, int damageAmount) {
if(attacker != null && defender != null && attacker.isPlayer() && defender.isPlayer()) {
// only let adversaries (same warzone, different team) attack each other
Player a = attacker.getPlayer();
Player d = defender.getPlayer();
Warzone attackerWarzone = war.warzone(a.getLocation());
Team attackerTeam = war.getPlayerTeam(a.getName());
Warzone defenderWarzone = war.warzone(d.getLocation());
Team defenderTeam = war.getPlayerTeam(d.getName());
if(attackerTeam != null && defenderTeam != null
&& attackerTeam != defenderTeam
&& attackerWarzone == defenderWarzone) {
war.getLogger().log(Level.INFO, a.getName() + " hit " + d.getName() + " for " + damageAmount);
return false; // adversaries!
} else {
a.sendMessage(war.str("Your attack missed!"));
if(attackerTeam == null) {
a.sendMessage(war.str(" You must join a team " +
", then you'll be able to damage people " +
"in the other teams in that warzone."));
} else if (defenderTeam == null) {
a.sendMessage(war.str("Your target is not in a team."));
} else if (attackerTeam == defenderTeam) {
a.sendMessage(war.str("Your target is on your team."));
} else if (attackerWarzone != defenderWarzone) {
a.sendMessage(war.str("Your target is playing in another warzone."));
}
return true; // no pvp outside of the war battles, no friendly fire either
}
}
// mobs are always dangerous
return false;
}
public boolean onHealthChange(Player player, int before, int after) {
if(after <= 0) {
Team team = war.getPlayerTeam(player.getName());
if(team != null){
// teleport to team spawn upon death
Warzone zone = war.warzone(player.getLocation());
boolean roundOver = false;
synchronized(zone) {
int remaining = team.getRemainingTickets();
if(remaining == 0) { // your death caused your team to lose
List<Team> teams = zone.getTeams();
for(Team t : teams) {
t.teamcast(war.str(player.getName() + " died but team " + team.getName() + "'s life pool was empty. "));
t.teamcast(war.str("The battle is over. Team " + team.getName() + " lost. "));
t.teamcast(war.str("A new battle begins. Team life pools are being reset..."));
if(!t.getName().equals(team.getName())) {
// all other teams get a point
t.addPoint();
}
}
zone.resetState();
roundOver = true;
} else {
team.setRemainingTickets(remaining - 1);
}
}
if(!roundOver) {
zone.respawnPlayer(team, player);
player.sendMessage(war.str("You died!"));
List<Team> teams = zone.getTeams();
for(Team t : teams) {
t.teamcast(war.str(player.getName() + " died. Team " + team.getName() + " has " + team.getRemainingTickets() + "/" + War.LIFEPOOL + " lives left."));
if(team.getRemainingTickets() == 0) {
t.teamcast(war.str("Team " + team.getName() + "'s life pool is empty. One more death and they will lose!"));
}
}
war.getLogger().log(Level.INFO, player.getName() + " died and was tp'd back to team " + team.getName() + "'s spawn");
} else {
war.getLogger().log(Level.INFO, player.getName() + " died and battle ended in team " + team.getName() + "'s disfavor");
}
//return true;
}
}
return false;
}
public void onPlayerMove(Player player, Location from, Location to) {
Warzone playerWarzone = war.getPlayerWarzone(player.getName());
Team playerTeam = war.getPlayerTeam(player.getName());
if(player != null && from != null && to != null &&
playerTeam != null && !playerWarzone.contains(to)) {
player.sendMessage(war.str("Can't go outside the warzone boundary! Use /leave to exit the battle."));
if(playerWarzone.contains(from)){
player.teleportTo(from);
} else {
// somehow the player made it out of the zone
player.teleportTo(playerTeam.getTeamSpawn());
player.sendMessage(war.str("Brought you back to your team spawn. Use /leave to exit the battle."));
}
}
if(to != null && playerTeam != null
&& playerWarzone.nearAnyOwnedMonument(to, playerTeam)
&& random.nextInt(42) == 3 ) { // one chance out of many of getting healed
player.setHealth(30);
player.sendMessage(war.str("Your dance has awakened the monument's voodoo. You were granted full health!"));
}
}
private String getAllTeamsMsg(Player player){
String teamsMessage = "Teams: ";
if(war.warzone(player.getLocation()).getTeams().isEmpty()){
teamsMessage += "none.";
}
for(Team team : war.warzone(player.getLocation()).getTeams()) {
teamsMessage += team.getName() + " (" + team.getPoints() + " points, "+ team.getRemainingTickets() + "/" + War.LIFEPOOL + " lives left. ";
for(Player member : team.getPlayers()) {
teamsMessage += member.getName() + " ";
}
teamsMessage += ") ";
}
return teamsMessage;
}
public void onDisconnect(Player player) {
Team team = war.getPlayerTeam(player.getName());
if(team != null) {
team.removePlayer(player.getName());
}
}
public boolean onIgnite(Block block, Player player) {
if(player != null) {
Team team = war.getPlayerTeam(player.getName());
Warzone zone = war.getPlayerWarzone(player.getName());
if(team != null && block != null && zone != null && zone.isMonumentFirestone(block)) {
Monument monument = zone.getMonumentForFirestone(block);
if(!monument.hasOwner()) {
monument.ignite(team);
List<Team> teams = zone.getTeams();
for(Team t : teams) {
t.teamcast(war.str("Monument " + monument.getName() + " has been ignited by team " + team.getName() + "."));
}
} else {
player.sendMessage(war.str("Monument must be smothered first."));
}
}
}
return false;
}
public boolean onFlow(Block blockFrom, Block blockTo) {
Block block = null;
if(blockTo != null) {
block = blockTo;
} else if (blockFrom != null) {
block = blockFrom;
}
if(block != null) {
Warzone zone = war.warzone(new Location(block.getX(), block.getY(), block.getZ()));
if(zone != null &&
((blockTo != null && zone.isMonumentFirestone(blockTo)
|| (blockFrom != null && zone.isMonumentFirestone(blockFrom))))) {
Monument monument = null;
if(blockTo != null) monument = zone.getMonumentForFirestone(blockTo);
if(monument == null && blockFrom != null) monument = zone.getMonumentForFirestone(blockFrom);
if(monument.hasOwner()) {
monument.setOwnerTeam(null);
List<Team> teams = zone.getTeams();
for(Team team : teams) {
team.teamcast(war.str("Monument " + monument.getName() + " has been smothered."));
}
}
}
}
return false;
}
}

View File

@ -1,281 +0,0 @@
import java.util.ArrayList;
import java.util.List;
public class Warzone {
private String name;
private Location northwest;
private Location southeast;
private final List<Team> teams = new ArrayList<Team>();
private final List<Monument> monuments = new ArrayList<Monument>();
private final Server server;
private int[][][] initialState = null;
private Location teleport;
public Warzone(Server server, String name) {
this.server = server;
this.name = name;
}
public boolean ready() {
if(getNorthwest() != null && getSoutheast() != null
&& !tooSmall() && !tooBig()) return true;
return false;
}
public boolean tooSmall() {
if((getSoutheast().x - getNorthwest().x < 20)
|| (getNorthwest().z - getSoutheast().z < 20)) return true;
return false;
}
public boolean tooBig() {
if((getSoutheast().x - getNorthwest().x > 1000)
|| (getNorthwest().z - getSoutheast().z > 1000)) return true;
return false;
}
public boolean contains(Location point) {
return ready() && point.x <= getSoutheast().x && point.x >= getNorthwest().x
&& point.z <= getNorthwest().z && point.z >= getSoutheast().z;
}
public List<Team> getTeams() {
return teams;
}
public Team getPlayerTeam(String playerName) {
for(Team team : teams) {
for(Player player : team.getPlayers()) {
if(player.getName().equals(playerName)) {
return team;
}
}
}
return null;
}
public String getName() {
return name;
}
public void setNorthwest(Location northwest) {
// remove old nw sign, if any (replace with air)
if(this.northwest != null) {
int x = (int)this.northwest.x;
int y = (int)this.northwest.y;
int z = (int)this.northwest.z;
Block block = new Block(0, x, y, z);
server.setBlock(block);
}
this.northwest = northwest;
// add sign
int x = (int)northwest.x;
int y = (int)northwest.y;
int z = (int)northwest.z;
Block block = new Block(63, x, y, z, 10); // towards southeast
server.setBlock(block);
block = server.getBlockAt(x, y, z);
ComplexBlock complexBlock = server.getComplexBlock(x, y, z);
Sign sign = (Sign)complexBlock;
sign.setText(0, "Northwest");
sign.setText(1, "corner of");
sign.setText(2, "warzone");
sign.setText(3, name);
sign.update();
saveState();
}
public Location getNorthwest() {
return northwest;
}
public void setSoutheast(Location southeast) {
// remove old se sign, if any (replace with air)
if(this.southeast != null) {
int x = (int)this.southeast.x;
int y = (int)this.southeast.y;
int z = (int)this.southeast.z;
Block block = new Block(0, x, y, z);
server.setBlock(block);
}
this.southeast = southeast;
// add sign
int x = (int)southeast.x;
int y = (int)southeast.y;
int z = (int)southeast.z;
Block block = new Block(63, x, y, z, 2); // towards northwest
server.setBlock(block);
block = server.getBlockAt(x, y, z);
ComplexBlock complexBlock = server.getComplexBlock(x, y, z);
Sign sign = (Sign)complexBlock;
sign.setText(0, "Southeast");
sign.setText(1, "corner of");
sign.setText(2, "warzone");
sign.setText(3, name);
sign.update();
saveState();
}
public Location getSoutheast() {
return southeast;
}
public void setTeleport(Location location) {
this.teleport = location;
}
public Location getTeleport() {
return this.teleport;
}
public int saveState() {
if(ready()){
int northSouth = ((int)(southeast.x)) - ((int)(northwest.x));
int eastWest = ((int)(northwest.z)) - ((int)(southeast.z));
initialState = new int[northSouth][128][eastWest];
int noOfSavedBlocks = 0;
int x = (int)northwest.x;
int minY = 0;
int maxY = 128;
for(int i = 0; i < northSouth; i++){
int y = minY;
for(int j = 0; j < maxY - minY; j++) {
int z = (int)southeast.z;
for(int k = 0; k < eastWest; k++) {
initialState[i][j][k] = server.getBlockIdAt(x, y, z);
noOfSavedBlocks++;
z++;
}
y++;
}
x++;
}
return noOfSavedBlocks;
}
return 0;
}
/**
* Goes back to the saved state of the warzone (resets only block types, not physics).
* Also teleports all players back to their respective spawns.
* @return
*/
public int resetState() {
if(ready() && initialState != null){
// reset blocks
int northSouth = ((int)(southeast.x)) - ((int)(northwest.x));
int eastWest = ((int)(northwest.z)) - ((int)(southeast.z));
int noOfResetBlocks = 0;
int noOfFailures = 0;
int x = (int)northwest.x;
int minY = 0;
int maxY = 128;
for(int i = 0; i < northSouth; i++){
int y = minY;
for(int j = 0; j < maxY - minY; j++) {
int z = (int)southeast.z;
for(int k = 0; k < eastWest; k++) {
int currentType = server.getBlockIdAt(x, y, z);
int initialType = initialState[i][j][k];
if(currentType != initialType) {
if(server.setBlockAt(initialType,x, y, z)) {
noOfResetBlocks++;
} else {
noOfFailures++;
}
}
z++;
}
y++;
}
x++;
}
// everyone back to team spawn with full health
for(Team team : teams) {
for(Player player : team.getPlayers()) {
respawnPlayer(team, player);
}
team.setRemainingTickets(War.LIFEPOOL);
}
// reset monuments
for(Monument monument : monuments) {
monument.reset();
}
this.setNorthwest(this.getNorthwest());
this.setSoutheast(this.getSoutheast());
return noOfResetBlocks;
}
return 0;
}
public void endRound() {
}
public void respawnPlayer(Team team, Player player) {
Inventory playerInv = player.getInventory();
playerInv.clearContents();
playerInv.update();
playerInv.setSlot(new Item(Item.Type.StoneSword), 0);
playerInv.setSlot(new Item(Item.Type.Bow), 1);
playerInv.setSlot(new Item(Item.Type.Arrow, 12), 2);
playerInv.setSlot(new Item(Item.Type.StonePickaxe), 3);
playerInv.setSlot(new Item(Item.Type.StoneSpade), 4);
playerInv.addItem(new Item(Item.Type.Bread, 3));
playerInv.setSlot(new Item(Item.Type.LeatherBoots), 100);
playerInv.setSlot(new Item(Item.Type.LeatherLeggings), 101);
playerInv.setSlot(new Item(Item.Type.LeatherChestplate), 102);
playerInv.setSlot(new Item(Item.Type.LeatherHelmet), 103);
playerInv.update();
player.setHealth(30);
player.setFireTicks(0);
player.teleportTo(team.getTeamSpawn());
}
public boolean isMonumentFirestone(Block block) {
for(Monument monument : monuments) {
int x = (int)monument.getLocation().x;
int y = (int)monument.getLocation().y;
int z = (int)monument.getLocation().z;
if(x == block.getX() && y == block.getY() && z == block.getZ()) {
return true;
}
}
return false;
}
public Monument getMonumentForFirestone(Block block) {
for(Monument monument : monuments) {
int x = (int)monument.getLocation().x;
int y = (int)monument.getLocation().y;
int z = (int)monument.getLocation().z;
if(x == block.getX() && y == block.getY() && z == block.getZ()) {
return monument;
}
}
return null;
}
public boolean nearAnyOwnedMonument(Location to, Team team) {
for(Monument monument : monuments) {
if(monument.isNear(to) && monument.isOwner(team)) {
return true;
}
}
return false;
}
public List<Monument> getMomuments() {
return monuments;
}
}

137
war/pom.xml Normal file
View File

@ -0,0 +1,137 @@
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tommytony</groupId>
<artifactId>war</artifactId>
<version>2.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>War</name>
<url>http://war.tommytony.com</url>
<description>Minecraft PVP arenas (called warzones) for a fast-paced and structured PVP experience with TDM, CTF and more!</description>
<prerequisites>
<maven>2.2.1</maven>
</prerequisites>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>maven.cmastudios.me</id>
<url>https://maven.cmastudios.me/</url>
</repository>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
</repository>
<repository>
<id>sk89q-repo</id>
<url>https://maven.sk89q.com/repo/</url>
</repository>
</repositories>
<issueManagement>
<system>Github issues</system>
<url>https://github.com/taoneill/war/issues</url>
</issueManagement>
<scm>
<connection>scm:git:git://github.com/taoneill/war.git</connection>
<developerConnection>scm:git:git@github.com:taoneill/war.git</developerConnection>
<tag>HEAD</tag>
<url>https://github.com/taoneill/war</url>
</scm>
<distributionManagement>
<repository>
<id>maven.cmastudios.me</id>
<url>s3://maven.cmastudios.me/</url>
</repository>
</distributionManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.7.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>org.mcstats.bukkit:metrics</include>
</includes>
</artifactSet>
<minimizeJar>false</minimizeJar>
<relocations>
<relocation>
<pattern>org.mcstats</pattern>
<shadedPattern>com.tommytony.war.metrics</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<extensions>
<extension>
<groupId>org.kuali.maven.wagons</groupId>
<artifactId>maven-s3-wagon</artifactId>
<version>1.2.1</version>
</extension>
</extensions>
<resources>
<resource>
<filtering>true</filtering>
<directory>${basedir}/src/main/resources/</directory>
</resource>
</resources>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.13-R0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<type>jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.tommytony</groupId>
<artifactId>worldedit-bukkit</artifactId>
<version>7.0.0-beta-01</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.mcstats.bukkit</groupId>
<artifactId>metrics</artifactId>
<version>R8-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.milkbowl.vault</groupId>
<artifactId>Vault</artifactId>
<version>1.2.32</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,772 @@
package com.tommytony.war;
import com.tommytony.war.config.*;
import com.tommytony.war.utility.Direction;
import com.tommytony.war.volume.Volume;
import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.attribute.Attribute;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.Sign;
import java.io.File;
import java.text.MessageFormat;
import java.util.*;
import java.util.Map.Entry;
import java.util.logging.Level;
/**
*
* @author tommytony
*
*/
public class Team {
private final Warzone warzone;
Random teamSpawnRandomizer = new Random();
private List<Player> players = new ArrayList<Player>();
private List<Player> teamChatPlayers = new ArrayList<Player>();
private List<Location> teamSpawns;
private Location teamFlag = null;
private String name;
private int remainingLives;
private int points = 0;
private Map<Location, Volume> spawnVolumes;
private Volume flagVolume;
private TeamKind kind;
private TeamConfigBag teamConfig;
private InventoryBag inventories;
public Team(String name, TeamKind kind, List<Location> teamSpawn, Warzone warzone) {
this.warzone = warzone;
this.teamConfig = new TeamConfigBag(warzone);
this.inventories = new InventoryBag(warzone); // important constructors for cascading configs
this.setName(name);
this.teamSpawns = new ArrayList<Location>(teamSpawn);
this.spawnVolumes = new HashMap<Location, Volume>();
for (Location spawn : teamSpawn) {
this.setSpawnVolume(spawn, new Volume(name + teamSpawns.indexOf(spawn), warzone.getWorld()));
}
this.kind = kind;
this.setFlagVolume(null); // no flag at the start
}
public static Team getTeamByPlayerName(String playerName) {
for (Warzone warzone : War.war.getWarzones()) {
Team team = warzone.getPlayerTeam(playerName);
if (team != null) {
return team;
}
}
return null;
}
public Warzone getZone() {
return this.warzone;
}
public TeamKind getKind() {
return this.kind;
}
private void createSpawnVolume(Location teamSpawn) {
Volume spawnVolume = this.spawnVolumes.get(teamSpawn);
if (spawnVolume.isSaved()) {
spawnVolume.resetBlocks();
}
int x = teamSpawn.getBlockX();
int y = teamSpawn.getBlockY();
int z = teamSpawn.getBlockZ();
TeamSpawnStyle style = this.getTeamConfig().resolveSpawnStyle();
if (style.equals(TeamSpawnStyle.INVISIBLE)) {
spawnVolume.setCornerOne(this.warzone.getWorld().getBlockAt(x, y - 1, z));
spawnVolume.setCornerTwo(this.warzone.getWorld().getBlockAt(x, y + 3, z));
} else if (style.equals(TeamSpawnStyle.SMALL)) {
spawnVolume.setCornerOne(this.warzone.getWorld().getBlockAt(x - 1, y - 1, z - 1));
spawnVolume.setCornerTwo(this.warzone.getWorld().getBlockAt(x + 1, y + 3, z + 1));
} else {
// flat or big
spawnVolume.setCornerOne(this.warzone.getWorld().getBlockAt(x - 2, y - 1, z - 2));
spawnVolume.setCornerTwo(this.warzone.getWorld().getBlockAt(x + 2, y + 3, z + 2));
}
}
public void initializeTeamSpawns() {
for (Location teamSpawn : this.spawnVolumes.keySet()) {
initializeTeamSpawn(teamSpawn);
}
}
public void initializeTeamSpawn(Location teamSpawn) {
// Set the spawn
int x = teamSpawn.getBlockX();
int y = teamSpawn.getBlockY();
int z = teamSpawn.getBlockZ();
ItemStack light = this.warzone.getWarzoneMaterials().getLightBlock();
TeamSpawnStyle style = this.getTeamConfig().resolveSpawnStyle();
if (!style.equals(TeamSpawnStyle.INVISIBLE)) {
// first ring
this.setBlock(x + 1, y - 1, z + 1, this.kind);
this.setBlock(x + 1, y - 1, z, this.kind);
this.setBlock(x + 1, y - 1, z - 1, this.kind);
this.setBlock(x, y - 1, z + 1, this.kind);
BlockState lightBlock = this.warzone.getWorld().getBlockAt(x, y - 1, z).getState();
lightBlock.setType(light.getType());
lightBlock.setData(light.getData());
lightBlock.update(true);
this.setBlock(x, y - 1, z - 1, this.kind);
this.setBlock(x - 1, y - 1, z + 1, this.kind);
this.setBlock(x - 1, y - 1, z, this.kind);
this.setBlock(x - 1, y - 1, z - 1, this.kind);
}
// Orientation
int yaw = 0;
if (teamSpawn.getYaw() >= 0) {
yaw = (int) (teamSpawn.getYaw() % 360);
} else {
yaw = (int) (360 + (teamSpawn.getYaw() % 360));
}
Block signBlock = null;
BlockFace signDirection = null;
if (style.equals(TeamSpawnStyle.SMALL)) {
// SMALL style
if (yaw >= 0 && yaw < 90) {
signDirection = BlockFace.SOUTH_WEST.getOppositeFace();
signBlock = this.warzone.getWorld().getBlockAt(x, y, z).getRelative(Direction.NORTH()).getRelative(Direction.WEST());
} else if (yaw >= 90 && yaw <= 180) {
signDirection = BlockFace.NORTH_WEST.getOppositeFace();
signBlock = this.warzone.getWorld().getBlockAt(x, y, z).getRelative(Direction.NORTH()).getRelative(Direction.EAST());
} else if (yaw >= 180 && yaw < 270) {
signDirection = BlockFace.NORTH_EAST.getOppositeFace();
signBlock = this.warzone.getWorld().getBlockAt(x, y, z).getRelative(Direction.SOUTH()).getRelative(Direction.EAST());
} else if (yaw >= 270 && yaw <= 360) {
signDirection = BlockFace.SOUTH_EAST.getOppositeFace();
signBlock = this.warzone.getWorld().getBlockAt(x, y, z).getRelative(Direction.SOUTH()).getRelative(Direction.WEST());
}
} else if (!style.equals(TeamSpawnStyle.INVISIBLE)) {
// outer ring (FLAT or BIG)
this.setBlock(x + 2, y - 1, z + 2, this.kind);
this.setBlock(x + 2, y - 1, z + 1, this.kind);
this.setBlock(x + 2, y - 1, z, this.kind);
this.setBlock(x + 2, y - 1, z - 1, this.kind);
this.setBlock(x + 2, y - 1, z - 2, this.kind);
this.setBlock(x - 1, y - 1, z + 2, this.kind);
this.setBlock(x - 1, y - 1, z - 2, this.kind);
this.setBlock(x, y - 1, z + 2, this.kind);
this.setBlock(x, y - 1, z - 2, this.kind);
this.setBlock(x + 1, y - 1, z + 2, this.kind);
this.setBlock(x + 1, y - 1, z - 2, this.kind);
this.setBlock(x - 2, y - 1, z + 2, this.kind);
this.setBlock(x - 2, y - 1, z + 1, this.kind);
this.setBlock(x - 2, y - 1, z, this.kind);
this.setBlock(x - 2, y - 1, z - 1, this.kind);
this.setBlock(x - 2, y - 1, z - 2, this.kind);
if (yaw >= 0 && yaw < 90) {
signDirection = BlockFace.SOUTH_WEST.getOppositeFace();
signBlock = this.warzone.getWorld().getBlockAt(x, y, z).getRelative(Direction.NORTH(), 2).getRelative(Direction.WEST(), 2);
if (style.equals(TeamSpawnStyle.BIG)) {
// rim
this.setBlock(x - 2, y, z - 1, this.kind);
this.setBlock(x - 2, y, z - 2, this.kind);
this.setBlock(x - 1, y, z - 2, this.kind);
this.setBlock(x, y, z - 2, this.kind);
this.setBlock(x + 1, y, z - 2, this.kind);
this.setBlock(x + 2, y, z - 2, this.kind);
this.setBlock(x + 2, y, z - 1, this.kind);
this.setBlock(x + 2, y, z, this.kind);
this.setBlock(x + 2, y, z + 1, this.kind);
this.setBlock(x + 2, y, z + 2, this.kind);
this.setBlock(x + 1, y, z + 2, this.kind);
// tower
this.setBlock(x, y + 1, z - 2, this.kind);
this.setBlock(x + 1, y + 1, z - 2, this.kind);
this.setBlock(x + 2, y + 1, z - 2, this.kind);
this.setBlock(x + 2, y + 1, z - 1, this.kind);
this.setBlock(x + 2, y + 1, z, this.kind);
this.setBlock(x + 1, y + 2, z - 2, this.kind);
this.setBlock(x + 2, y + 2, z - 2, this.kind);
this.setBlock(x + 2, y + 2, z - 1, this.kind);
this.setBlock(x + 2, y + 3, z - 2, this.kind);
}
} else if (yaw >= 90 && yaw <= 180) {
signDirection = BlockFace.NORTH_WEST.getOppositeFace();
signBlock = this.warzone.getWorld().getBlockAt(x, y, z).getRelative(Direction.NORTH(), 2).getRelative(Direction.EAST(), 2);
if (style.equals(TeamSpawnStyle.BIG)) {
// rim
this.setBlock(x + 1, y, z - 2, this.kind);
this.setBlock(x + 2, y, z - 2, this.kind);
this.setBlock(x + 2, y, z - 1, this.kind);
this.setBlock(x + 2, y, z, this.kind);
this.setBlock(x + 2, y, z + 1, this.kind);
this.setBlock(x + 2, y, z + 2, this.kind);
this.setBlock(x + 1, y, z + 2, this.kind);
this.setBlock(x, y, z + 2, this.kind);
this.setBlock(x - 1, y, z + 2, this.kind);
this.setBlock(x - 2, y, z + 2, this.kind);
this.setBlock(x - 2, y, z + 1, this.kind);
// tower
this.setBlock(x + 2, y + 1, z, this.kind);
this.setBlock(x + 2, y + 1, z + 1, this.kind);
this.setBlock(x + 2, y + 1, z + 2, this.kind);
this.setBlock(x + 1, y + 1, z + 2, this.kind);
this.setBlock(x, y + 1, z + 2, this.kind);
this.setBlock(x + 2, y + 2, z + 1, this.kind);
this.setBlock(x + 2, y + 2, z + 2, this.kind);
this.setBlock(x + 1, y + 2, z + 2, this.kind);
this.setBlock(x + 2, y + 3, z + 2, this.kind);
}
} else if (yaw >= 180 && yaw < 270) {
signDirection = BlockFace.NORTH_EAST.getOppositeFace();
signBlock = this.warzone.getWorld().getBlockAt(x, y, z).getRelative(Direction.SOUTH(), 2).getRelative(Direction.EAST(), 2);
if (style.equals(TeamSpawnStyle.BIG)) {
// rim
this.setBlock(x + 2, y, z + 1, this.kind);
this.setBlock(x + 2, y, z + 2, this.kind);
this.setBlock(x + 1, y, z + 2, this.kind);
this.setBlock(x, y, z + 2, this.kind);
this.setBlock(x - 1, y, z + 2, this.kind);
this.setBlock(x - 2, y, z + 2, this.kind);
this.setBlock(x - 2, y, z + 1, this.kind);
this.setBlock(x - 2, y, z, this.kind);
this.setBlock(x - 2, y, z - 1, this.kind);
this.setBlock(x - 2, y, z - 2, this.kind);
this.setBlock(x - 1, y, z - 2, this.kind);
// tower
this.setBlock(x, y + 1, z + 2, this.kind);
this.setBlock(x - 1, y + 1, z + 2, this.kind);
this.setBlock(x - 2, y + 1, z + 2, this.kind);
this.setBlock(x - 2, y + 1, z + 1, this.kind);
this.setBlock(x - 2, y + 1, z, this.kind);
this.setBlock(x - 1, y + 2, z + 2, this.kind);
this.setBlock(x - 2, y + 2, z + 2, this.kind);
this.setBlock(x - 2, y + 2, z + 1, this.kind);
this.setBlock(x - 2, y + 3, z + 2, this.kind);
}
} else if (yaw >= 270 && yaw <= 360) {
signDirection = BlockFace.SOUTH_EAST.getOppositeFace();
signBlock = this.warzone.getWorld().getBlockAt(x, y, z).getRelative(Direction.SOUTH(), 2).getRelative(Direction.WEST(), 2);
if (style.equals(TeamSpawnStyle.BIG)) {
// rim
this.setBlock(x - 1, y, z + 2, this.kind);
this.setBlock(x - 2, y, z + 2, this.kind);
this.setBlock(x - 2, y, z + 1, this.kind);
this.setBlock(x - 2, y, z, this.kind);
this.setBlock(x - 2, y, z - 1, this.kind);
this.setBlock(x - 2, y, z - 2, this.kind);
this.setBlock(x - 1, y, z - 2, this.kind);
this.setBlock(x, y, z - 2, this.kind);
this.setBlock(x + 1, y, z - 2, this.kind);
this.setBlock(x + 2, y, z - 2, this.kind);
this.setBlock(x + 2, y, z - 1, this.kind);
// tower
this.setBlock(x - 2, y + 1, z, this.kind);
this.setBlock(x - 2, y + 1, z - 1, this.kind);
this.setBlock(x - 2, y + 1, z - 2, this.kind);
this.setBlock(x - 1, y + 1, z - 2, this.kind);
this.setBlock(x, y + 1, z - 2, this.kind);
this.setBlock(x - 2, y + 2, z - 1, this.kind);
this.setBlock(x - 2, y + 2, z - 2, this.kind);
this.setBlock(x - 1, y + 2, z - 2, this.kind);
this.setBlock(x - 2, y + 3, z - 2, this.kind);
}
}
}
if (signBlock != null) {
String[] lines;
if (this.getTeamConfig().resolveInt(TeamConfig.LIFEPOOL) == -1) {
lines = MessageFormat
.format(War.war.getString("sign.team.unlimited"),
this.name,
this.players.size(),
this.getTeamConfig().resolveInt(
TeamConfig.TEAMSIZE),
this.points,
this.getTeamConfig().resolveInt(
TeamConfig.MAXSCORE)).split("\n");
} else {
lines = MessageFormat
.format(War.war.getString("sign.team.limited"),
this.name,
this.players.size(),
this.getTeamConfig().resolveInt(
TeamConfig.TEAMSIZE),
this.points,
this.getTeamConfig().resolveInt(
TeamConfig.MAXSCORE),
this.remainingLives,
this.getTeamConfig().resolveInt(
TeamConfig.LIFEPOOL)).split("\n");
}
signBlock.setType(Material.SIGN);
org.bukkit.block.Sign block = (org.bukkit.block.Sign) signBlock
.getState();
org.bukkit.material.Sign data = (Sign) block.getData();
data.setFacingDirection(signDirection);
block.setData(data);
for (int i = 0; i < 4; i++) {
block.setLine(i, lines[i]);
}
block.update(true);
}
}
private void setBlock(int x, int y, int z, TeamKind kind) {
BlockState block = this.warzone.getWorld().getBlockAt(x, y, z).getState();
block.setType(kind.getMaterial());
block.update(true);
}
public void addTeamSpawn(Location teamSpawn) {
if (!this.teamSpawns.contains(teamSpawn)) {
this.teamSpawns.add(teamSpawn);
}
// this resets the block to old state
this.setSpawnVolume(teamSpawn, new Volume(name + teamSpawns.indexOf(teamSpawn), warzone.getWorld()));
this.createSpawnVolume(teamSpawn);
this.spawnVolumes.get(teamSpawn).saveBlocks();
this.initializeTeamSpawn(teamSpawn);
}
public List<Location> getTeamSpawns() {
return this.teamSpawns;
}
public Location getRandomSpawn() {
return this.teamSpawns.get(teamSpawnRandomizer.nextInt(this.teamSpawns.size()));
}
public void addPlayer(Player player) {
this.players.add(player);
if (this.warzone.getScoreboard() != null && this.warzone.getScoreboardType() != ScoreboardType.NONE) {
player.setScoreboard(this.warzone.getScoreboard());
}
warzone.updateScoreboard();
boolean cooldownEnabled = War.war.getWarConfig().getBoolean(WarConfig.DISABLECOOLDOWN);
if(cooldownEnabled) {
player.getAttribute(Attribute.GENERIC_ATTACK_SPEED).setBaseValue(1024.0);
} else {
player.getAttribute(Attribute.GENERIC_ATTACK_SPEED).setBaseValue(4.0);
}
}
public List<Player> getPlayers() {
return this.players;
}
public void teamcast(String message) {
// by default a teamcast is a notification
teamcast(message, true);
}
public void teamcast(String message, boolean isNotification) {
for (Player player : this.players) {
War.war.msg(player, message);
}
}
public void teamcast(String message, Object... args) {
// by default a teamcast is a notification
teamcast(message, true, args);
}
public void teamcast(String message, boolean isNotification, Object... args) {
for (Player player : this.players) {
War.war.msg(player, message, args);
}
}
/**
* Send an achievement to all players on the team.
* Currently implemented using SpoutCraft.
* @param line1 Achievement first line
* @param line2 Achievement second line
* @param icon Item to display in the achievement
* @param ticks Duration the achievement should be displayed
*/
public void sendAchievement(String line1, String line2, ItemStack icon, int ticks) {
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public void removePlayer(Player thePlayer) {
this.players.remove(thePlayer);
synchronized (teamChatPlayers) {
this.teamChatPlayers.remove(thePlayer);
}
this.warzone.dropAllStolenObjects(thePlayer, false);
thePlayer.setFireTicks(0);
thePlayer.setRemainingAir(300);
if (!this.warzone.getReallyDeadFighters().contains(thePlayer.getName())) {
this.warzone.restorePlayerState(thePlayer);
}
this.warzone.getLoadoutSelections().remove(thePlayer);
warzone.updateScoreboard();
thePlayer.getAttribute(Attribute.GENERIC_ATTACK_SPEED).setBaseValue(4.0);
}
public int getRemainingLives() {
return this.remainingLives;
}
public void setRemainingLives(int remainingLives) {
this.remainingLives = remainingLives;
warzone.updateScoreboard();
}
public void addPoint() {
boolean atLeastOnePlayerOnTeam = this.players.size() != 0;
boolean atLeastOnePlayerOnOtherTeam = false;
for (Team team : this.warzone.getTeams()) {
if (!team.getName().equals(this.getName()) && team.getPlayers().size() > 0) {
atLeastOnePlayerOnOtherTeam = true;
}
}
if (atLeastOnePlayerOnTeam && atLeastOnePlayerOnOtherTeam) {
this.points++;
} else if (!atLeastOnePlayerOnOtherTeam) {
this.teamcast("zone.score.empty");
}
this.warzone.updateScoreboard();
}
public int getPoints() {
return this.points;
}
public Map<Location, Volume> getSpawnVolumes() {
return this.spawnVolumes;
}
public void resetSign() {
for (Entry<Location, Volume> spawnEntry : this.getSpawnVolumes().entrySet()) {
spawnEntry.getValue().resetBlocks();
this.initializeTeamSpawn(spawnEntry.getKey()); // reset everything instead of just sign
}
if (this.warzone.getLobby() != null) {
this.warzone.getLobby().resetTeamGateSign(this);
}
if (War.war.getWarHub() != null) {
War.war.getWarHub().resetZoneSign(warzone);
}
}
public void setSpawnVolume(Location spawnLocation, Volume volume) {
this.spawnVolumes.put(spawnLocation, volume);
}
public void resetPoints() {
this.points = 0;
warzone.updateScoreboard();
}
public Volume getFlagVolume() {
return this.flagVolume;
}
public void setFlagVolume(Volume flagVolume) {
this.flagVolume = flagVolume;
}
private void setFlagVolume() {
if (this.flagVolume == null) {
this.flagVolume = new Volume(this.getName() + "flag", this.warzone.getWorld());
}
if (this.flagVolume.isSaved()) {
this.flagVolume.resetBlocks();
}
int x = this.teamFlag.getBlockX();
int y = this.teamFlag.getBlockY();
int z = this.teamFlag.getBlockZ();
this.flagVolume.setCornerOne(this.warzone.getWorld().getBlockAt(x - 1, y - 1, z - 1));
this.flagVolume.setCornerTwo(this.warzone.getWorld().getBlockAt(x + 1, y + 3, z + 1));
}
public void initializeTeamFlag() {
// make air (old two-high above floor)
Volume airGap = new Volume(new Location(this.flagVolume.getWorld(),
this.flagVolume.getCornerOne().getX(), this.flagVolume
.getCornerOne().getY() + 1, this.flagVolume
.getCornerOne().getZ()), new Location(
this.flagVolume.getWorld(), this.flagVolume.getCornerTwo()
.getX(), this.flagVolume.getCornerOne().getY() + 2,
this.flagVolume.getCornerTwo().getZ()));
airGap.setToMaterial(Material.AIR);
// Set the flag blocks
int x = this.teamFlag.getBlockX();
int y = this.teamFlag.getBlockY();
int z = this.teamFlag.getBlockZ();
// first ring
BlockState current = this.warzone.getWorld().getBlockAt(x + 1, y - 1, z + 1).getState();
current.setType(this.warzone.getWarzoneMaterials().getMainBlock().getType());
current.setData(this.warzone.getWarzoneMaterials().getMainBlock().getData());
current.update(true);
current = this.warzone.getWorld().getBlockAt(x + 1, y - 1, z).getState();
current.setType(this.warzone.getWarzoneMaterials().getMainBlock().getType());
current.setData(this.warzone.getWarzoneMaterials().getMainBlock().getData());
current.update(true);
current = this.warzone.getWorld().getBlockAt(x + 1, y - 1, z - 1).getState();
current.setType(this.warzone.getWarzoneMaterials().getMainBlock().getType());
current.setData(this.warzone.getWarzoneMaterials().getMainBlock().getData());
current.update(true);
current = this.warzone.getWorld().getBlockAt(x, y - 1, z + 1).getState();
current.setType(this.warzone.getWarzoneMaterials().getMainBlock().getType());
current.setData(this.warzone.getWarzoneMaterials().getMainBlock().getData());
current.update(true);
current = this.warzone.getWorld().getBlockAt(x, y - 1, z).getState();
current.setType(this.warzone.getWarzoneMaterials().getLightBlock().getType());
current.setData(this.warzone.getWarzoneMaterials().getLightBlock().getData());
current.update(true);
current = this.warzone.getWorld().getBlockAt(x, y - 1, z - 1).getState();
current.setType(this.warzone.getWarzoneMaterials().getMainBlock().getType());
current.setData(this.warzone.getWarzoneMaterials().getMainBlock().getData());
current.update(true);
current = this.warzone.getWorld().getBlockAt(x - 1, y - 1, z + 1).getState();
current.setType(this.warzone.getWarzoneMaterials().getMainBlock().getType());
current.setData(this.warzone.getWarzoneMaterials().getMainBlock().getData());
current.update(true);
current = this.warzone.getWorld().getBlockAt(x - 1, y - 1, z).getState();
current.setType(this.warzone.getWarzoneMaterials().getMainBlock().getType());
current.setData(this.warzone.getWarzoneMaterials().getMainBlock().getData());
current.update(true);
current = this.warzone.getWorld().getBlockAt(x - 1, y - 1, z - 1).getState();
current.setType(this.warzone.getWarzoneMaterials().getMainBlock().getType());
current.setData(this.warzone.getWarzoneMaterials().getMainBlock().getData());
current.update(true);
// flag
BlockState flagBlock = this.warzone.getWorld().getBlockAt(x, y + 1, z).getState();
flagBlock.setType(this.kind.getMaterial());
flagBlock.update(true);
// Flag post using Orientation
int yaw = 0;
if (this.teamFlag.getYaw() >= 0) {
yaw = (int) (this.teamFlag.getYaw() % 360);
} else {
yaw = (int) (360 + (this.teamFlag.getYaw() % 360));
}
if ((yaw >= 0 && yaw < 45) || (yaw >= 315 && yaw <= 360)) {
current = this.warzone.getWorld().getBlockAt(x, y, z - 1).getState();
current.setType(this.warzone.getWarzoneMaterials().getStandBlock().getType());
current.setData(this.warzone.getWarzoneMaterials().getStandBlock().getData());
current.update(true);
current = this.warzone.getWorld().getBlockAt(x, y + 1, z - 1).getState();
current.setType(this.warzone.getWarzoneMaterials().getStandBlock().getType());
current.setData(this.warzone.getWarzoneMaterials().getStandBlock().getData());
current.update(true);
} else if (yaw >= 45 && yaw < 135) {
current = this.warzone.getWorld().getBlockAt(x + 1, y, z).getState();
current.setType(this.warzone.getWarzoneMaterials().getStandBlock().getType());
current.setData(this.warzone.getWarzoneMaterials().getStandBlock().getData());
current.update(true);
current = this.warzone.getWorld().getBlockAt(x + 1, y + 1, z).getState();
current.setType(this.warzone.getWarzoneMaterials().getStandBlock().getType());
current.setData(this.warzone.getWarzoneMaterials().getStandBlock().getData());
current.update(true);
} else if (yaw >= 135 && yaw < 225) {
current = this.warzone.getWorld().getBlockAt(x, y, z + 1).getState();
current.setType(this.warzone.getWarzoneMaterials().getStandBlock().getType());
current.setData(this.warzone.getWarzoneMaterials().getStandBlock().getData());
current.update(true);
current = this.warzone.getWorld().getBlockAt(x, y + 1, z + 1).getState();
current.setType(this.warzone.getWarzoneMaterials().getStandBlock().getType());
current.setData(this.warzone.getWarzoneMaterials().getStandBlock().getData());
current.update(true);
} else if (yaw >= 225 && yaw < 315) {
current = this.warzone.getWorld().getBlockAt(x - 1, y, z).getState();
current.setType(this.warzone.getWarzoneMaterials().getStandBlock().getType());
current.setData(this.warzone.getWarzoneMaterials().getStandBlock().getData());
current.update(true);
current = this.warzone.getWorld().getBlockAt(x - 1, y + 1, z).getState();
current.setType(this.warzone.getWarzoneMaterials().getStandBlock().getType());
current.setData(this.warzone.getWarzoneMaterials().getStandBlock().getData());
current.update(true);
}
}
public boolean isTeamFlagBlock(Block block) {
if (this.teamFlag != null) {
int flagX = this.teamFlag.getBlockX();
int flagY = this.teamFlag.getBlockY() + 1;
int flagZ = this.teamFlag.getBlockZ();
if (block.getX() == flagX && block.getY() == flagY && block.getZ() == flagZ) {
return true;
}
}
return false;
}
public Location getTeamFlag() {
return this.teamFlag;
}
public void setTeamFlag(Location teamFlag) {
this.teamFlag = teamFlag;
// this resets the block to old state
this.setFlagVolume();
this.getFlagVolume().saveBlocks();
this.initializeTeamFlag();
}
public void deleteTeamFlag() {
this.getFlagVolume().resetBlocks();
this.setFlagVolume(null);
this.teamFlag = null;
// remove volume file
String filePath = War.war.getDataFolder().getPath() + "/dat/warzone-" + this.warzone.getName() + "/volume-" + this.getName() + "flag.dat";
if (!new File(filePath).delete()) {
War.war.log("Failed to delete file " + filePath, Level.WARNING);
}
}
public InventoryBag getInventories() {
return this.inventories ;
}
public TeamConfigBag getTeamConfig() {
return this.teamConfig;
}
/**
* Check if any team spawns contain a certain location.
*
* @param loc Location to check if contained by a spawn.
* @return true if loc is part of a spawn volume, false otherwise.
*/
public boolean isSpawnLocation(Location loc) {
for (Volume spawnVolume : this.spawnVolumes.values()) {
if (spawnVolume.contains(loc)) {
return true;
}
}
return false;
}
public boolean isFull() {
return this.getPlayers().size() == this.getTeamConfig().resolveInt(TeamConfig.TEAMSIZE);
}
/**
* Get an array of player usernames for players on this team.
*
* @return array of usernames.
*/
public List<String> getPlayerNames() {
List<String> ret = new ArrayList<String>(this.players.size());
for (Player player : this.players) {
ret.add(player.getName());
}
return ret;
}
/**
* Check if a player on this team can modify a certain type of block defined in the block whitelist.
*
* @param type Type of block to check.
* @return true if this block can be modified, false otherwise.
*/
public boolean canModify(Material type) {
for (String whitelistedBlock : this.getTeamConfig()
.resolveString(TeamConfig.BLOCKWHITELIST).split(",")) {
if (whitelistedBlock.equalsIgnoreCase("all")) {
return true;
}
if (type.toString().equalsIgnoreCase(whitelistedBlock)) {
return true;
}
}
return false;
}
/**
* Send a team chat message with proper formatting.
*
* @param sender Player sending the message
* @param message Message to send
*/
public void sendTeamChatMessage(OfflinePlayer sender, String message) {
String player = this.getKind().getColor() + ChatColor.stripColor(sender.getName()) + ChatColor.WHITE;
String output = String.format("%s: %s", player, message);
teamcast(output, false);
War.war.getLogger().info("[TeamChat] " + output);
}
/**
* Check if a player on this team has toggled on team chat. Thread safe.
*
* @param player Player to check
* @return true if the player has toggled on team chat
*/
public boolean isInTeamChat(Player player) {
synchronized (teamChatPlayers) {
return this.teamChatPlayers.contains(player);
}
}
/**
* Add a player to team chat. Thread safe.
* @param player Player to add
* @throws IllegalArgumentException Player is already in team chat
*/
public void addTeamChatPlayer(Player player) {
Validate.isTrue(!isInTeamChat(player), "Player is already in team chat");
synchronized (teamChatPlayers) {
this.teamChatPlayers.add(player);
}
}
/**
* Remove a player from team chat. Thread safe.
*
* @param player Player to remove
*/
public void removeTeamChatPlayer(Player player) {
synchronized (teamChatPlayers) {
this.teamChatPlayers.remove(player);
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,39 @@
package com.tommytony.war.command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
/**
* Represents a command that may only be used by War admins
*
*/
public abstract class AbstractOptionalWarAdminCommand extends AbstractWarCommand {
public AbstractOptionalWarAdminCommand(WarCommandHandler handler, CommandSender sender, String[] args, boolean mustBeWarAdmin) throws NotWarAdminException {
super(handler, sender, args);
if (mustBeWarAdmin && !isSenderWarAdmin()) {
throw new NotWarAdminException();
}
}
public boolean isSenderWarAdmin() {
if (this.getSender() instanceof Player) {
if (!War.war.isWarAdmin((Player) this.getSender())) {
return false;
} else {
return true;
}
} else if (!(this.getSender() instanceof ConsoleCommandSender)) {
return false;
} else {
// ConsoleCommandSender is admin
return true;
}
}
}

View File

@ -0,0 +1,60 @@
package com.tommytony.war.command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
/**
* Represents a command that may only used by zone makers or regular users
*
* @author tommytony
*/
public abstract class AbstractOptionalZoneMakerCommand extends AbstractWarCommand {
public AbstractOptionalZoneMakerCommand(WarCommandHandler handler, CommandSender sender, String[] args, boolean zoneMakersOnly) throws NotZoneMakerException {
super(handler, sender, args);
if (zoneMakersOnly && !this.isSenderZoneMaker()) {
throw new NotZoneMakerException();
}
}
public boolean isSenderZoneMaker() {
if (this.getSender() instanceof Player) {
// for players check War.isZoneMaker()
if (!War.war.isZoneMaker((Player) this.getSender())) {
return false;
} else {
return true;
}
} else if (!(this.getSender() instanceof ConsoleCommandSender)) {
return false;
} else {
// ConsoleCommandSender is admin
return true;
}
}
public boolean isSenderAuthorOfZone(Warzone zone) {
if (this.getSender() instanceof Player) {
if (War.war.isWarAdmin((Player) this.getSender())) {
// War admin has rights over all warzones
return true;
}
// Not War admin, is he author?
boolean isAuthor = zone.isAuthor((Player) this.getSender());
if (!isAuthor) {
War.war.badMsg(this.getSender(), "You can't do this because you are not an author of the " + zone.getName() + " warzone." );
}
return isAuthor;
} else {
// From console, you can do anything
return true;
}
}
}

View File

@ -0,0 +1,15 @@
package com.tommytony.war.command;
import org.bukkit.command.CommandSender;
/**
* Represents a command that may only be used by War admins
*
*/
public abstract class AbstractWarAdminCommand extends AbstractOptionalWarAdminCommand {
public AbstractWarAdminCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotWarAdminException {
super(handler, sender, args, true);
}
}

View File

@ -0,0 +1,102 @@
package com.tommytony.war.command;
import org.bukkit.command.CommandSender;
import com.tommytony.war.War;
/**
* Represents a war command
*
* @author Tim Düsterhus
*/
public abstract class AbstractWarCommand {
/**
* The sender of this command
*
* @var sender
*/
private CommandSender sender;
/**
* The arguments of this command
*
* @var args
*/
protected String[] args;
/**
* Instance of WarCommandHandler
*
* @var handler
*/
protected WarCommandHandler handler;
public AbstractWarCommand(WarCommandHandler handler, CommandSender sender, String[] args) {
this.handler = handler;
this.setSender(sender);
this.args = args;
}
/**
* Handles the command
*
* @return true if command was used the right way
*/
abstract public boolean handle();
/**
* Sends a success message
*
* @param message message to send
*/
public void msg(String message) {
War.war.msg(this.getSender(), message);
}
/**
* Sends a failure message
*
* @param message message to send
*/
public void badMsg(String message) {
War.war.badMsg(this.getSender(), message);
}
/**
* Sends a success message.
* @param message Message or key to translate
* @param args Arguments for the formatter
*/
public void msg(String message, Object... args) {
War.war.msg(this.getSender(), message, args);
}
/**
* Sends a failure message.
* @param message Message or key to translate
* @param args Arguments for the formatter
*/
public void badMsg(String message, Object... args) {
War.war.badMsg(this.getSender(), message, args);
}
/**
* Changes the command-sender
*
* @param sender new sender
*/
public void setSender(CommandSender sender) {
this.sender = sender;
}
/**
* Gets the command-sender
*
* @return Command-Sender
*/
public CommandSender getSender() {
return this.sender;
}
}

View File

@ -0,0 +1,16 @@
package com.tommytony.war.command;
import org.bukkit.command.CommandSender;
/**
* Represents a command that may only be used by zone makers
*
* @author Tim Düsterhus
*/
public abstract class AbstractZoneMakerCommand extends AbstractOptionalZoneMakerCommand {
public AbstractZoneMakerCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args, true);
}
}

View File

@ -0,0 +1,69 @@
package com.tommytony.war.command;
import java.util.logging.Level;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.Bomb;
import com.tommytony.war.structure.ZoneLobby;
/**
* Deletes a bomb.
*
* @author tommytony
*/
public class DeleteBombCommand extends AbstractZoneMakerCommand {
public DeleteBombCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
@Override
public boolean handle() {
Warzone zone;
if (this.args.length == 0) {
return false;
} else if (this.args.length == 2) {
zone = Warzone.getZoneByName(this.args[0]);
this.args[0] = this.args[1];
} else if (this.args.length == 1) {
if (!(this.getSender() instanceof Player)) {
return false;
}
zone = Warzone.getZoneByLocation((Player) this.getSender());
if (zone == null) {
ZoneLobby lobby = ZoneLobby.getLobbyByLocation((Player) this.getSender());
if (lobby == null) {
return false;
}
zone = lobby.getZone();
}
} else {
return false;
}
if (zone == null) {
return false;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
Bomb bomb = zone.getBomb(this.args[0]);
if (bomb != null) {
bomb.getVolume().resetBlocks();
zone.getBombs().remove(bomb);
WarzoneYmlMapper.save(zone);
this.msg("Bomb " + bomb.getName() + " removed.");
War.war.log(this.getSender().getName() + " deleted bomb " + bomb.getName() + " in warzone " + zone.getName(), Level.INFO);
} else {
this.badMsg("No such bomb.");
}
return true;
}
}

View File

@ -0,0 +1,69 @@
package com.tommytony.war.command;
import java.util.logging.Level;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.Cake;
import com.tommytony.war.structure.ZoneLobby;
/**
* Deletes a cake.
*
* @author tommytony
*/
public class DeleteCakeCommand extends AbstractZoneMakerCommand {
public DeleteCakeCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
@Override
public boolean handle() {
Warzone zone;
if (this.args.length == 0) {
return false;
} else if (this.args.length == 2) {
zone = Warzone.getZoneByName(this.args[0]);
this.args[0] = this.args[1];
} else if (this.args.length == 1) {
if (!(this.getSender() instanceof Player)) {
return false;
}
zone = Warzone.getZoneByLocation((Player) this.getSender());
if (zone == null) {
ZoneLobby lobby = ZoneLobby.getLobbyByLocation((Player) this.getSender());
if (lobby == null) {
return false;
}
zone = lobby.getZone();
}
} else {
return false;
}
if (zone == null) {
return false;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
Cake cake = zone.getCake(this.args[0]);
if (cake != null) {
cake.getVolume().resetBlocks();
zone.getCakes().remove(cake);
WarzoneYmlMapper.save(zone);
this.msg("Cake " + cake.getName() + " removed.");
War.war.log(this.getSender().getName() + " deleted cake " + cake.getName() + " in warzone " + zone.getName(), Level.INFO);
} else {
this.badMsg("No such cake.");
}
return true;
}
}

View File

@ -0,0 +1,68 @@
package com.tommytony.war.command;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.CapturePoint;
import com.tommytony.war.structure.Monument;
import com.tommytony.war.structure.ZoneLobby;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.logging.Level;
/**
* Deletes a capture point.
*
* @author Connor Monahan
*/
public class DeleteCapturePointCommand extends AbstractZoneMakerCommand {
public DeleteCapturePointCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
@Override
public boolean handle() {
Warzone zone;
if (this.args.length == 0) {
return false;
} else if (this.args.length == 2) {
zone = Warzone.getZoneByName(this.args[0]);
this.args[0] = this.args[1];
} else if (this.args.length == 1) {
if (!(this.getSender() instanceof Player)) {
return false;
}
zone = Warzone.getZoneByLocation((Player) this.getSender());
if (zone == null) {
ZoneLobby lobby = ZoneLobby.getLobbyByLocation((Player) this.getSender());
if (lobby == null) {
return false;
}
zone = lobby.getZone();
}
} else {
return false;
}
if (zone == null) {
return false;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
CapturePoint cp = zone.getCapturePoint(this.args[0]);
if (cp != null) {
cp.getVolume().resetBlocks();
zone.getCapturePoints().remove(cp);
WarzoneYmlMapper.save(zone);
this.msg("Capture point " + cp.getName() + " removed.");
War.war.log(this.getSender().getName() + " deleted capture point " + cp.getName() + " in warzone " + zone.getName(), Level.INFO);
} else {
this.badMsg("No such capture point.");
}
return true;
}
}

View File

@ -0,0 +1,69 @@
package com.tommytony.war.command;
import java.util.logging.Level;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.Monument;
import com.tommytony.war.structure.ZoneLobby;
/**
* Deletes a monument.
*
* @author Tim Düsterhus
*/
public class DeleteMonumentCommand extends AbstractZoneMakerCommand {
public DeleteMonumentCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
@Override
public boolean handle() {
Warzone zone;
if (this.args.length == 0) {
return false;
} else if (this.args.length == 2) {
zone = Warzone.getZoneByName(this.args[0]);
this.args[0] = this.args[1];
} else if (this.args.length == 1) {
if (!(this.getSender() instanceof Player)) {
return false;
}
zone = Warzone.getZoneByLocation((Player) this.getSender());
if (zone == null) {
ZoneLobby lobby = ZoneLobby.getLobbyByLocation((Player) this.getSender());
if (lobby == null) {
return false;
}
zone = lobby.getZone();
}
} else {
return false;
}
if (zone == null) {
return false;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
Monument monument = zone.getMonument(this.args[0]);
if (monument != null) {
monument.getVolume().resetBlocks();
zone.getMonuments().remove(monument);
WarzoneYmlMapper.save(zone);
this.msg("Monument " + monument.getName() + " removed.");
War.war.log(this.getSender().getName() + " deleted monument " + monument.getName() + " in warzone " + zone.getName(), Level.INFO);
} else {
this.badMsg("No such monument.");
}
return true;
}
}

View File

@ -0,0 +1,80 @@
package com.tommytony.war.command;
import java.util.logging.Level;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.Team;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.TeamKind;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.ZoneLobby;
import com.tommytony.war.volume.Volume;
/**
* Deletes a team.
*
* @author Tim Düsterhus
*/
public class DeleteTeamCommand extends AbstractZoneMakerCommand {
public DeleteTeamCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
@Override
public boolean handle() {
Warzone zone;
if (this.args.length == 0) {
return false;
} else if (this.args.length == 2) {
zone = Warzone.getZoneByName(this.args[0]);
this.args[0] = this.args[1];
} else if (this.args.length == 1) {
if (!(this.getSender() instanceof Player)) {
return false;
}
zone = Warzone.getZoneByLocation((Player) this.getSender());
if (zone == null) {
ZoneLobby lobby = ZoneLobby.getLobbyByLocation((Player) this.getSender());
if (lobby == null) {
return false;
}
zone = lobby.getZone();
}
} else {
return false;
}
if (zone == null) {
return false;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
Team team = zone.getTeamByKind(TeamKind.teamKindFromString(this.args[0]));
if (team != null) {
if (team.getFlagVolume() != null) {
team.getFlagVolume().resetBlocks();
}
for (Volume spawnVolume : team.getSpawnVolumes().values()) {
spawnVolume.resetBlocks();
}
zone.getTeams().remove(team);
if (zone.getLobby() != null) {
zone.getLobby().setLocation(zone.getTeleport());
zone.getLobby().initialize();
}
WarzoneYmlMapper.save(zone);
this.msg("Team " + team.getName() + " removed.");
War.war.log(this.getSender().getName() + " deleted team " + team.getName() + " in warzone " + zone.getName(), Level.INFO);
} else {
this.badMsg("No such team.");
}
return true;
}
}

View File

@ -0,0 +1,74 @@
package com.tommytony.war.command;
import java.util.logging.Level;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.Team;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.ZoneLobby;
/**
* Deletes a monument.
*
* @author Tim Düsterhus
*/
public class DeleteTeamFlagCommand extends AbstractZoneMakerCommand {
public DeleteTeamFlagCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
@Override
public boolean handle() {
Warzone zone;
if (this.args.length == 0) {
return false;
} else if (this.args.length == 2) {
zone = Warzone.getZoneByName(this.args[0]);
this.args[0] = this.args[1];
} else if (this.args.length == 1) {
if (!(this.getSender() instanceof Player)) {
return false;
}
zone = Warzone.getZoneByLocation((Player) this.getSender());
if (zone == null) {
ZoneLobby lobby = ZoneLobby.getLobbyByLocation((Player) this.getSender());
if (lobby == null) {
return false;
}
zone = lobby.getZone();
}
} else {
return false;
}
if (zone == null) {
return false;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
Team teamFlagTeam = null;
for (Team team : zone.getTeams()) {
if (team.getName().startsWith(this.args[0].toLowerCase())) {
teamFlagTeam = team;
}
}
if (teamFlagTeam != null) {
teamFlagTeam.deleteTeamFlag();
WarzoneYmlMapper.save(zone);
this.msg(teamFlagTeam.getName() + " flag removed.");
War.war.log(this.getSender().getName() + " deleted team " + teamFlagTeam.getName() + " flag in warzone " + zone.getName(), Level.INFO);
} else {
this.badMsg("No such team flag.");
}
return true;
}
}

View File

@ -0,0 +1,49 @@
package com.tommytony.war.command;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.mapper.VolumeMapper;
import com.tommytony.war.mapper.WarYmlMapper;
import com.tommytony.war.structure.WarHub;
import org.bukkit.command.CommandSender;
import java.util.logging.Level;
/**
* Deletes the warhub.
*
* @author Tim Düsterhus
*/
public class DeleteWarhubCommand extends AbstractWarAdminCommand {
public DeleteWarhubCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotWarAdminException {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (this.args.length != 0) {
return false;
}
if (War.war.getWarHub() != null) {
// reset existing hub
War.war.getWarHub().getVolume().resetBlocks();
VolumeMapper.deleteSimpleVolume(War.war.getWarHub().getVolume());
War.war.setWarHub((WarHub) null);
for (Warzone zone : War.war.getWarzones()) {
if (zone.getLobby() != null) {
zone.getLobby().getVolume().resetBlocks();
zone.getLobby().initialize();
}
}
this.msg("War hub removed.");
War.war.log(this.getSender().getName() + " deleted warhub", Level.INFO);
} else {
this.badMsg("No War hub to delete.");
}
WarYmlMapper.save();
return true;
}
}

View File

@ -0,0 +1,71 @@
package com.tommytony.war.command;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.mapper.WarYmlMapper;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.ZoneLobby;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.logging.Level;
/**
* Deletes a warzone.
*
* @author Tim Düsterhus
*/
public class DeleteZoneCommand extends AbstractZoneMakerCommand {
public DeleteZoneCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
public static void forceDeleteZone(Warzone zone, CommandSender sender) {
War.war.getWarzones().remove(zone);
WarYmlMapper.save();
WarzoneYmlMapper.delete(zone);
if (War.war.getWarHub() != null) { // warhub has to change
War.war.getWarHub().getVolume().resetBlocks();
War.war.getWarHub().initialize();
}
String msg = "Warzone " + zone.getName() + " removed by " + sender.getName() + ".";
War.war.log(msg, Level.INFO);
War.war.msg(sender, msg);
}
@Override
public boolean handle() {
Warzone zone;
if (this.args.length == 1) {
zone = Warzone.getZoneByName(this.args[0]);
} else if (this.args.length == 0) {
if (!(this.getSender() instanceof Player)) {
return false;
}
zone = Warzone.getZoneByLocation((Player) this.getSender());
if (zone == null) {
ZoneLobby lobby = ZoneLobby.getLobbyByLocation((Player) this.getSender());
if (lobby == null) {
return false;
}
zone = lobby.getZone();
}
} else {
return false;
}
if (zone == null) {
return false;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
forceDeleteZone(zone, getSender());
return true;
}
}

View File

@ -0,0 +1,95 @@
package com.tommytony.war.command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.Team;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.TeamKind;
import com.tommytony.war.config.WarzoneConfig;
import com.tommytony.war.structure.ZoneLobby;
/**
* Joins a team.
*
* @author Tim Düsterhus
*/
public class JoinCommand extends AbstractWarCommand {
public JoinCommand(WarCommandHandler handler, CommandSender sender, String[] args) {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (!(this.getSender() instanceof Player)) {
this.badMsg("command.console");
return true;
}
Player player = (Player) this.getSender();
Warzone zone;
TeamKind kind;
boolean signup = false;
if (this.args.length == 2) {
// zone by name
zone = Warzone.getZoneByName(this.args[0]);
kind = TeamKind.teamKindFromString(this.args[1]);
} else if (this.args.length == 3 && args[0].equals("delayed")) {
signup = true;
zone = Warzone.getZoneByName(this.args[1]);
kind = TeamKind.teamKindFromString(this.args[2]);
} else if (this.args.length == 1) {
zone = Warzone.getZoneByLocation((Player) this.getSender());
if (zone == null) {
ZoneLobby lobby = ZoneLobby.getLobbyByLocation((Player) this.getSender());
if (lobby == null) {
return false;
}
zone = lobby.getZone();
}
kind = TeamKind.teamKindFromString(this.args[0]);
} else {
return false;
}
if (zone == null) {
return false;
}
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.DISABLED)) {
this.badMsg("join.disabled");
} else if (zone.isReinitializing()) {
this.badMsg("join.disabled");
} else if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.AUTOASSIGN)) {
this.badMsg("join.aarequired");
} else if (!zone.getWarzoneConfig().getBoolean(WarzoneConfig.JOINMIDBATTLE) && zone.isEnoughPlayers()) {
this.badMsg("join.progress");
} else {
Team team = zone.getTeamByKind(kind);
if (kind == null || team == null) {
this.badMsg("join.team404");
} else if (!War.war.canPlayWar(player, team)) {
this.badMsg("join.permission.single");
} else if (team.isFull()) {
this.badMsg("join.full.single", team.getName());
} else {
Team previousTeam = Team.getTeamByPlayerName(player.getName());
if (previousTeam != null) {
if (previousTeam == team) {
this.badMsg("join.selfteam");
return true;
}
previousTeam.removePlayer(player);
previousTeam.resetSign();
}
if (signup && !zone.testEnoughPlayers(kind, false)) {
// player wants to automatically join the zone when everyone else is ready
zone.signup(player, team);
return true;
}
zone.assign(player, team);
}
}
return true;
}
}

View File

@ -0,0 +1,39 @@
package com.tommytony.war.command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.Warzone;
import com.tommytony.war.Warzone.LeaveCause;
/**
* Leaves a game.
*
* @author Tim Düsterhus
*/
public class LeaveCommand extends AbstractWarCommand {
public LeaveCommand(WarCommandHandler handler, CommandSender sender, String[] args) {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (!(this.getSender() instanceof Player)) {
this.badMsg("command.console");
return true;
}
if (this.args.length != 0) {
return false;
}
Player player = (Player) this.getSender();
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
if (zone == null) {
return false;
}
zone.handlePlayerLeave(player, zone.getEndTeleport(LeaveCause.COMMAND), true);
return true;
}
}

View File

@ -0,0 +1,28 @@
package com.tommytony.war.command;
import org.bukkit.command.CommandSender;
import com.tommytony.war.War;
/**
* Loads war.
*
* @author Tim Düsterhus
*/
public class LoadWarCommand extends AbstractWarAdminCommand {
public LoadWarCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotWarAdminException {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (this.args.length != 0) {
return false;
}
War.war.loadWar();
this.msg("War loaded.");
return true;
}
}

View File

@ -0,0 +1,55 @@
package com.tommytony.war.command;
import java.util.logging.Level;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.job.PartialZoneResetJob;
import com.tommytony.war.structure.ZoneLobby;
public class NextBattleCommand extends AbstractZoneMakerCommand {
public NextBattleCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
@Override
public boolean handle() {
Warzone zone;
if (this.args.length == 1) {
zone = Warzone.getZoneByName(this.args[0]);
} else if (this.args.length == 0) {
if (!(this.getSender() instanceof Player)) {
return false;
}
zone = Warzone.getZoneByLocation((Player) this.getSender());
if (zone == null) {
ZoneLobby lobby = ZoneLobby.getLobbyByLocation((Player) this.getSender());
if (lobby == null) {
return false;
}
zone = lobby.getZone();
}
} else {
return false;
}
if (zone == null) {
return false;
}
zone.clearThieves();
zone.broadcast("zone.battle.next", zone.getName());
PartialZoneResetJob.setSenderToNotify(zone, this.getSender());
zone.reinitialize();
War.war.log(this.getSender().getName() + " used nextbattle in warzone " + zone.getName(), Level.INFO);
return true;
}
}

View File

@ -0,0 +1,11 @@
package com.tommytony.war.command;
/**
* NotZoneMakerException is thrown when a player is no zonemaker.
*
* @author Tim Düsterhus
*/
public class NotWarAdminException extends Exception {
private static final long serialVersionUID = -5412011034665080340L;
}

View File

@ -0,0 +1,11 @@
package com.tommytony.war.command;
/**
* NotZoneMakerException is thrown when a player is no zonemaker.
*
* @author Tim Düsterhus
*/
public class NotZoneMakerException extends Exception {
private static final long serialVersionUID = -5412011034665080340L;
}

View File

@ -0,0 +1,117 @@
package com.tommytony.war.command;
import java.io.File;
import java.sql.SQLException;
import java.util.logging.Level;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.WarzoneConfig;
import com.tommytony.war.mapper.WarYmlMapper;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.ZoneLobby;
public class RenameZoneCommand extends AbstractZoneMakerCommand {
public RenameZoneCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
@Override
public boolean handle() {
Warzone zone;
if (this.args.length == 2) {
zone = Warzone.getZoneByName(this.args[0]);
this.args[0] = this.args[1];
} else if (this.args.length == 1) {
if (!(this.getSender() instanceof Player)) {
return false;
}
zone = Warzone.getZoneByLocation((Player) this.getSender());
if (zone == null) {
ZoneLobby lobby = ZoneLobby.getLobbyByLocation((Player) this.getSender());
if (lobby == null) {
return false;
}
zone = lobby.getZone();
}
} else {
return false;
}
if (zone == null) {
return false;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
// Kill old warzone, but use it to create the renamed copy
zone.unload();
zone.getVolume().resetBlocks(); // We're going to use the blocks to save the new copy, reset to base state.
String newName = this.args[0];
String oldName = zone.getName();
// Update the name
zone.setName(newName);
zone.saveState(false); // Save new volume files. Don't clear anything, we already unloaded.
WarzoneYmlMapper.save(zone); // Save new config files for warzone.
// Get rid of old unloaded zone instance
War.war.getWarzones().remove(zone);
// Move old files
(new File(War.war.getDataFolder().getPath() + "/temp/renamed/")).mkdir();
(new File(War.war.getDataFolder().getPath() + "/warzone-" + oldName + ".yml")).renameTo(new File(War.war.getDataFolder().getPath() + "/temp/renamed/warzone-" + oldName + ".yml"));
(new File(War.war.getDataFolder().getPath() + "/temp/renamed/dat/warzone-" + oldName)).mkdirs();
String oldPath = War.war.getDataFolder().getPath() + "/dat/warzone-" + oldName + "/";
File oldZoneFolder = new File(oldPath);
File[] oldZoneFiles = oldZoneFolder.listFiles();
for (File file : oldZoneFiles) {
file.renameTo(new File(War.war.getDataFolder().getPath() + "/temp/renamed/dat/warzone-" + oldName + "/" + file.getName()));
}
oldZoneFolder.delete();
// Load new warzone
War.war.log("Loading zone " + newName + "...", Level.INFO);
Warzone newZone = WarzoneYmlMapper.load(newName);
War.war.getWarzones().add(newZone);
try {
newZone.getVolume().loadCorners();
} catch (SQLException ex) {
War.war.log("Failed to load warzone " + newZone.getName() + ": " + ex.getMessage(), Level.WARNING);
throw new RuntimeException(ex);
}
try {
zone.getVolume().loadCorners();
} catch (SQLException ex) {
War.war.log("Failed to load warzone " + zone.getName() + ": " + ex.getMessage(), Level.WARNING);
throw new RuntimeException(ex);
}
if (zone.getLobby() != null) {
zone.getLobby().getVolume().resetBlocks();
}
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.RESETONLOAD)) {
zone.getVolume().resetBlocks();
}
newZone.initializeZone();
// Update war config
WarYmlMapper.save();
if (War.war.getWarHub() != null) { // warhub has to change
War.war.getWarHub().getVolume().resetBlocks();
War.war.getWarHub().initialize();
}
War.war.log(this.getSender().getName() + " renamed warzone " + oldName + " to " + newName, Level.INFO);
this.msg("Warzone " + oldName + " renamed to " + newName + ".");
return true;
}
}

View File

@ -0,0 +1,77 @@
package com.tommytony.war.command;
import com.tommytony.war.Team;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.Warzone.LeaveCause;
import com.tommytony.war.job.PartialZoneResetJob;
import com.tommytony.war.structure.ZoneLobby;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.Iterator;
import java.util.logging.Level;
public class ResetZoneCommand extends AbstractZoneMakerCommand {
public ResetZoneCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
public static void forceResetZone(Warzone zone, CommandSender sender) {
zone.clearThieves();
for (Team team : zone.getTeams()) {
team.teamcast("The war has ended. " + zone.getTeamInformation() + " Resetting warzone " + zone.getName() + " and teams...");
for (Iterator<Player> it = team.getPlayers().iterator(); it.hasNext(); ) {
Player p = it.next();
it.remove();
team.removePlayer(p);
if (!zone.getReallyDeadFighters().contains(p.getName())) {
p.teleport(zone.getEndTeleport(LeaveCause.RESET));
}
}
team.resetPoints();
team.getPlayers().clear();
}
War.war.msg(sender, "Reloading warzone " + zone.getName() + ".");
PartialZoneResetJob.setSenderToNotify(zone, sender);
zone.reinitialize();
War.war.log(sender.getName() + " reset warzone " + zone.getName(), Level.INFO);
}
@Override
public boolean handle() {
Warzone zone;
if (this.args.length == 1) {
zone = Warzone.getZoneByName(this.args[0]);
} else if (this.args.length == 0) {
if (!(this.getSender() instanceof Player)) {
return false;
}
zone = Warzone.getZoneByLocation((Player) this.getSender());
if (zone == null) {
ZoneLobby lobby = ZoneLobby.getLobbyByLocation((Player) this.getSender());
if (lobby == null) {
return false;
}
zone = lobby.getZone();
}
} else {
return false;
}
if (zone == null) {
return false;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
forceResetZone(zone, this.getSender());
return true;
}
}

View File

@ -0,0 +1,161 @@
package com.tommytony.war.command;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.WarConfig;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.ZoneLobby;
public class SaveZoneCommand extends AbstractZoneMakerCommand {
public SaveZoneCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
@Override
public boolean handle() {
Warzone zone = null;
CommandSender commandSender = this.getSender();
boolean isFirstParamWarzone = false;
if (this.args.length > 0 && !this.args[0].contains(":")) {
// warzone name maybe in first place
Warzone zoneByName = Warzone.getZoneByName(this.args[0]);
if (zoneByName != null) {
zone = zoneByName;
isFirstParamWarzone = true;
}
}
if (this.getSender() instanceof Player) {
Player player = (Player) commandSender;
Warzone zoneByLoc = Warzone.getZoneByLocation(player);
ZoneLobby lobbyByLoc = ZoneLobby.getLobbyByLocation(player);
if (zoneByLoc == null && lobbyByLoc != null) {
zoneByLoc = lobbyByLoc.getZone();
}
if (zoneByLoc != null) {
zone = zoneByLoc;
}
}
if (zone == null) {
// No warzone found, whatever the mean, escape
return false;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
if (isFirstParamWarzone) {
if (this.args.length > 1) {
// More than one param: the arguments need to be shifted
String[] newargs = new String[this.args.length - 1];
for (int i = 1; i < this.args.length; i++) {
newargs[i - 1] = this.args[i];
}
this.args = newargs;
}
}
// We have a warzone and indexed-from-0 arguments
if (War.war.getWarConfig().getBoolean(WarConfig.KEEPOLDZONEVERSIONS)) {
// Keep a copy of the old version, just in case. First, find the version number
File oldVersionsFolder = new File(War.war.getDataFolder().getPath() + "/temp/oldversions/warzone-" + zone.getName());
oldVersionsFolder.mkdirs();
File[] versionFolders = oldVersionsFolder.listFiles();
int newVersion = versionFolders.length + 1;
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
String newVersionString = format.format(new Date()) + "-" + newVersion;
String newVersionPath = War.war.getDataFolder().getPath() + "/temp/oldversions/warzone-" + zone.getName() + "/" + newVersionString;
File newVersionFolder = new File(newVersionPath);
newVersionFolder.mkdir();
// Copy all warzone files to new version folder before they get overwritten
try {
copyFile(new File(War.war.getDataFolder().getPath() + "/warzone-" + zone.getName() + ".yml"), new File(newVersionPath + "/warzone-" + zone.getName() + ".yml"));
(new File(newVersionPath + "/dat/warzone-" + zone.getName())).mkdirs();
String oldPath = War.war.getDataFolder().getPath() + "/dat/warzone-" + zone.getName() + "/";
File currentZoneFolder = new File(oldPath);
File[] currentZoneFiles = currentZoneFolder.listFiles();
for (File file : currentZoneFiles) {
copyFile(file, new File(newVersionPath + "/dat/warzone-" + zone.getName() + "/" + file.getName()));
}
} catch (IOException badCopy) {
War.war.log("Failed to make backup copy version " + newVersion + " of warzone " + zone.getName(), Level.WARNING);
}
int currentVersion = newVersion + 1;
this.msg("Saving version " + currentVersion + " of warzone " + zone.getName());
War.war.log(this.getSender().getName() + " is saving version " + currentVersion + " of warzone " + zone.getName(), Level.INFO);
} else {
this.msg("Saving new permanent version of warzone " + zone.getName());
War.war.log(this.getSender().getName() + " is saving new permanent version of warzone " + zone.getName(), Level.INFO);
}
// Let's save the new version update
int savedBlocks = zone.saveState(true);
// changed settings: must reinitialize with new settings
String namedParamResult = War.war.updateZoneFromNamedParams(zone, commandSender, this.args);
WarzoneYmlMapper.save(zone);
if (this.args.length > 0) {
// the config may have changed, requiring a reset for spawn styles etc.
zone.getVolume().resetBlocks();
}
if (zone.getLobby() != null) {
zone.getLobby().getVolume().resetBlocks();
}
zone.initializeZone(); // bring back team spawns etc
if (War.war.getWarHub() != null) { // maybe the zone was disabled/enabled
War.war.getWarHub().getVolume().resetBlocks();
War.war.getWarHub().initialize();
}
this.msg("Saved " + savedBlocks + " blocks in warzone " + zone.getName() + "." + namedParamResult);
if (namedParamResult != null && namedParamResult.length() > 0) {
War.war.log(this.getSender().getName() + " also updated warzone " + zone.getName() + " configuration." + namedParamResult, Level.INFO);
}
return true;
}
public static void copyFile(File sourceFile, File destFile) throws IOException {
if(!destFile.exists()) {
destFile.createNewFile();
}
FileChannel source = null;
FileChannel destination = null;
try {
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destFile).getChannel();
destination.transferFrom(source, 0, source.size());
}
finally {
if(source != null) {
source.close();
}
if(destination != null) {
destination.close();
}
}
}
}

View File

@ -0,0 +1,68 @@
package com.tommytony.war.command;
import java.util.logging.Level;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.Bomb;
/**
* Places a bomb
*
* @author tommytony
*/
public class SetBombCommand extends AbstractZoneMakerCommand {
public SetBombCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (!(this.getSender() instanceof Player)) {
this.badMsg("You can't do this if you are not in-game.");
return true;
}
Player player = (Player) this.getSender();
if (this.args.length != 1) {
return false;
}
Warzone zone = Warzone.getZoneByLocation(player);
if (zone == null) {
return false;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
if (this.args[0].equals(zone.getName())) {
return false;
}
if (zone.hasBomb(this.args[0])) {
// move the existing bomb
Bomb bomb = zone.getBomb(this.args[0]);
bomb.getVolume().resetBlocks();
bomb.setLocation(player.getLocation());
this.msg("Bomb " + bomb.getName() + " was moved.");
War.war.log(this.getSender().getName() + " moved bomb " + bomb.getName() + " in warzone " + zone.getName(), Level.INFO);
} else {
// create a new bomb
Bomb bomb = new Bomb(this.args[0], zone, player.getLocation());
zone.getBombs().add(bomb);
this.msg("Bomb " + bomb.getName() + " created.");
War.war.log(this.getSender().getName() + " created bomb " + bomb.getName() + " in warzone " + zone.getName(), Level.INFO);
}
WarzoneYmlMapper.save(zone);
return true;
}
}

View File

@ -0,0 +1,68 @@
package com.tommytony.war.command;
import java.util.logging.Level;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.Cake;
/**
* Places a cake
*
* @author tommytony
*/
public class SetCakeCommand extends AbstractZoneMakerCommand {
public SetCakeCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (!(this.getSender() instanceof Player)) {
this.badMsg("You can't do this if you are not in-game.");
return true;
}
Player player = (Player) this.getSender();
if (this.args.length != 1) {
return false;
}
Warzone zone = Warzone.getZoneByLocation(player);
if (zone == null) {
return false;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
if (this.args[0].equals(zone.getName())) {
return false;
}
if (zone.hasCake(this.args[0])) {
// move the existing cake
Cake cake = zone.getCake(this.args[0]);
cake.getVolume().resetBlocks();
cake.setLocation(player.getLocation());
this.msg("Cake " + cake.getName() + " was moved.");
War.war.log(this.getSender().getName() + " moved cake " + cake.getName() + " in warzone " + zone.getName(), Level.INFO);
} else {
// create a new cake
Cake cake = new Cake(this.args[0], zone, player.getLocation());
zone.getCakes().add(cake);
this.msg("Cake " + cake.getName() + " created.");
War.war.log(this.getSender().getName() + " created cake " + cake.getName() + " in warzone " + zone.getName(), Level.INFO);
}
WarzoneYmlMapper.save(zone);
return true;
}
}

View File

@ -0,0 +1,77 @@
package com.tommytony.war.command;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.TeamKind;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.CapturePoint;
import com.tommytony.war.structure.Monument;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.logging.Level;
/**
* Sets a capture point
*
* @author Connor Monahan
*/
public class SetCapturePointCommand extends AbstractZoneMakerCommand {
public SetCapturePointCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (!(this.getSender() instanceof Player)) {
this.badMsg("You can't do this if you are not in-game.");
return true;
}
Player player = (Player) this.getSender();
if (this.args.length < 1) {
return false;
}
Warzone zone = Warzone.getZoneByLocation(player);
if (zone == null) {
return false;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
if (this.args[0].equals(zone.getName())) {
return false;
}
if (zone.hasCapturePoint(this.args[0])) {
// move the existing capture point
CapturePoint cp = zone.getCapturePoint(this.args[0]);
cp.getVolume().resetBlocks();
cp.setLocation(player.getLocation());
this.msg("Capture point " + cp.getName() + " was moved.");
War.war.log(this.getSender().getName() + " moved capture point " + cp.getName() + " in warzone " + zone.getName(), Level.INFO);
} else {
// create a new capture point
TeamKind controller = null;
int strength = 0;
if (args.length > 1) {
controller = TeamKind.teamKindFromString(args[1]);
strength = 4;
if (controller == null || zone.getTeamByKind(controller) == null) {
this.badMsg("Failed to create capture point: team {0} does not exist", args[1]);
return true;
}
}
CapturePoint cp = new CapturePoint(this.args[0], player.getLocation(), controller, strength, zone);
zone.getCapturePoints().add(cp);
War.war.log(this.getSender().getName() + " created capture point " + cp.getName() + " in warzone " + zone.getName(), Level.INFO);
}
WarzoneYmlMapper.save(zone);
return true;
}
}

View File

@ -0,0 +1,67 @@
package com.tommytony.war.command;
import java.util.logging.Level;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.Monument;
/**
* Places a monument
*
* @author Tim Düsterhus
*/
public class SetMonumentCommand extends AbstractZoneMakerCommand {
public SetMonumentCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (!(this.getSender() instanceof Player)) {
this.badMsg("You can't do this if you are not in-game.");
return true;
}
Player player = (Player) this.getSender();
if (this.args.length != 1) {
return false;
}
Warzone zone = Warzone.getZoneByLocation(player);
if (zone == null) {
return false;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
if (this.args[0].equals(zone.getName())) {
return false;
}
if (zone.hasMonument(this.args[0])) {
// move the existing monument
Monument monument = zone.getMonument(this.args[0]);
monument.getVolume().resetBlocks();
monument.setLocation(player.getLocation());
this.msg("Monument " + monument.getName() + " was moved.");
War.war.log(this.getSender().getName() + " moved monument " + monument.getName() + " in warzone " + zone.getName(), Level.INFO);
} else {
// create a new monument
Monument monument = new Monument(this.args[0], zone, player.getLocation());
zone.getMonuments().add(monument);
War.war.log(this.getSender().getName() + " created monument " + monument.getName() + " in warzone " + zone.getName(), Level.INFO);
}
WarzoneYmlMapper.save(zone);
return true;
}
}

View File

@ -0,0 +1,78 @@
package com.tommytony.war.command;
import java.util.logging.Level;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.Team;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.TeamConfig;
import com.tommytony.war.config.TeamKind;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import java.util.Collections;
import org.bukkit.Location;
/**
* Places a soawn
*
* @author Tim Düsterhus
*/
public class SetTeamCommand extends AbstractZoneMakerCommand {
public SetTeamCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (!(this.getSender() instanceof Player)) {
this.badMsg("You can't do this if you are not in-game.");
return true;
}
Player player = (Player) this.getSender();
if (this.args.length != 1) {
return false;
}
Warzone zone = Warzone.getZoneByLocation(player);
if (zone == null) {
return false;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
TeamKind teamKind = TeamKind.teamKindFromString(this.args[0]);
if (teamKind == null) {
return false;
} else {
Team existingTeam = zone.getTeamByKind(teamKind);
if (existingTeam != null) {
// add additional spawn
existingTeam.addTeamSpawn(player.getLocation());
this.msg("Additional spawn added for team " + existingTeam.getName() + ". Use /deleteteam " + existingTeam.getName() + " to remove all spawns.");
War.war.log(this.getSender().getName() + " moved team " + existingTeam.getName() + " in warzone " + zone.getName(), Level.INFO);
} else {
// new team (use default TeamKind name for now)
Team newTeam = new Team(teamKind.toString(), teamKind, Collections.<Location>emptyList(), zone);
newTeam.setRemainingLives(newTeam.getTeamConfig().resolveInt(TeamConfig.LIFEPOOL));
zone.getTeams().add(newTeam);
if (zone.getLobby() != null) {
zone.getLobby().setLocation(zone.getTeleport());
zone.getLobby().initialize();
}
newTeam.addTeamSpawn(player.getLocation());
this.msg("Team " + newTeam.getName() + " created with spawn here.");
War.war.log(this.getSender().getName() + " created team " + newTeam.getName() + " in warzone " + zone.getName(), Level.INFO);
}
}
WarzoneYmlMapper.save(zone);
return true;
}
}

View File

@ -0,0 +1,154 @@
package com.tommytony.war.command;
import java.util.logging.Level;
import com.tommytony.war.config.TeamConfigBag;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.Team;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.TeamKind;
import com.tommytony.war.config.WarzoneConfig;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.ZoneLobby;
public class SetTeamConfigCommand extends AbstractOptionalZoneMakerCommand {
public SetTeamConfigCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args, false);
}
@Override
public boolean handle() {
Warzone zone = null;
Player player = null;
CommandSender commandSender = this.getSender();
boolean isFirstParamWarzone = false;
boolean wantsToPrint = false;
Team team = null;
if (this.args.length == 0) {
return false;
} else {
if (!this.args[0].contains(":")) {
// warzone name maybe in first place
Warzone zoneByName = Warzone.getZoneByName(this.args[0]);
if (zoneByName != null) {
zone = zoneByName;
isFirstParamWarzone = true;
} else if (this.args[0].equals("-p") || this.args[0].equals("print")) {
wantsToPrint = true;
}
}
if (this.getSender() instanceof Player) {
player = (Player) commandSender;
if (zone == null) {
// zone not found, is he standing in it?
Warzone zoneByLoc = Warzone.getZoneByLocation(player);
ZoneLobby lobbyByLoc = ZoneLobby.getLobbyByLocation(player);
if (zoneByLoc == null && lobbyByLoc != null) {
zoneByLoc = lobbyByLoc.getZone();
}
if (zoneByLoc != null) {
zone = zoneByLoc;
}
}
team = Team.getTeamByPlayerName(player.getName());
}
if (zone == null) {
// No warzone found, whatever the mean, escape
return false;
}
if (isFirstParamWarzone) {
if (this.args.length == 1) {
// Only one param: the warzone name - pritn usage
return false;
}
// More than one param: the arguments need to be shifted
String[] newargs = new String[this.args.length - 1];
for (int i = 1; i < this.args.length; i++) {
newargs[i - 1] = this.args[i];
}
this.args = newargs;
}
// args have been shifted if needed
if (this.args.length > 0) {
TeamKind kind = TeamKind.teamKindFromString(this.args[0]);
Team teamByName = zone.getTeamByKind(kind);
if (team == null && teamByName == null) {
// Team not found
this.badMsg("No such team. Use /teams.");
return true;
} else if (this.args.length == 1 && teamByName != null) {
// only team name, print config
this.msg(War.war.printConfig(teamByName));
return true;
}
if (teamByName != null) {
// first param was team, shift again
String[] newargs = new String[this.args.length - 1];
for (int i = 1; i < this.args.length; i++) {
newargs[i - 1] = this.args[i];
}
this.args = newargs;
}
if (teamByName != null) {
// Named team > player's team
team = teamByName;
}
} else {
// No team param, show usage
return false;
}
if (this.args.length > 0 && (this.args[0].equals("-p") || this.args[0].equals("print"))) {
// only printing
if (this.args.length == 1) {
this.msg(War.war.printConfig(team));
return true;
} else {
// first param was to print, shift again
String[] newargs = new String[this.args.length - 1];
for (int i = 1; i < this.args.length; i++) {
newargs[i - 1] = this.args[i];
}
this.args = newargs;
}
wantsToPrint = true;
}
if (!this.isSenderZoneMaker()) {
War.war.badMsg(this.getSender(), "You can't do this if you are not a warzone maker (permission war.zonemaker).");
return true;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
// We have a warzone, a team and indexed-from-0 arguments, let's update
String namedParamReturn = War.war.updateTeamFromNamedParams(team, player, this.args);
if (!namedParamReturn.equals("") && !namedParamReturn.equals("PARSE-ERROR")) {
TeamConfigBag.afterUpdate(team, player, namedParamReturn, wantsToPrint);
} else if (namedParamReturn.equals("PARSE-ERROR")) {
this.badMsg("Failed to read named parameter(s).");
} else {
// empty return means no param was parsed - print command usage
return false;
}
return true;
}
}
}

View File

@ -0,0 +1,72 @@
package com.tommytony.war.command;
import java.util.logging.Level;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.Team;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.TeamKind;
import com.tommytony.war.mapper.WarzoneYmlMapper;
/**
* Places a teamflag
*
* @author Tim Düsterhus
*/
public class SetTeamFlagCommand extends AbstractZoneMakerCommand {
public SetTeamFlagCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (!(this.getSender() instanceof Player)) {
this.badMsg("You can't do this if you are not in-game.");
return true;
}
Player player = (Player) this.getSender();
if (this.args.length != 1) {
return false;
}
Warzone zone = Warzone.getZoneByLocation(player);
if (zone == null) {
return false;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
TeamKind kind = TeamKind.teamKindFromString(this.args[0]);
Team team = zone.getTeamByKind(kind);
if (team == null) {
// no such team yet
this.msg("Place the team spawn first.");
} else if (team.getFlagVolume() == null) {
// new team flag
team.setTeamFlag(player.getLocation());
Location playerLoc = player.getLocation();
player.teleport(new Location(playerLoc.getWorld(), playerLoc.getBlockX() + 1, playerLoc.getBlockY(), playerLoc.getBlockZ()));
this.msg("Team " + team.getName() + " flag added here.");
WarzoneYmlMapper.save(zone);
War.war.log(this.getSender().getName() + " created team " + team.getName() + " flag in warzone " + zone.getName(), Level.INFO);
} else {
// relocate flag
team.getFlagVolume().resetBlocks();
team.setTeamFlag(player.getLocation());
Location playerLoc = player.getLocation();
player.teleport(new Location(playerLoc.getWorld(), playerLoc.getBlockX() + 1, playerLoc.getBlockY(), playerLoc.getBlockZ() + 1));
this.msg("Team " + team.getName() + " flag moved.");
WarzoneYmlMapper.save(zone);
War.war.log(this.getSender().getName() + " moved team " + team.getName() + " flag in warzone " + zone.getName(), Level.INFO);
}
return true;
}
}

View File

@ -0,0 +1,48 @@
package com.tommytony.war.command;
import java.util.logging.Level;
import com.tommytony.war.config.WarConfigBag;
import org.bukkit.command.CommandSender;
import com.tommytony.war.War;
import com.tommytony.war.mapper.WarYmlMapper;
public class SetWarConfigCommand extends AbstractOptionalWarAdminCommand {
public SetWarConfigCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotWarAdminException {
super(handler, sender, args, false);
}
@Override
public boolean handle() {
boolean wantsToPrint = false;
if (this.args.length == 0) {
return false;
} else if (this.args.length == 1 && (this.args[0].equals("-p") || this.args[0].equals("print"))) {
String config = War.war.printConfig();
this.msg(config);
return true;
} else if (this.args.length > 1 && (this.args[0].equals("-p") || this.args[0].equals("print"))) {
wantsToPrint = true;
}
if (!this.isSenderWarAdmin()) {
War.war.badMsg(this.getSender(), "You can't do this if you are not a War admin (permission war.admin).");
return true;
}
String namedParamReturn = War.war.updateFromNamedParams(this.getSender(), this.args);
if (!namedParamReturn.equals("") && !namedParamReturn.equals("PARSE-ERROR")) {
WarConfigBag.afterUpdate(this.getSender(), namedParamReturn, wantsToPrint);
} else if (namedParamReturn.equals("PARSE-ERROR")) {
this.msg("Failed to read named parameters.");
} else {
return false;
}
return true;
}
}

View File

@ -0,0 +1,63 @@
package com.tommytony.war.command;
import java.util.logging.Level;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.mapper.WarYmlMapper;
import com.tommytony.war.structure.WarHub;
/**
* Places the warhub
*
* @author Tim Düsterhus
*/
public class SetWarHubCommand extends AbstractWarAdminCommand {
public SetWarHubCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotWarAdminException {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (!(this.getSender() instanceof Player)) {
this.badMsg("command.console");
return true;
}
if (this.args.length != 0) {
return false;
}
Player player = (Player) this.getSender();
if (War.war.getWarzones().size() > 0) {
if (War.war.getWarHub() != null) {
// reset existing hub
War.war.getWarHub().getVolume().resetBlocks();
War.war.getWarHub().setLocation(player.getLocation());
War.war.getWarHub().initialize();
this.msg("War hub moved.");
War.war.log(this.getSender().getName() + " moved the warhub", Level.INFO);
} else {
War.war.setWarHub(new WarHub(player.getLocation()));
War.war.getWarHub().initialize();
for (Warzone zone : War.war.getWarzones()) {
if (zone.getLobby() != null) {
zone.getLobby().getVolume().resetBlocks();
zone.getLobby().initialize();
}
}
this.msg("War hub created.");
War.war.log(this.getSender().getName() + " created the warhub", Level.INFO);
}
WarYmlMapper.save();
} else {
this.msg("No warzones yet.");
}
return true;
}
}

View File

@ -0,0 +1,58 @@
package com.tommytony.war.command;
import com.tommytony.war.War;
import com.tommytony.war.utility.Compat;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class SetZoneCommand extends AbstractZoneMakerCommand {
public SetZoneCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (!(this.getSender() instanceof Player)) {
this.badMsg("command.console");
return true;
}
Player player = (Player) this.getSender();
if (this.args.length == 0) {
return false;
} else if (this.args.length > 2) {
return false;
} else if (this.args.length == 1) {
Compat.BlockPair pair = Compat.getWorldEditSelection(player);
if (pair != null) {
ZoneSetter setter = new ZoneSetter(player, this.args[0]);
setter.placeCorner1(pair.getBlock1());
setter.placeCorner2(pair.getBlock2());
return true;
}
War.war.addWandBearer(player, this.args[0]);
} else {
if (!this.args[1].equals("southeast") && !this.args[1].equals("northwest") && !this.args[1].equals("se") && !this.args[1].equals("nw") && !this.args[1].equals("corner1") && !this.args[1].equals("corner2") && !this.args[1].equals("c1") && !this.args[1].equals("c2") && !this.args[1].equals("pos1") && !this.args[1].equals("pos2") && !this.args[1].equals("wand")) {
return false;
}
ZoneSetter setter = new ZoneSetter(player, this.args[0]);
if (this.args[1].equals("northwest") || this.args[1].equals("nw")) {
setter.placeNorthwest();
} else if (this.args[1].equals("southeast") || this.args[1].equals("se")) {
setter.placeSoutheast();
} else if (this.args[1].equals("corner1") || this.args[1].equals("c1") || this.args[1].equals("pos1")) {
setter.placeCorner1();
} else if (this.args[1].equals("corner2") || this.args[1].equals("c2") || this.args[1].equals("pos2")) {
setter.placeCorner2();
} else if (this.args[1].equals("wand")) {
War.war.addWandBearer(player, this.args[0]);
}
}
return true;
}
}

View File

@ -0,0 +1,115 @@
package com.tommytony.war.command;
import java.util.logging.Level;
import com.tommytony.war.config.WarzoneConfigBag;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.WarzoneConfig;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.ZoneLobby;
public class SetZoneConfigCommand extends AbstractOptionalZoneMakerCommand {
public SetZoneConfigCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args, false);
}
@Override
public boolean handle() {
Warzone zone = null;
Player player = null;
CommandSender commandSender = this.getSender();
boolean isFirstParamWarzone = false;
boolean wantsToPrint = false;
if (this.args.length == 0) {
return false;
} else {
if (!this.args[0].contains(":")) {
// warzone name maybe in first place
Warzone zoneByName = Warzone.getZoneByName(this.args[0]);
if (zoneByName != null) {
zone = zoneByName;
isFirstParamWarzone = true;
} else if (this.args[0].equals("-p") || this.args[0].equals("print")) {
wantsToPrint = true;
}
}
if (this.getSender() instanceof Player) {
player = (Player) commandSender;
if (zone == null) {
// zone not found, is he standing in it?
Warzone zoneByLoc = Warzone.getZoneByLocation(player);
ZoneLobby lobbyByLoc = ZoneLobby.getLobbyByLocation(player);
if (zoneByLoc == null && lobbyByLoc != null) {
zoneByLoc = lobbyByLoc.getZone();
}
if (zoneByLoc != null) {
zone = zoneByLoc;
}
}
}
if (zone == null) {
// No warzone found, whatever the mean, escape
return false;
}
if (isFirstParamWarzone) {
if (this.args.length == 1) {
// Only one param: the warzone name - default to usage
return false;
}
// More than one param: the arguments need to be shifted
String[] newargs = new String[this.args.length - 1];
for (int i = 1; i < this.args.length; i++) {
newargs[i - 1] = this.args[i];
}
this.args = newargs;
}
// args have been shifted if needed
if (this.args.length > 0 && (this.args[0].equals("-p") || this.args[0].equals("print"))) {
// only printing
if (this.args.length == 1) {
this.msg(War.war.printConfig(zone));
return true;
} else {
// first param was to print, shift again
String[] newargs = new String[this.args.length - 1];
for (int i = 1; i < this.args.length; i++) {
newargs[i - 1] = this.args[i];
}
this.args = newargs;
}
wantsToPrint = true;
}
if (!this.isSenderZoneMaker()) {
War.war.badMsg(this.getSender(), "You can't do this if you are not a warzone maker (permission war.zonemaker).");
return true;
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
}
// We have a warzone and indexed-from-0 arguments, let's update
String namedParamReturn = War.war.updateZoneFromNamedParams(zone, player, this.args);
if (!namedParamReturn.equals("") && !namedParamReturn.equals("PARSE-ERROR")) {
WarzoneConfigBag.afterUpdate(zone, player, namedParamReturn, wantsToPrint);
} else if (namedParamReturn.equals("PARSE-ERROR")) {
this.badMsg("Failed to read named parameter(s).");
} else {
// empty return means no param was parsed - print command usage
return false;
}
return true;
}
}
}

View File

@ -0,0 +1,129 @@
package com.tommytony.war.command;
import java.util.logging.Level;
import org.bukkit.block.BlockFace;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.ZoneLobby;
import com.tommytony.war.utility.Direction;
/**
* Places the zonelobby
*
* @author Tim Düsterhus
*/
public class SetZoneLobbyCommand extends AbstractZoneMakerCommand {
public SetZoneLobbyCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (!(this.getSender() instanceof Player)) {
this.badMsg("You can't do this if you are not in-game.");
return true;
}
if (this.args.length != 1) {
return false;
}
Player player = (Player) this.getSender();
ZoneLobby origLobby = null;
Warzone zone = Warzone.getZoneByLocation((Player) this.getSender());
if (zone == null) {
origLobby = ZoneLobby.getLobbyByLocation((Player) this.getSender());
if (origLobby != null) {
zone = origLobby.getZone();
}
}
if (zone == null) {
// Zone not where player is standing, maybe player is detaching/relocating the lobby
Warzone givenWarzone = Warzone.getZoneByName(this.args[0]);
if (givenWarzone == null) {
return false;
} else if (!this.isSenderAuthorOfZone(givenWarzone)) {
return true;
} else {
// Move the warzone lobby
ZoneLobby lobby = givenWarzone.getLobby();
if (lobby != null) {
// reset existing lobby and save new volume at new location
lobby.setLocation(player.getLocation());
lobby.initialize();
this.msg("Warzone lobby moved to your location.");
} else {
// new lobby
lobby = new ZoneLobby(givenWarzone, player.getLocation());
givenWarzone.setLobby(lobby);
lobby.initialize();
if (War.war.getWarHub() != null) { // warhub has to change
War.war.getWarHub().getVolume().resetBlocks();
War.war.getWarHub().initialize();
}
this.msg("Warzone lobby moved to your location.");
}
WarzoneYmlMapper.save(givenWarzone);
}
} else if (!this.isSenderAuthorOfZone(zone)) {
return true;
} else {
// Inside a warzone: use the classic n/s/e/w mode
if (!this.args[0].equals("north") && !this.args[0].equals("n") && !this.args[0].equals("east") && !this.args[0].equals("e") && !this.args[0].equals("south") && !this.args[0].equals("s") && !this.args[0].equals("west") && !this.args[0].equals("w")) {
if (Warzone.getZoneByName(this.args[0]) == zone && origLobby != null) {
origLobby.setLocation(player.getLocation());
origLobby.initialize();
this.msg("Warzone lobby moved to your location.");
return true;
}
return false;
}
ZoneLobby lobby = zone.getLobby();
BlockFace wall = Direction.WEST();
String wallStr = "";
if (this.args[0].equals("north") || this.args[0].equals("n")) {
wall = Direction.NORTH();
wallStr = "north";
} else if (this.args[0].equals("east") || this.args[0].equals("e")) {
wall = Direction.EAST();
wallStr = "east";
} else if (this.args[0].equals("south") || this.args[0].equals("s")) {
wall = Direction.SOUTH();
wallStr = "south";
} else if (this.args[0].equals("west") || this.args[0].equals("w")) {
wall = Direction.WEST();
wallStr = "west";
}
if (lobby != null) {
// reset existing lobby
lobby.getVolume().resetBlocks();
lobby.setWall(wall);
lobby.initialize();
this.msg("Warzone lobby moved to " + wallStr + " side of zone.");
} else {
// new lobby
lobby = new ZoneLobby(zone, wall);
zone.setLobby(lobby);
lobby.initialize();
if (War.war.getWarHub() != null) { // warhub has to change
War.war.getWarHub().getVolume().resetBlocks();
War.war.getWarHub().initialize();
}
this.msg("Warzone lobby created on " + wallStr + "side of zone.");
}
WarzoneYmlMapper.save(zone);
War.war.log(player.getName() + " moved lobby of warzone " + zone.getName(), Level.INFO);
}
return true;
}
}

View File

@ -0,0 +1,51 @@
package com.tommytony.war.command;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.Team;
/**
* Sends a message to all team-members
*
* @author Tim Düsterhus
*/
public class TeamCommand extends AbstractWarCommand {
public TeamCommand(WarCommandHandler handler, CommandSender sender, String[] args) {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (!(this.getSender() instanceof Player)) {
this.badMsg("command.console");
return true;
}
Player player = (Player) this.getSender();
Team playerTeam = Team.getTeamByPlayerName(player.getName());
if (playerTeam == null) {
return false;
}
if (this.args.length < 1) {
if (playerTeam.isInTeamChat(player)) {
playerTeam.removeTeamChatPlayer(player);
this.msg("team.chat.disable");
} else {
playerTeam.addTeamChatPlayer(player);
this.msg("team.chat.enable");
}
return true;
}
StringBuilder teamMessage = new StringBuilder();
for (String part : this.args) {
teamMessage.append(part).append(' ');
}
playerTeam.sendTeamChatMessage(player, teamMessage.toString());
return true;
}
}

View File

@ -0,0 +1,48 @@
package com.tommytony.war.command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.Warzone;
import com.tommytony.war.structure.ZoneLobby;
/**
* Shows team information
*
* @author Tim Düsterhus
*/
public class TeamsCommand extends AbstractWarCommand {
public TeamsCommand(WarCommandHandler handler, CommandSender sender, String[] args) {
super(handler, sender, args);
}
@Override
public boolean handle() {
Warzone zone;
if (this.args.length == 1) {
zone = Warzone.getZoneByName(this.args[0]);
} else if (this.args.length == 0) {
if (!(this.getSender() instanceof Player)) {
return false;
}
zone = Warzone.getZoneByLocation((Player) this.getSender());
if (zone == null) {
ZoneLobby lobby = ZoneLobby.getLobbyByLocation((Player) this.getSender());
if (lobby == null) {
return false;
}
zone = lobby.getZone();
}
} else {
return false;
}
if (zone == null) {
return false;
}
this.msg(zone.getTeamInformation());
return true;
}
}

View File

@ -0,0 +1,28 @@
package com.tommytony.war.command;
import org.bukkit.command.CommandSender;
import com.tommytony.war.War;
/**
* Unloads war.
*
* @author Tim Düsterhus
*/
public class UnloadWarCommand extends AbstractWarAdminCommand {
public UnloadWarCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotWarAdminException {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (this.args.length != 0) {
return false;
}
War.war.unloadWar();
this.msg("War unloaded.");
return true;
}
}

View File

@ -0,0 +1,149 @@
package com.tommytony.war.command;
import com.tommytony.war.War;
import com.tommytony.war.ui.WarUI;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.logging.Level;
/**
* Handles commands received by War
*
* @author Tim Düsterhus
* @package bukkit.tommytony.war
*/
public class WarCommandHandler {
/**
* Handles a command
*
* @param sender
* The sender of the command
* @param cmd
* The command
* @param args
* The arguments
* @return Success
*/
public boolean handle(CommandSender sender, Command cmd, String[] args) {
String command = cmd.getName();
String[] arguments = null;
// parse prefixed commands
if ((command.equals("war") || command.equals("War")) && args.length > 0) {
command = args[0];
arguments = new String[args.length - 1];
for (int i = 1; i <= arguments.length; i++) {
arguments[i - 1] = args[i];
}
if (arguments.length == 1 && (arguments[0].equals("help") || arguments[0].equals("h"))) {
// show /war help
War.war.badMsg(sender, cmd.getUsage());
return true;
}
} else if (command.equals("war") || command.equals("War")) {
if (sender instanceof Player) {
War.war.getUIManager().assignUI((Player) sender, new WarUI());
} else {
War.war.badMsg(sender, "Use /war help for information.");
}
return true;
} else {
arguments = args;
}
AbstractWarCommand commandObj = null;
try {
if (command.equals("warhub")) {
commandObj = new WarhubCommand(this, sender, arguments);
} else if (command.equals("zones") || command.equals("warzones")) {
commandObj = new WarzonesCommand(this, sender, arguments);
} else if (command.equals("zone") || command.equals("warzone")) {
commandObj = new WarzoneCommand(this, sender, arguments);
} else if (command.equals("teams")) {
commandObj = new TeamsCommand(this, sender, arguments);
} else if (command.equals("join")) {
commandObj = new JoinCommand(this, sender, arguments);
} else if (command.equals("leave")) {
commandObj = new LeaveCommand(this, sender, arguments);
} else if (command.equals("team")) {
commandObj = new TeamCommand(this, sender, arguments);
} else if (command.equals("setzone")) {
commandObj = new SetZoneCommand(this, sender, arguments);
} else if (command.equals("deletezone")) {
commandObj = new DeleteZoneCommand(this, sender, arguments);
} else if (command.equals("setzonelobby")) {
commandObj = new SetZoneLobbyCommand(this, sender, arguments);
} else if (command.equals("savezone")) {
commandObj = new SaveZoneCommand(this, sender, arguments);
} else if (command.equals("resetzone")) {
commandObj = new ResetZoneCommand(this, sender, arguments);
} else if (command.equals("nextbattle")) {
commandObj = new NextBattleCommand(this, sender, arguments);
} else if (command.equals("renamezone")) {
commandObj = new RenameZoneCommand(this, sender, arguments);
} else if (command.equals("setteam")) {
commandObj = new SetTeamCommand(this, sender, arguments);
} else if (command.equals("deleteteam")) {
commandObj = new DeleteTeamCommand(this, sender, arguments);
} else if (command.equals("setteamflag")) {
commandObj = new SetTeamFlagCommand(this, sender, arguments);
} else if (command.equals("deleteteamflag")) {
commandObj = new DeleteTeamFlagCommand(this, sender, arguments);
} else if (command.equals("setmonument")) {
commandObj = new SetMonumentCommand(this, sender, arguments);
} else if (command.equals("deletemonument")) {
commandObj = new DeleteMonumentCommand(this, sender, arguments);
} else if (command.equals("setcapturepoint")) {
commandObj = new SetCapturePointCommand(this, sender, arguments);
} else if (command.equals("deletecapturepoint")) {
commandObj = new DeleteCapturePointCommand(this, sender, arguments);
} else if (command.equals("setbomb")) {
commandObj = new SetBombCommand(this, sender, arguments);
} else if (command.equals("deletebomb")) {
commandObj = new DeleteBombCommand(this, sender, arguments);
} else if (command.equals("setcake")) {
commandObj = new SetCakeCommand(this, sender, arguments);
} else if (command.equals("deletecake")) {
commandObj = new DeleteCakeCommand(this, sender, arguments);
}else if (command.equals("setteamconfig") || command.equals("teamcfg")) {
commandObj = new SetTeamConfigCommand(this, sender, arguments);
} else if (command.equals("setzoneconfig") || command.equals("zonecfg")) {
commandObj = new SetZoneConfigCommand(this, sender, arguments);
} else if (command.equals("setwarhub")) {
commandObj = new SetWarHubCommand(this, sender, arguments);
} else if (command.equals("deletewarhub")) {
commandObj = new DeleteWarhubCommand(this, sender, arguments);
} else if (command.equals("loadwar")) {
commandObj = new LoadWarCommand(this, sender, arguments);
} else if (command.equals("unloadwar")) {
commandObj = new UnloadWarCommand(this, sender, arguments);
} else if (command.equals("setwarconfig") || command.equals("warcfg")) {
commandObj = new SetWarConfigCommand(this, sender, arguments);
} else if (command.equals("zonemaker") || command.equals("zm")) {
commandObj = new ZoneMakerCommand(this, sender, arguments);
}
// we are not responsible for any other command
} catch (NotWarAdminException e) {
War.war.badMsg(sender, "war.notadmin");
} catch (NotZoneMakerException e) {
War.war.badMsg(sender, "war.notzm");
} catch (Exception e) {
War.war.log("An error occured while handling command " + cmd.getName() + ". Exception:" + e.getClass().toString() + " " + e.getMessage(), Level.WARNING);
e.printStackTrace();
}
if(commandObj != null) {
boolean handled = commandObj.handle();
if(!handled) {
War.war.badMsg(sender, cmd.getUsage());
}
}
return true;
}
}

View File

@ -0,0 +1,53 @@
package com.tommytony.war.command;
import com.tommytony.war.config.WarConfig;
import com.tommytony.war.job.TeleportPlayerJob;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
/**
* Warps the player to the warhub.
*
* @author Tim Düsterhus
*/
public class WarhubCommand extends AbstractWarCommand {
public WarhubCommand(WarCommandHandler handler, CommandSender sender, String[] args) {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (!(this.getSender() instanceof Player)) {
this.badMsg("command.console");
return true;
}
if (this.args.length != 0) {
return false;
}
Player player = (Player) this.getSender();
if (War.war.getWarHub() == null) {
this.badMsg("warhub.none");
} else if (!War.war.canWarp(player)) {
this.badMsg("warhub.permission");
} else {
Warzone playerWarzone = Warzone.getZoneByPlayerName(player.getName());
if (playerWarzone != null) { // was in zone
playerWarzone.handlePlayerLeave(player, War.war.getWarHub().getLocation(), true);
}
int warmup = War.war.getWarConfig().getInt(WarConfig.TPWARMUP);
if (warmup > 0 && !player.hasPermission("war.warmupexempt")) {
final int TICKS_PER_SECOND = 20;
TeleportPlayerJob job = new TeleportPlayerJob(player, War.war.getWarHub().getLocation());
job.runTaskLater(War.war, warmup);
this.msg("command.tp.init", warmup / TICKS_PER_SECOND);
} else {
player.teleport(War.war.getWarHub().getLocation());
}
}
return true;
}
}

View File

@ -0,0 +1,76 @@
package com.tommytony.war.command;
import com.tommytony.war.config.WarConfig;
import com.tommytony.war.job.TeleportPlayerJob;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import org.bukkit.Bukkit;
/**
* Warps the player to the given warzone.
*
* @author Tim Düsterhus
*/
public class WarzoneCommand extends AbstractWarCommand {
public WarzoneCommand(WarCommandHandler handler, CommandSender sender, String[] args) {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (!(this.getSender() instanceof Player)) {
this.badMsg("command.console");
return true;
}
Player player = (Player) this.getSender();
if (args.length == 1) {
if (War.war.canWarp(player)) {
Warzone warzone = Warzone.getZoneByName(args[0]);
if (warzone != null && warzone.getTeleport() != null) {
Warzone playerWarzone = Warzone.getZoneByPlayerName(player.getName());
int warmup = War.war.getWarConfig().getInt(WarConfig.TPWARMUP);
if (playerWarzone != null) {
playerWarzone.handlePlayerLeave(player, warzone.getTeleport(), true);
}
if (warmup > 0 && !player.hasPermission("war.warmupexempt")) {
final int TICKS_PER_SECOND = 20;
TeleportPlayerJob job = new TeleportPlayerJob(player, warzone.getTeleport());
job.runTaskLater(War.war, warmup);
this.msg("command.tp.init", warmup / TICKS_PER_SECOND);
} else {
player.teleport(warzone.getTeleport());
}
} else {
this.badMsg("zone.zone404");
}
} else {
this.badMsg("zone.warp.permission");
}
return true;
} else if (args.length == 2 && (args[1].equalsIgnoreCase("sb")
|| args[1].equalsIgnoreCase("score")
|| args[1].equalsIgnoreCase("scoreboard"))) {
Warzone warzone = Warzone.getZoneByName(args[0]);
if (warzone != null) {
if (warzone.getScoreboard() != null) {
if (warzone.getScoreboard() == player.getScoreboard()) {
player.setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard());
} else {
player.setScoreboard(warzone.getScoreboard());
}
} else {
this.badMsg("zone.score.board404");
}
} else {
this.badMsg("zone.zone404");
}
return true;
} else {
return false;
}
}
}

View File

@ -0,0 +1,41 @@
package com.tommytony.war.command;
import java.text.MessageFormat;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
/**
* Lists all warzones
*
* @author Tim Düsterhus
*/
public class WarzonesCommand extends AbstractWarCommand {
public WarzonesCommand(WarCommandHandler handler, CommandSender sender, String[] args) {
super(handler, sender, args);
}
@Override
public boolean handle() {
if (this.args.length != 0) {
return false;
}
StringBuilder warzonesMessage = new StringBuilder(War.war.getString("zone.zoneinfo.prefix"));
if (War.war.getWarzones().isEmpty()) {
warzonesMessage.append(War.war.getString("zone.teaminfo.none"));
} else {
for (Warzone warzone : War.war.getWarzones()) {
warzonesMessage.append('\n');
warzonesMessage.append(MessageFormat.format(War.war.getString("zone.zoneinfo.format"),
warzone.getName(), warzone.getTeams().size(), warzone.getPlayerCount()));
}
}
this.msg(warzonesMessage.toString() + ((this.getSender() instanceof Player) ? War.war.getString("zone.zoneinfo.teleport") : ""));
return true;
}
}

View File

@ -0,0 +1,82 @@
package com.tommytony.war.command;
import com.tommytony.war.War;
import com.tommytony.war.mapper.WarYmlMapper;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.logging.Level;
/**
* Makes a player zonemaker and other way round.
*
* @author Tim Düsterhus
*/
public class ZoneMakerCommand extends AbstractWarCommand {
public ZoneMakerCommand(WarCommandHandler handler, CommandSender sender, String[] args) throws NotZoneMakerException {
super(handler, sender, args);
if (sender instanceof Player) { // i hate java for this.
if (!War.war.isZoneMaker((Player) sender)) {
for (OfflinePlayer offlinePlayer : War.war.getZoneMakersImpersonatingPlayers()) {
if (offlinePlayer.isOnline() && sender.equals(offlinePlayer.getPlayer())) {
return;
}
}
throw new NotZoneMakerException();
}
}
}
@Override
public boolean handle() {
if (!(this.getSender() instanceof Player)) {
this.badMsg("You can't do this if you are not in-game.");
return true;
}
Player player = (Player) this.getSender();
if (War.war.isZoneMaker(player)) {
if (this.args.length == 0) {
War.war.getZoneMakersImpersonatingPlayers().add(player);
this.msg("You are now impersonating a regular player. Type /zonemaker again to toggle back to war maker mode.");
} else if (this.args.length == 1) {
OfflinePlayer other = Bukkit.getOfflinePlayer(this.args[0]);
// make someone zonemaker or remove the right
if (War.war.getZoneMakerNames().contains(other)) {
// kick
War.war.getZoneMakerNames().remove(other);
this.msg(this.args[0] + " is not a zone maker anymore.");
if (other.isOnline()) {
War.war.msg(other.getPlayer(), player.getName() + " took away your warzone maker priviledges.");
War.war.log(player.getName() + " took away zonemaker rights from " + other.getName(), Level.INFO);
}
} else {
// add
War.war.getZoneMakerNames().add(other);
this.msg(this.args[0] + " is now a zone maker.");
if (other.isOnline()) {
War.war.msg(other.getPlayer(), player.getName() + " made you warzone maker.");
War.war.log(player.getName() + " made " + other.getName() + " a zonemaker", Level.INFO);
}
}
WarYmlMapper.save();
} else {
return false;
}
} else {
if (this.args.length != 0) {
return false;
}
War.war.getZoneMakersImpersonatingPlayers().remove(player);
this.msg("You are back as a zone maker.");
WarYmlMapper.save();
}
return true;
}
}

View File

@ -0,0 +1,274 @@
package com.tommytony.war.command;
import java.util.logging.Level;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.WarConfig;
import com.tommytony.war.mapper.WarYmlMapper;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import com.tommytony.war.structure.ZoneLobby;
import com.tommytony.war.utility.Direction;
import com.tommytony.war.volume.NotNorthwestException;
import com.tommytony.war.volume.NotSoutheastException;
import com.tommytony.war.volume.TooBigException;
import com.tommytony.war.volume.TooSmallException;
public class ZoneSetter {
private final Player player;
private final String zoneName;
public ZoneSetter(Player player, String zoneName) {
this.player = player;
this.zoneName = zoneName;
}
public void placeNorthwest() {
Warzone warzone = War.war.findWarzone(this.zoneName);
Block northwestBlock = this.player.getLocation().getWorld().getBlockAt(this.player.getLocation());
StringBuilder msgString = new StringBuilder();
try {
if (warzone == null && War.war.getWarzones().size() >= War.war.getWarConfig().getInt(WarConfig.MAXZONES)) {
// max warzones reached
War.war.badMsg(player, "Too many warzones already! To change the maximum, use /warcfg maxzone:20.");
return;
} else if (warzone == null) {
// create the warzone
warzone = new Warzone(this.player.getLocation().getWorld(), this.zoneName);
warzone.addAuthor(player.getName());
War.war.getIncompleteZones().add(warzone);
warzone.getVolume().setNorthwest(northwestBlock.getLocation());
War.war.msg(this.player, "Warzone " + warzone.getName() + " created. Northwesternmost point set to x:" + warzone.getVolume().getNorthwestX() + " z:" + warzone.getVolume().getNorthwestZ() + ". ");
War.war.log(player.getName() + " created warzone " + zoneName + " by setting its nw corner", Level.INFO);
} else if (!this.isPlayerAuthorOfZoneOrAdmin(warzone)) {
return;
} else {
// change existing warzone
this.resetWarzone(warzone, msgString);
warzone.getVolume().setNorthwest(northwestBlock.getLocation());
msgString.append("Warzone " + warzone.getName() + " modified. Northwesternmost point set to x:" + warzone.getVolume().getNorthwestX() + " z:" + warzone.getVolume().getNorthwestZ() + ". ");
War.war.log(player.getName() + " updated warzone " + zoneName + " by setting its nw corner", Level.INFO);
}
this.saveIfReady(warzone, msgString);
} catch (NotNorthwestException e) {
War.war.badMsg(this.player, "The block you selected is not to the northwest of the existing southeasternmost block.");
if (warzone.getVolume().isSaved()) {
warzone.initializeZone(); // was reset before changing
}
} catch (TooSmallException e) {
this.handleTooSmall();
if (warzone.getVolume().isSaved()) {
warzone.initializeZone();
}
} catch (TooBigException e) {
this.handleTooBig();
if (warzone.getVolume().isSaved()) {
warzone.initializeZone();
}
}
}
public void placeSoutheast() {
Warzone warzone = War.war.findWarzone(this.zoneName);
Block southeastBlock = this.player.getLocation().getWorld().getBlockAt(this.player.getLocation());
StringBuilder msgString = new StringBuilder();
try {
if (warzone == null && War.war.getWarzones().size() >= War.war.getWarConfig().getInt(WarConfig.MAXZONES)) {
// max warzones reached
War.war.badMsg(player, "Too many warzones already! To change the maximum, use /warcfg maxzone:20.");
return;
} else if (warzone == null) {
// create the warzone
warzone = new Warzone(this.player.getLocation().getWorld(), this.zoneName);
warzone.addAuthor(player.getName());
War.war.getIncompleteZones().add(warzone);
warzone.getVolume().setSoutheast(southeastBlock.getLocation());
War.war.msg(this.player, "Warzone " + warzone.getName() + " created. Southeasternmost point set to x:" + warzone.getVolume().getSoutheastX() + " z:" + warzone.getVolume().getSoutheastZ() + ". ");
War.war.log(player.getName() + " created warzone " + zoneName + " by setting its se corner", Level.INFO);
} else if (!this.isPlayerAuthorOfZoneOrAdmin(warzone)) {
return;
} else {
// change existing warzone
this.resetWarzone(warzone, msgString);
warzone.getVolume().setSoutheast(southeastBlock.getLocation());
msgString.append("Warzone " + warzone.getName() + " modified. Southeasternmost point set to x:" + warzone.getVolume().getSoutheastX() + " z:" + warzone.getVolume().getSoutheastZ() + ". ");
War.war.log(player.getName() + " updated warzone " + zoneName + " by setting its se corner", Level.INFO);
}
this.saveIfReady(warzone, msgString);
} catch (NotSoutheastException e) {
War.war.badMsg(this.player, "The block you selected is not to the southeast of the existing northwestnmost block.");
if (warzone.getVolume().isSaved()) {
warzone.initializeZone(); // was reset before changing
}
} catch (TooSmallException e) {
this.handleTooSmall();
if (warzone.getVolume().isSaved()) {
warzone.initializeZone();
}
} catch (TooBigException e) {
this.handleTooBig();
if (warzone.getVolume().isSaved()) {
warzone.initializeZone();
}
}
}
public void placeCorner1() {
Block corner1Block = this.player.getLocation().getWorld().getBlockAt(this.player.getLocation());
this.placeCorner1(corner1Block);
}
public void placeCorner1(Block corner1Block) {
Warzone warzone = War.war.findWarzone(this.zoneName);
StringBuilder msgString = new StringBuilder();
try {
if (warzone == null && War.war.getWarzones().size() >= War.war.getWarConfig().getInt(WarConfig.MAXZONES)) {
// max warzones reached
War.war.badMsg(player, "Too many warzones already! To change the maximum, use /warcfg maxzone:20.");
return;
} else if (warzone == null) {
// create the warzone
warzone = new Warzone(this.player.getLocation().getWorld(), this.zoneName);
warzone.addAuthor(player.getName());
War.war.getIncompleteZones().add(warzone);
warzone.getVolume().setZoneCornerOne(corner1Block);
War.war.msg(this.player, "Warzone " + warzone.getName() + " created. Corner 1 set to x:" + corner1Block.getX() + " y:" + corner1Block.getY() + " z:" + corner1Block.getZ() + ". ");
War.war.log(player.getName() + " created warzone " + zoneName + " by setting its corner 1", Level.INFO);
} else if (!this.isPlayerAuthorOfZoneOrAdmin(warzone)) {
return;
} else {
// change existing warzone
this.resetWarzone(warzone, msgString);
warzone.getVolume().setZoneCornerOne(corner1Block);
msgString.append("Warzone " + warzone.getName() + " modified. Corner 1 set to x:" + corner1Block.getX() + " y:" + corner1Block.getY() + " z:" + corner1Block.getZ() + ". ");
War.war.log(player.getName() + " updated warzone " + zoneName + " by setting its corner 1", Level.INFO);
}
this.saveIfReady(warzone, msgString);
} catch (TooSmallException e) {
this.handleTooSmall();
if (warzone.getVolume().isSaved()) {
warzone.initializeZone();
}
} catch (TooBigException e) {
this.handleTooBig();
if (warzone.getVolume().isSaved()) {
warzone.initializeZone();
}
}
}
public void placeCorner2() {
Block corner2Block = this.player.getLocation().getWorld().getBlockAt(this.player.getLocation());
this.placeCorner2(corner2Block);
}
public void placeCorner2(Block corner2Block) {
Warzone warzone = War.war.findWarzone(this.zoneName);
StringBuilder msgString = new StringBuilder();
try {
if (warzone == null && War.war.getWarzones().size() >= War.war.getWarConfig().getInt(WarConfig.MAXZONES)) {
// max warzones reached
War.war.badMsg(player, "Too many warzones already! To change the maximum, use /warcfg maxzone:20.");
return;
} else if (warzone == null) {
// create the warzone
warzone = new Warzone(this.player.getLocation().getWorld(), this.zoneName);
warzone.addAuthor(player.getName());
War.war.getIncompleteZones().add(warzone);
warzone.getVolume().setZoneCornerTwo(corner2Block);
War.war.msg(this.player, "Warzone " + warzone.getName() + " created. Corner 2 set to x:" + corner2Block.getX() + " y:" + corner2Block.getY() + " z:" + corner2Block.getZ() + ". ");
War.war.log(player.getName() + " created warzone " + zoneName + " by setting its corner 2", Level.INFO);
} else if (!this.isPlayerAuthorOfZoneOrAdmin(warzone)) {
return;
} else {
// change existing warzone
this.resetWarzone(warzone, msgString);
warzone.getVolume().setZoneCornerTwo(corner2Block);
msgString.append("Warzone " + warzone.getName() + " modified. Corner 2 set to x:" + corner2Block.getX() + " y:" + corner2Block.getY() + " z:" + corner2Block.getZ() + ". ");
War.war.log(player.getName() + " updated warzone " + zoneName + " by setting its corner 2", Level.INFO);
}
this.saveIfReady(warzone, msgString);
} catch (TooSmallException e) {
this.handleTooSmall();
if (warzone.getVolume().isSaved()) {
warzone.initializeZone();
}
} catch (TooBigException e) {
this.handleTooBig();
if (warzone.getVolume().isSaved()) {
warzone.initializeZone();
}
}
}
private boolean isPlayerAuthorOfZoneOrAdmin(Warzone warzone) {
boolean isAuthor = warzone.isAuthor(player);
boolean isAdmin = !War.war.isWarAdmin(player);
if (!isAuthor && !isAdmin) {
War.war.badMsg(player, "You can't do this because you are not an author of the " + warzone.getName() + " warzone." );
}
return isAuthor || isAdmin;
}
private void resetWarzone(Warzone warzone, StringBuilder msgString) {
if (warzone.getVolume().isSaved()) {
War.war.msg(this.player, "Resetting " + warzone.getName() + " blocks.");
if (warzone.getLobby() != null && warzone.getLobby().getVolume() != null) {
warzone.getLobby().getVolume().resetBlocks();
}
warzone.getVolume().resetBlocks();
msgString.append(warzone.getVolume().size() + " blocks reset. ");
}
}
private void handleTooSmall() {
War.war.badMsg(this.player, "That would make the " + this.zoneName + " warzone too small. Sides must be at least 10 blocks and all existing structures (spawns, flags, etc) must fit inside.");
}
private void handleTooBig() {
War.war.badMsg(this.player, "That would make the " + this.zoneName + " warzone too big. Sides must be less than 750 blocks.");
}
private void saveIfReady(Warzone warzone, StringBuilder msgString) {
if (warzone.ready()) {
if (!War.war.getWarzones().contains(warzone)) {
War.war.addWarzone(warzone);
}
if (War.war.getIncompleteZones().contains(warzone)) {
War.war.getIncompleteZones().remove(warzone);
}
WarYmlMapper.save();
msgString.append("Saving new warzone blocks...");
War.war.msg(this.player, msgString.toString());
warzone.saveState(false); // we just changed the volume, cant reset walls
if (warzone.getLobby() == null) {
// Set default lobby on south side
ZoneLobby lobby = new ZoneLobby(warzone, Direction.SOUTH());
warzone.setLobby(lobby);
if (War.war.getWarHub() != null) { // warhub has to change
War.war.getWarHub().getVolume().resetBlocks();
War.war.getWarHub().initialize();
}
War.war.msg(this.player, "Default lobby created on south side of zone. Use /setzonelobby <n/s/e/w> to change its position.");
}
warzone.initializeZone();
WarzoneYmlMapper.save(warzone);
War.war.msg(this.player, "Warzone saved.");
War.war.log(this.player.getName() + " saved first version of warzone " + zoneName, Level.INFO);
} else {
if (warzone.getVolume().getCornerOne() == null) {
msgString.append("Still missing corner 1.");
} else if (warzone.getVolume().getCornerTwo() == null) {
msgString.append("Still missing corner 2.");
}
War.war.msg(this.player, msgString.toString());
}
}
}

View File

@ -0,0 +1,22 @@
package com.tommytony.war.config;
public enum FlagReturn {
BOTH,
FLAG,
SPAWN;
@Override
public String toString() {
return super.toString().toLowerCase();
}
public static FlagReturn getFromString(String string) {
for (FlagReturn flagMode : FlagReturn.values()) {
if (string.toLowerCase().equals(flagMode.toString())) {
return flagMode;
}
}
return FlagReturn.BOTH;
}
}

View File

@ -0,0 +1,153 @@
package com.tommytony.war.config;
import java.util.HashMap;
import org.bukkit.inventory.ItemStack;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.utility.Loadout;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class InventoryBag {
private List<Loadout> loadouts = new ArrayList<Loadout>();
private HashMap<Integer, ItemStack> reward = null;
private Warzone warzone;
public InventoryBag(Warzone warzone) {
this.warzone = warzone;
}
public InventoryBag() {
this.warzone = null;
}
public void addLoadout(String name, HashMap<Integer, ItemStack> loadout) {
this.loadouts.add(new Loadout(name, loadout, null));
}
public void addLoadout(Loadout loadout) {
this.loadouts.add(loadout);
}
public void removeLoadout(String name) {
ArrayList<Loadout> loadoutsToRemove = new ArrayList<Loadout>();
for (Loadout ldt : loadouts) {
if (ldt.getName().equals(name)) {
loadoutsToRemove.add(ldt);
}
}
// avoid concurrent modif exceptions
for (Loadout loadoutToRemove : loadoutsToRemove) {
this.removeLoadout(loadoutToRemove);
}
}
public void removeLoadout(Loadout ldt) {
this.loadouts.remove(ldt);
}
public boolean hasLoadouts() {
return loadouts.size() > 0;
}
public HashMap<String, HashMap<Integer, ItemStack>> getLoadouts() {
return Loadout.toLegacyFormat(loadouts);
}
public List<Loadout> getNewLoadouts() {
return loadouts;
}
public void setLoadouts(List<Loadout> loadouts) {
this.loadouts = loadouts;
}
public HashMap<String, HashMap<Integer, ItemStack>> resolveLoadouts() {
if (this.hasLoadouts()) {
return this.getLoadouts();
} else if (warzone != null && warzone.getDefaultInventories().hasLoadouts()) {
return warzone.getDefaultInventories().resolveLoadouts();
} else if (War.war.getDefaultInventories().hasLoadouts()) {
return War.war.getDefaultInventories().resolveLoadouts();
} else {
return new HashMap<String, HashMap<Integer, ItemStack>>();
}
}
public List<Loadout> resolveNewLoadouts() {
if (this.hasLoadouts()) {
return this.getNewLoadouts();
} else if (warzone != null && warzone.getDefaultInventories().hasLoadouts()) {
return warzone.getDefaultInventories().resolveNewLoadouts();
} else if (War.war.getDefaultInventories().hasLoadouts()) {
return War.war.getDefaultInventories().resolveNewLoadouts();
} else {
return Collections.emptyList();
}
}
public void setReward(HashMap<Integer, ItemStack> reward) {
this.reward = reward;
}
public boolean hasReward() {
return reward != null;
}
public HashMap<Integer, ItemStack> getReward() {
return reward;
}
public HashMap<Integer, ItemStack> resolveReward() {
if (this.hasReward()) {
return reward;
} else if (warzone != null && warzone.getDefaultInventories().hasReward()) {
return warzone.getDefaultInventories().resolveReward();
} else {
return War.war.getDefaultInventories().resolveReward();
}
}
public void clearLoadouts() {
this.loadouts.clear();
}
public HashMap<Integer, ItemStack> getLoadout(String loadoutName) {
for (Loadout ldt : loadouts) {
if (ldt.getName().equals(loadoutName)) {
return ldt.getContents();
}
}
return null;
}
public Loadout getNewLoadout(String loadoutName) {
for (Loadout ldt : loadouts) {
if (ldt.getName().equals(loadoutName)) {
return ldt;
}
}
return null;
}
public void setLoadout(String name, HashMap<Integer, ItemStack> contents) {
for (Loadout ldt : loadouts) {
if (ldt.getName().equals(name)) {
ldt.setContents(contents);
return;
}
}
loadouts.add(new Loadout(name, contents, null));
}
public boolean containsLoadout(String name) {
return this.getNewLoadout(name) != null;
}
}

View File

@ -0,0 +1,155 @@
package com.tommytony.war.config;
import com.google.common.collect.ImmutableList;
import com.tommytony.war.Team;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor;
import org.bukkit.Effect;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.MemoryConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
/**
* Manage rewards for certain killstreaks.
*
* @author cmastudios
*/
public class KillstreakReward {
private ConfigurationSection section;
private Set<String> airstrikePlayers;
/**
* Creates a new killstreak reward class with default options.
*/
public KillstreakReward() {
this(new MemoryConfiguration());
section.set("3.privmsg", "You have been rewarded with some health for your kills.");
section.set("3.reward.health", 8);
section.set("4.reward.xp", 3);
section.set("5.message", "{0} is on a &ckillstreak&f! 5 kills this life.");
section.set("5.privmsg", "You have received some items for your kills.");
section.set("5.reward.points", 1);
section.set("5.reward.airstrike", true);
section.set("5.reward.items", ImmutableList.of(new ItemStack(Material.ARROW, 15), new ItemStack(Material.EGG)));
section.set("5.reward.effect", Effect.GHAST_SHRIEK.name());
ItemStack sword = new ItemStack(Material.WOODEN_SWORD);
sword.addEnchantment(Enchantment.DAMAGE_ALL, 2);
sword.addEnchantment(Enchantment.KNOCKBACK, 1);
ItemMeta meta = sword.getItemMeta();
meta.setDisplayName("The Breaker");
meta.setLore(ImmutableList.of("Very slow speed"));
sword.setItemMeta(meta);
section.set("7.reward.items", ImmutableList.of(sword));
}
/**
* Creates a new killstreak reward class with options from the provided
* config.
*
* @param section Section to load killstreak options from, such as
* set.war.killstreak
*/
public KillstreakReward(ConfigurationSection section) {
this.section = section;
this.airstrikePlayers = new HashSet<String>();
}
/**
* Rewards a player for their current killstreak. The player must be in a
* warzone.
*
* @param player Player to reward
* @param kills Amount of kills to reward for
*/
public void rewardPlayer(Player player, int kills) {
if (section == null) {
/*
* Cancel the reward if there is no configuration for killstreaks.
* This can occur if the server owner has an older War config with
* no settings for killstreaks and have neglected to add any. Heck,
* they shouldn't have enabled killstreaks in the warzone anyway.
*/
return;
}
final Warzone zone = Warzone.getZoneByPlayerName(player.getName());
final Team playerTeam = Team.getTeamByPlayerName(player.getName());
Validate.notNull(zone, "Cannot reward player if they are not in a warzone");
Validate.notNull(playerTeam, "Cannot reward player if they are not in a team");
if (section.contains(Integer.toString(kills))) {
ConfigurationSection killSection = section.getConfigurationSection(Integer.toString(kills));
if (killSection.contains("message")) {
final String playerName = playerTeam.getKind().getColor() + player.getName() + ChatColor.WHITE;
final String message = ChatColor.translateAlternateColorCodes('&', MessageFormat.format(killSection.getString("message"), playerName));
for (Team team : zone.getTeams()) {
team.teamcast(message);
}
}
if (killSection.contains("privmsg")) {
War.war.msg(player, ChatColor.translateAlternateColorCodes('&', killSection.getString("privmsg")));
}
if (killSection.contains("reward.health")) {
double health = player.getHealth() + killSection.getInt("reward.health");
player.setHealth(health > 20 ? 20 : health); // Grant up to full health only
}
if (killSection.contains("reward.items")) {
for (Object obj : killSection.getList("reward.items")) {
if (obj instanceof ItemStack) {
player.getInventory().addItem((ItemStack) obj);
}
}
}
if (killSection.contains("reward.xp") && !playerTeam.getTeamConfig().resolveBoolean(TeamConfig.XPKILLMETER)) {
// Will not work if XPKILLMETER is enabled
player.setLevel(player.getLevel() + killSection.getInt("reward.xp"));
}
if (killSection.contains("reward.points")) {
for (int i = 0; i < killSection.getInt("reward.points"); i++) {
playerTeam.addPoint();
}
// Detect win conditions
if (playerTeam.getPoints() >= playerTeam.getTeamConfig().resolveInt(TeamConfig.MAXSCORE)) {
player.getServer().getScheduler().runTaskLater(War.war, new Runnable() {
public void run() {
zone.handleScoreCapReached(playerTeam.getName());
}
}, 1L);
} else {
// just added a point
playerTeam.resetSign();
zone.getLobby().resetTeamGateSign(playerTeam);
}
}
if (killSection.getBoolean("reward.airstrike")) {
this.airstrikePlayers.add(player.getName());
}
if (killSection.contains("reward.effect")) {
Effect effect = Effect.valueOf(killSection.getString("reward.effect"));
player.getWorld().playEffect(player.getLocation(), effect, null);
}
}
}
public void saveTo(ConfigurationSection section) {
Map<String, Object> values = this.section.getValues(true);
for (Map.Entry<String, Object> entry : values.entrySet()) {
section.set(entry.getKey(), entry.getValue());
}
}
public Set<String> getAirstrikePlayers() {
return airstrikePlayers;
}
}

View File

@ -0,0 +1,102 @@
package com.tommytony.war.config;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Map;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.MemoryConfiguration;
/**
* Storage class for MySQL configuration settings.
*
* @author cmastudios
*/
public class MySQLConfig {
private ConfigurationSection section;
/**
* Load the values from the specified section into the MySQL config.
*
* @param section Section to load MySQL settings from.
*/
public MySQLConfig(ConfigurationSection section) {
this.section = section;
}
/**
* Create a new MySQL configuration section with default values.
*/
public MySQLConfig() {
this(new MemoryConfiguration());
section.set("enabled", false);
section.set("host", "localhost");
section.set("port", 3306);
section.set("database", "war");
section.set("username", "root");
section.set("password", "meow");
section.set("logging.enabled", false);
section.set("logging.autoclear",
"WHERE `date` < NOW() - INTERVAL 7 DAY");
}
/**
* Check if MySQL support is enabled.
*
* @return true if MySQL support is enabled, false otherwise.
*/
public boolean isEnabled() {
return section.getBoolean("enabled");
}
/**
* Check if kill-death logging is enabled.
*
* @return true if kill-death logging is enabled, false otherwise.
*/
public boolean isLoggingEnabled() {
return section.getBoolean("logging.enabled");
}
/**
* Get WHERE clause for automatic deletion from database table.
*
* @return deletion WHERE clause or empty string.
*/
public String getLoggingDeleteClause() {
return section.getString("logging.autoclear", "");
}
private String getJDBCUrl() {
return String.format("jdbc:mysql://%s:%d/%s?user=%s&password=%s",
section.getString("host"), section.getInt("port"),
section.getString("database"), section.getString("username"),
section.getString("password"));
}
/**
* Get a connection to the MySQL database represented by this configuration.
*
* @return connection to MySQL database.
* @throws SQLException Error occured connecting to database.
* @throws IllegalArgumentException MySQL support is not enabled.
*/
public Connection getConnection() throws SQLException {
Validate.isTrue(this.isEnabled(), "MySQL support is not enabled");
return DriverManager.getConnection(this.getJDBCUrl());
}
/**
* Copy represented configuration into another configuration section.
*
* @param section Mutable section to write values in.
*/
public void saveTo(ConfigurationSection section) {
Map<String, Object> values = this.section.getValues(true);
for (Map.Entry<String, Object> entry : values.entrySet()) {
section.set(entry.getKey(), entry.getValue());
}
}
}

View File

@ -0,0 +1,35 @@
package com.tommytony.war.config;
public enum ScoreboardType {
NONE(null),
POINTS("Points"),
LIFEPOOL("Lifepool"),
TOPKILLS("Top kills"),
PLAYERCOUNT("Player count"),
SWITCHING("Switching");
private final String displayName;
ScoreboardType(String displayName) {
this.displayName = displayName;
}
public static ScoreboardType getFromString(String string) {
for (ScoreboardType boardMode : ScoreboardType.values()) {
if (string.toLowerCase().equals(boardMode.toString())) {
return boardMode;
}
}
return ScoreboardType.NONE;
}
@Override
public String toString() {
return super.toString().toLowerCase();
}
public String getDisplayName() {
return displayName;
}
}

View File

@ -0,0 +1,66 @@
package com.tommytony.war.config;
public enum TeamConfig {
FLAGMUSTBEHOME (Boolean.class, "Flag Must Be Home", "If true, enemy flag cannot be captured if your flag is out"),
FLAGPOINTSONLY (Boolean.class, null, null), // obsolete
FLAGRETURN (FlagReturn.class, "Flag Return Destination", "Defines where the flag must be returned to capture\nOptions: spawn, flag, or both"),
LIFEPOOL (Integer.class, "Lifepool", "Sets maximum team lives"),
MAXSCORE (Integer.class, "Max Score", "Sets the point limit for when a team will win"),
NOHUNGER (Boolean.class, "No Hunger", "If true, player hunger will not decrease"),
PLAYERLOADOUTASDEFAULT (Boolean.class, "Player Loadout As Default", "If true, the default loadout will be the items the player brings into the zone"),
RESPAWNTIMER (Integer.class, "Respawn Time", "Time, in seconds, required to wait after each death"),
SATURATION (Integer.class, "Saturation", "Set player saturation to this level after each death"),
SPAWNSTYLE (TeamSpawnStyle.class, "Spawn Style", "Sets the type spawn point\nOptions: small, big, flat, invisible"),
TEAMSIZE (Integer.class, "Team Size", "Maximum players that may play on a team"),
PERMISSION (String.class, "Required Permission", "Only allow players with a certain permission to join a team"),
XPKILLMETER (Boolean.class, "XP Kill Meter", "Use the XP bar to count kills"),
KILLSTREAK (Boolean.class, "Killstreak Rewards", "Reward players for kills based on war.yml configuration"),
BLOCKWHITELIST (String.class, "Block Whitelist", "Comma-separated list of blocks players may break or place, 'all' removes this limit"),
PLACEBLOCK (Boolean.class, "Place Blocks", "If true, players can place blocks"),
APPLYPOTION(String.class, "Apply Potion Effect", "Give players a potion effect after each death, Format: EFFECT;DURATION;STRENGTH"),
ECOREWARD(Double.class, "Economy Reward", "Give the winning team this much money, requires Vault plugin"),
INVENTORYDROP(Boolean.class, "Drop Inventory", "If true, players will drop items on death"),
BORDERDROP(Boolean.class, "Drop Near Border", "If true, players can drop items near the border\nUsually enabled to prevent duping");
private final Class<?> configType;
private final String title;
private final String description;
TeamConfig(Class<?> configType, String title, String description) {
this.configType = configType;
this.title = title;
this.description = description;
}
public Class<?> getConfigType() {
return configType;
}
public String getTitle() {
return title;
}
public String getDescription() {
return description;
}
public static TeamConfig teamConfigFromString(String str) {
String lowered = str.toLowerCase();
for (TeamConfig config : TeamConfig.values()) {
if (config.toString().startsWith(lowered)) {
return config;
}
}
return null;
}
public String toStringWithValue(Object value) {
return this.toString() + ":" + value.toString();
}
@Override
public String toString() {
return super.toString().toLowerCase();
}
}

View File

@ -0,0 +1,280 @@
package com.tommytony.war.config;
import com.tommytony.war.Team;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
import java.util.EnumMap;
import java.util.Map;
import java.util.logging.Level;
public class TeamConfigBag {
private EnumMap<TeamConfig, Object> bag = new EnumMap<TeamConfig, Object>(TeamConfig.class);
private Warzone warzone;
public TeamConfigBag(Warzone warzone) {
this.warzone = warzone;
}
public TeamConfigBag() {
this.warzone = null;
}
public static void afterUpdate(Team team, CommandSender sender, String namedParamReturn, boolean wantsToPrint) {
final Warzone zone = team.getZone();
WarzoneYmlMapper.save(zone);
String zoneReset = "Some changes may require a /resetzone. ";
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.RESETONCONFIGCHANGE)) {
zone.reinitialize(); // bring back team spawns etc
zoneReset = "Zone reset. ";
}
if (wantsToPrint) {
War.war.msg(sender, "Team config saved. " + zoneReset + namedParamReturn + " " + War.war.printConfig(team));
} else {
War.war.msg(sender, "Team config saved. " + zoneReset + namedParamReturn);
}
War.war.log(sender.getName() + " updated team " + team.getName() + " configuration in warzone " + zone.getName() + "." + namedParamReturn, Level.INFO);
if (War.war.getWarHub() != null) { // maybe the zone was disabled/enabled
War.war.getWarHub().getVolume().resetBlocks();
War.war.getWarHub().initialize();
}
}
public boolean contains(TeamConfig config) {
return this.bag.containsKey(config);
}
public void reset() {
this.bag.clear();
}
public boolean isEmpty() {
return this.bag.keySet().size() == 0;
}
public void put(TeamConfig config, Object value) {
this.bag.put(config, value);
}
public Object getValue(TeamConfig config) {
if (this.contains(config)) {
return this.bag.get(config);
} else {
return null;
}
}
public Object resolveValue(TeamConfig config) {
if (this.contains(config)) {
return this.bag.get(config);
} else if (this.warzone != null && this.warzone.getTeamDefaultConfig().contains(config)){
// use Warzone default config
return this.warzone.getTeamDefaultConfig().resolveValue(config);
} else {
// use War default config
return War.war.getTeamDefaultConfig().resolveValue(config);
}
}
public Double getDouble(TeamConfig config) {
if (this.contains(config)) {
return (Double)this.bag.get(config);
}
return null;
}
public Double resolveDouble(TeamConfig config) {
if (this.contains(config)) {
return (Double)this.bag.get(config);
} else if (this.warzone != null && this.warzone.getTeamDefaultConfig().contains(config)){
// use Warzone default config
return this.warzone.getTeamDefaultConfig().resolveDouble(config);
} else {
// use War default config
return War.war.getTeamDefaultConfig().resolveDouble(config);
}
}
public Integer getInt(TeamConfig config) {
if (this.contains(config)) {
return (Integer)this.bag.get(config);
}
return null;
}
public Integer resolveInt(TeamConfig config) {
if (this.contains(config)) {
return (Integer) this.bag.get(config);
} else if (this.warzone != null && this.warzone.getTeamDefaultConfig().contains(config)){
// use Warzone default config
return this.warzone.getTeamDefaultConfig().resolveInt(config);
} else {
// use War default config
return War.war.getTeamDefaultConfig().resolveInt(config);
}
}
public Boolean getBoolean(TeamConfig config) {
if (this.contains(config)) {
return (Boolean)this.bag.get(config);
}
return null;
}
public Boolean resolveBoolean(TeamConfig config) {
if (this.contains(config)) {
return (Boolean) this.bag.get(config);
} else if (this.warzone != null && this.warzone.getTeamDefaultConfig().contains(config)){
// use Warzone default config
return this.warzone.getTeamDefaultConfig().resolveBoolean(config);
} else {
// use War default config
return War.war.getTeamDefaultConfig().resolveBoolean(config);
}
}
public String getString(TeamConfig config) {
if (this.contains(config)) {
return (String)this.bag.get(config);
}
return null;
}
public String resolveString(TeamConfig config) {
if (this.contains(config)) {
return (String) this.bag.get(config);
} else if (this.warzone != null && this.warzone.getTeamDefaultConfig().contains(config)){
// use Warzone default config
return this.warzone.getTeamDefaultConfig().resolveString(config);
} else {
// use War default config
return War.war.getTeamDefaultConfig().resolveString(config);
}
}
public FlagReturn resolveFlagReturn() {
if (this.contains(TeamConfig.FLAGRETURN)) {
return (FlagReturn) this.bag.get(TeamConfig.FLAGRETURN);
} else if (this.warzone != null && this.warzone.getTeamDefaultConfig().contains(TeamConfig.FLAGRETURN)){
// use Warzone default config
return this.warzone.getTeamDefaultConfig().resolveFlagReturn();
} else {
// use War default config
return War.war.getTeamDefaultConfig().resolveFlagReturn();
}
}
public FlagReturn getFlagReturn() {
if (this.contains(TeamConfig.FLAGRETURN)) {
return (FlagReturn) this.bag.get(TeamConfig.FLAGRETURN);
}
return null;
}
public TeamSpawnStyle resolveSpawnStyle() {
if (this.contains(TeamConfig.SPAWNSTYLE)) {
return (TeamSpawnStyle) this.bag.get(TeamConfig.SPAWNSTYLE);
} else if (this.warzone != null && this.warzone.getTeamDefaultConfig().contains(TeamConfig.SPAWNSTYLE)){
// use War default config
return this.warzone.getTeamDefaultConfig().resolveSpawnStyle();
} else {
return War.war.getTeamDefaultConfig().resolveSpawnStyle();
}
}
public TeamSpawnStyle getSpawnStyle() {
if (this.contains(TeamConfig.SPAWNSTYLE)) {
return (TeamSpawnStyle) this.bag.get(TeamConfig.SPAWNSTYLE);
}
return null;
}
public void loadFrom(ConfigurationSection teamConfigSection) {
for (TeamConfig config : TeamConfig.values()) {
if (teamConfigSection.contains(config.toString())) {
if (config.getConfigType().equals(Integer.class)) {
this.put(config, teamConfigSection.getInt(config.toString()));
} else if (config.getConfigType().equals(Boolean.class)) {
this.put(config, teamConfigSection.getBoolean(config.toString()));
} else if (config.getConfigType().equals(String.class)) {
this.put(config, teamConfigSection.getString(config.toString()));
} else if (config.getConfigType().equals(Double.class)) {
this.put(config, teamConfigSection.getDouble(config.toString()));
} else if (config.getConfigType().equals(FlagReturn.class)) {
String flagReturnStr = teamConfigSection.getString(config.toString());
FlagReturn returnMode = FlagReturn.getFromString(flagReturnStr);
if (returnMode != null) {
this.put(config, returnMode);
}
} else if (config.getConfigType().equals(TeamSpawnStyle.class)) {
String spawnStyleStr = teamConfigSection.getString(config.toString());
TeamSpawnStyle style = TeamSpawnStyle.getStyleFromString(spawnStyleStr);
if (style != null) {
this.put(config, style);
}
}
}
}
}
public void saveTo(ConfigurationSection teamConfigSection) {
for (TeamConfig config : TeamConfig.values()) {
if (this.contains(config)) {
if (config.getConfigType().equals(Integer.class)
|| config.getConfigType().equals(Boolean.class)
|| config.getConfigType().equals(Double.class)) {
teamConfigSection.set(config.toString(), this.bag.get(config));
} else {
teamConfigSection.set(config.toString(), this.bag.get(config).toString());
}
}
}
}
public String updateFromNamedParams(Map<String, String> namedParams) {
String returnMessage = "";
for (String namedParam : namedParams.keySet()) {
TeamConfig teamConfig = TeamConfig.teamConfigFromString(namedParam);
if (teamConfig != null) {
if (teamConfig.getConfigType().equals(Integer.class)) {
int intValue = Integer.parseInt(namedParams.get(namedParam));
this.bag.put(teamConfig, intValue);
} else if (teamConfig.getConfigType().equals(Double.class)) {
double doubleValue = Double.parseDouble(namedParams.get(namedParam));
this.bag.put(teamConfig, doubleValue);
} else if (teamConfig.getConfigType().equals(Boolean.class)) {
String onOff = namedParams.get(namedParam);
this.bag.put(teamConfig, onOff.equals("on") || onOff.equals("true"));
} else if (teamConfig.getConfigType().equals(String.class)) {
String str = namedParams.get(namedParam);
this.bag.put(teamConfig, str);
} else if (teamConfig.getConfigType().equals(FlagReturn.class)) {
FlagReturn flagValue = FlagReturn.getFromString(namedParams.get(namedParam));
this.bag.put(teamConfig, flagValue);
} else if (teamConfig.getConfigType().equals(TeamSpawnStyle.class)) {
TeamSpawnStyle spawnValue = TeamSpawnStyle.getStyleFromString(namedParams.get(namedParam));
this.bag.put(teamConfig, spawnValue);
}
returnMessage += " " + teamConfig.toString() + " set to " + namedParams.get(namedParam);
} else if (namedParam.equals("delete")) {
String toDelete = namedParams.get(namedParam);
teamConfig = TeamConfig.teamConfigFromString(toDelete);
// param delete (to restore inheritance)
if (teamConfig != null) {
this.bag.remove(teamConfig);
returnMessage += " " + teamConfig.toString() + " removed";
}
}
}
return returnMessage;
}
}

View File

@ -0,0 +1,157 @@
package com.tommytony.war.config;
import org.bukkit.ChatColor;
import org.bukkit.DyeColor;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.LeatherArmorMeta;
public enum TeamKind {
WHITE (DyeColor.WHITE, Material.WHITE_WOOL, ChatColor.WHITE, 450),
ORANGE (DyeColor.ORANGE, Material.ORANGE_WOOL, ChatColor.GOLD, 51),
MAGENTA (DyeColor.MAGENTA, Material.MAGENTA_WOOL, ChatColor.LIGHT_PURPLE, 353),
BLUE (DyeColor.LIGHT_BLUE, Material.LIGHT_BLUE_WOOL, ChatColor.BLUE, 23),
GOLD (DyeColor.YELLOW, Material.YELLOW_WOOL, ChatColor.YELLOW, 403), // yellow = gold
GREEN (DyeColor.LIME, Material.LIME_WOOL, ChatColor.GREEN, 612),
PINK (DyeColor.PINK, Material.PINK_WOOL, ChatColor.LIGHT_PURPLE, 929),
GRAY (DyeColor.GRAY, Material.GRAY_WOOL, ChatColor.DARK_GRAY, 600),
IRON (DyeColor.GRAY, Material.GRAY_WOOL, ChatColor.GRAY, 154), // lightgrey = iron
DIAMOND (DyeColor.CYAN, Material.CYAN_WOOL, ChatColor.DARK_AQUA, 738), // cyan = diamond
PURPLE (DyeColor.PURPLE, Material.PURPLE_WOOL, ChatColor.DARK_PURPLE, 153),
NAVY (DyeColor.BLUE, Material.BLUE_WOOL, ChatColor.DARK_BLUE, 939),
BROWN (DyeColor.BROWN, Material.BROWN_WOOL, ChatColor.DARK_RED, 908),
DARKGREEN (DyeColor.GREEN, Material.GREEN_WOOL, ChatColor.DARK_GREEN, 612),
RED (DyeColor.RED, Material.RED_WOOL, ChatColor.RED, 245),
BLACK (DyeColor.BLACK, Material.BLACK_WOOL, ChatColor.BLACK, 0);
private final DyeColor dyeColor;
private final ChatColor chatColor;
private final Material material;
private final int potionEffectColor;
TeamKind(DyeColor blockHeadColor, Material material, ChatColor color, int potionEffectColor) {
this.dyeColor = blockHeadColor;
this.material = material;
this.chatColor = color;
this.potionEffectColor = potionEffectColor;
}
public static TeamKind teamKindFromString(String str) {
String lowered = str.toLowerCase();
for (TeamKind kind : TeamKind.values()) {
if (kind.toString().startsWith(lowered)) {
return kind;
}
}
return null;
}
public static TeamKind getTeam(String teamName) {
for (TeamKind team : TeamKind.values()) {
if (team.toString().equalsIgnoreCase(teamName)) {
return team;
}
}
return null;
}
/**
* Get wool block data for the dye color.
* @deprecated TODO remove all spout craft support
* @return wool color data value
*/
public byte getData() {
return this.dyeColor.getWoolData();
}
/**
* Get the color of this team in chat messages.
*
* @return team chat color.
*/
public ChatColor getColor() {
return this.chatColor;
}
/**
* Get the color of the wool block as a bukkit color.
*
* @return wool block color.
*/
public org.bukkit.Color getBukkitColor() {
return this.dyeColor.getColor();
}
/**
* Get head block material.
*
* @return team head block material.
*/
public Material getMaterial() {
return this.material;
}
@Override
public String toString() {
return super.toString().toLowerCase();
}
/**
* Get color of the team's potion effect, for thieves.
*
* @return potion effect color.
*/
public int getPotionEffectColor() {
return this.potionEffectColor;
}
/**
* Get a single item of this team's wool head block.
*
* @return single block head item.
*/
public ItemStack getBlockHead() {
return new ItemStack(this.material, 1);
}
/**
* Check if a block is this team's color block.
*
* @param block Wool block to check.
* @return true if block is this team's color.
*/
public boolean isTeamBlock(BlockState block) {
return block.getType() == material;
}
/**
* Check if an item is this team's color block.
*
* @param item Wool item to check.
* @return true if item is this team's color.
*/
public boolean isTeamItem(ItemStack item) {
return item.getType() == material;
}
public String getFormattedName() {
return this.getColor() + this.name().toLowerCase() + ChatColor.WHITE;
}
public String getCapsName() {
return String.valueOf(name().charAt(0)) + name().substring(1).toLowerCase();
}
/**
* Get a colored hat item for the team.
* @return Hat item with the team's color.
*/
public ItemStack getHat() {
ItemStack helmet = new ItemStack(Material.LEATHER_HELMET);
LeatherArmorMeta meta = (LeatherArmorMeta) helmet.getItemMeta();
meta.setColor(this.getBukkitColor());
helmet.setItemMeta(meta);
return helmet;
}
}

View File

@ -0,0 +1,28 @@
package com.tommytony.war.config;
/**
*
* @author tommytony
*
*/
public enum TeamSpawnStyle {
INVISIBLE,
SMALL,
FLAT,
BIG;
@Override
public String toString() {
return super.toString().toLowerCase();
}
public static TeamSpawnStyle getStyleFromString(String string) {
for (TeamSpawnStyle style : TeamSpawnStyle.values()) {
if (string.toLowerCase().equals(style.toString())) {
return style;
}
}
return TeamSpawnStyle.SMALL;
}
}

View File

@ -0,0 +1,59 @@
package com.tommytony.war.config;
public enum WarConfig {
BUILDINZONESONLY (Boolean.class, "Build in zones only", "Allow building in zones only"),
DISABLEBUILDMESSAGE (Boolean.class, "Disable build message", "Silently prevent building outside zones"),
DISABLEPVPMESSAGE (Boolean.class, "Disable PVP message", "Silently prevent PVP"),
KEEPOLDZONEVERSIONS (Boolean.class, "Keep old zone versions", "If true, archive the warzone on each save"),
MAXZONES (Integer.class, "Max zones", "Limit on number of zones that can be created"),
PVPINZONESONLY (Boolean.class, "PVP in zones only", "If true, limits PVP to warzones"),
TNTINZONESONLY (Boolean.class, "TNT in zones only", "If true, limits TNT to warzones"),
RESETSPEED (Integer.class, "Reset speed", "Number of blocks to reset per tick"),
MAXSIZE (Integer.class, "Max size", "Maximum volume of a warzone"),
LANGUAGE (String.class, "Language", "Preferred server language"),
AUTOJOIN (String.class, "Auto-join", "Name of warzone to send players to upon join"),
TPWARMUP(Integer.class, "TP warmup", "Amount of seconds a player must wait after requesting a teleport"),
DISABLECOOLDOWN (Boolean.class, "Disable the 1.9 combat cooldown", "Disables the attack cooldown when swinging a weapon");
private final Class<?> configType;
private final String title;
private final String description;
WarConfig(Class<?> configType, String title, String description) {
this.configType = configType;
this.title = title;
this.description = description;
}
public Class<?> getConfigType() {
return configType;
}
public String getTitle() {
return title;
}
public String getDescription() {
return description;
}
public static WarConfig warConfigFromString(String str) {
String lowered = str.toLowerCase();
for (WarConfig config : WarConfig.values()) {
if (config.toString().startsWith(lowered)) {
return config;
}
}
return null;
}
public String toStringWithValue(Object value) {
return this.toString() + ":" + value.toString();
}
@Override
public String toString() {
return super.toString().toLowerCase();
}
}

View File

@ -0,0 +1,109 @@
package com.tommytony.war.config;
import java.util.EnumMap;
import java.util.Map;
import java.util.logging.Level;
import com.tommytony.war.War;
import com.tommytony.war.mapper.WarYmlMapper;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
public class WarConfigBag {
EnumMap<WarConfig, Object> bag = new EnumMap<WarConfig, Object>(WarConfig.class);
public void put(WarConfig config, Object value) {
this.bag.put(config, value);
}
public Object getValue(WarConfig config) {
if (this.bag.containsKey(config)) {
return this.bag.get(config);
} else {
return null;
}
}
public Integer getInt(WarConfig config) {
if (this.bag.containsKey(config)) {
return (Integer)this.bag.get(config);
} else {
return null;
}
}
public Boolean getBoolean(WarConfig config) {
if (this.bag.containsKey(config)) {
return (Boolean)this.bag.get(config);
} else {
return null;
}
}
public String getString(WarConfig config) {
if (this.bag.containsKey(config)) {
return (String)this.bag.get(config);
} else {
return null;
}
}
public void loadFrom(ConfigurationSection warConfigSection) {
for (WarConfig config : WarConfig.values()) {
if (warConfigSection.contains(config.toString())) {
if (config.getConfigType().equals(Integer.class)) {
this.put(config, warConfigSection.getInt(config.toString()));
} else if (config.getConfigType().equals(Boolean.class)) {
this.put(config, warConfigSection.getBoolean(config.toString()));
} else if (config.getConfigType().equals(String.class)) {
this.put(config, warConfigSection.getString(config.toString()));
}
}
}
}
public void saveTo(ConfigurationSection warConfigSection) {
for (WarConfig config : WarConfig.values()) {
if (this.bag.containsKey(config)) {
warConfigSection.set(config.toString(), this.bag.get(config));
}
}
}
public String updateFromNamedParams(Map<String, String> namedParams) {
String returnMessage = "";
for (String namedParam : namedParams.keySet()) {
WarConfig warConfig = WarConfig.warConfigFromString(namedParam);
if (warConfig != null) {
if (warConfig.getConfigType().equals(Integer.class)) {
int intValue = Integer.parseInt(namedParams.get(namedParam));
this.bag.put(warConfig, intValue);
} else if (warConfig.getConfigType().equals(Boolean.class)) {
String onOff = namedParams.get(namedParam);
this.bag.put(warConfig, onOff.equals("on") || onOff.equals("true"));
} else if (warConfig.getConfigType().equals(String.class)) {
String str = namedParams.get(namedParam);
this.bag.put(warConfig, str);
}
if (warConfig == WarConfig.LANGUAGE) {
War.reloadLanguage();
}
returnMessage += warConfig.toString() + " set to " + namedParams.get(namedParam);
}
}
return returnMessage;
}
public static void afterUpdate(CommandSender sender, String namedParamReturn, boolean wantsToPrint) {
WarYmlMapper.save();
if (wantsToPrint) {
String config = War.war.printConfig();
War.war.msg(sender, "War config saved. " + namedParamReturn + " " + config);
} else {
War.war.msg(sender, "War config saved. " + namedParamReturn);
}
War.war.log(sender.getName() + " updated War configuration. " + namedParamReturn, Level.INFO);
}
}

View File

@ -0,0 +1,73 @@
package com.tommytony.war.config;
public enum WarzoneConfig {
AUTOASSIGN (Boolean.class, "Auto-Assign", "If true, distributes players across teams"),
BLOCKHEADS (Boolean.class, "Team Helmets", "If true, players are given a team-colored hat"),
DEATHMESSAGES (Boolean.class, "Death Notification", "If true, notify the zone when players are killed"),
DISABLED (Boolean.class, "Disable Zone", "If true, prevent players from joining the zone"),
FRIENDLYFIRE (Boolean.class, "Friendly Fire", "If true, players are allowed to injure teammates"),
GLASSWALLS (Boolean.class, "Glass Walls", "If true, use magic glass walls to keep players in/out of zones"),
INSTABREAK (Boolean.class, "Insta-Break", "If true, players break blocks instantly\nUseful for Spleef gamemodes"),
MINTEAMS (Integer.class, "Minimum Teams", "Minimum number of active teams required to start the battle"),
MINPLAYERS (Integer.class, "Minimum Players", "Minimum number of players required per team to start the battle"),
MONUMENTHEAL (Integer.class, "Monument Heal", "Number of hearts given to players jumping on the monument"),
NOCREATURES (Boolean.class, "No Mobs", "If true, prevent mob spawning"),
NODROPS (Boolean.class, "No Drops", "If true, prevent players from dropping items"),
PVPINZONE (Boolean.class, "PVP", "If true, PVP is enabled\nUseful for Spleef gamemodes"),
REALDEATHS (Boolean.class, "Real Deaths", "If true, send players to the real Minecraft death screen"),
RESETONEMPTY (Boolean.class, "Reset on Empty", "If true, reset the zone when all players leave"),
RESETONCONFIGCHANGE (Boolean.class, "Reset on Config Change", "If true, reset every time the zone config is modified"),
RESETONLOAD (Boolean.class, "Reset on Load", "If true, reset warzone when the server starts"),
RESETONUNLOAD (Boolean.class, "Reset on Unload", "If true, reset warzone when the server stops"),
UNBREAKABLE (Boolean.class, "Unbreakable Blocks", "If true, prevent block breaking"),
JOINMIDBATTLE (Boolean.class, "Join Mid-Battle", "If true, players are allowed to join during a battle"),
AUTOJOIN (Boolean.class, "Auto-Join", "If true, bypass the zone lobby and auto-assign the player a team"),
SCOREBOARD (ScoreboardType.class, "Scoreboard Type", "Type of scoreboard for this zone\nOptions: none, points, lifepool, top kills"),
SOUPHEALING (Boolean.class, "Soup Healing", "If true, allow players to heal by consuming soup"),
ALLOWENDER (Boolean.class, "Allow Ender Chests", "If true, ender chests are allowed\nEnder chests are usually blocked to prevent item duplication"),
RESETBLOCKS (Boolean.class, "Reset Blocks", "If true, reset warzone blocks each battle"),
CAPTUREPOINTTIME (Integer.class, "Capture Control Time", "Time, in seconds, required to gain control of a capture point"),
PREPTIME(Integer.class, "Preparation Time", "Time, in seconds, before players are allowed to fight");
private final Class<?> configType;
private final String title;
private final String description;
WarzoneConfig(Class<?> configType, String title, String description) {
this.configType = configType;
this.title = title;
this.description = description;
}
public Class<?> getConfigType() {
return configType;
}
public String getTitle() {
return title;
}
public String getDescription() {
return description;
}
public static WarzoneConfig warzoneConfigFromString(String str) {
String lowered = str.toLowerCase();
for (WarzoneConfig config : WarzoneConfig.values()) {
if (config.toString().startsWith(lowered)) {
return config;
}
}
return null;
}
public String toStringWithValue(Object value) {
return this.toString() + ":" + value.toString();
}
@Override
public String toString() {
return super.toString().toLowerCase();
}
}

View File

@ -0,0 +1,165 @@
package com.tommytony.war.config;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import org.bukkit.command.CommandSender;
import org.bukkit.configuration.ConfigurationSection;
import java.util.EnumMap;
import java.util.Map;
import java.util.logging.Level;
public class WarzoneConfigBag {
private final Warzone warzone;
EnumMap<WarzoneConfig, Object> bag = new EnumMap<WarzoneConfig, Object>(WarzoneConfig.class);
public WarzoneConfigBag(Warzone warzone) {
this.warzone = warzone;
}
public WarzoneConfigBag() {
// default zone settings (at War level) don't have a warzone
this.warzone = null;
}
public static void afterUpdate(Warzone zone, CommandSender sender, String namedParamReturn, boolean wantsToPrint) {
WarzoneYmlMapper.save(zone);
String zoneReset = "Some changes may require a /resetzone. ";
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.RESETONCONFIGCHANGE)) {
zone.reinitialize(); // bring back team spawns etc
zoneReset = "Zone reset. ";
}
if (wantsToPrint) {
War.war.msg(sender, "Warzone config saved. " + zoneReset + namedParamReturn + " " + War.war.printConfig(zone));
} else {
War.war.msg(sender, "Warzone config saved. " + zoneReset + namedParamReturn);
}
War.war.log(sender.getName() + " updated warzone " + zone.getName() + " configuration." + namedParamReturn, Level.INFO);
if (War.war.getWarHub() != null) { // maybe the zone was disabled/enabled
War.war.getWarHub().getVolume().resetBlocks();
War.war.getWarHub().initialize();
}
}
public void put(WarzoneConfig config, Object value) {
bag.put(config, value);
}
public boolean isEmpty() {
return bag.keySet().size() == 0;
}
public Object getValue(WarzoneConfig config) {
if (bag.containsKey(config)) {
return bag.get(config);
} else {
// use War default config
return War.war.getWarzoneDefaultConfig().getValue(config);
}
}
public Integer getInt(WarzoneConfig config) {
if (bag.containsKey(config)) {
return (Integer) bag.get(config);
} else {
// use War default config
return War.war.getWarzoneDefaultConfig().getInt(config);
}
}
public Boolean getBoolean(WarzoneConfig config) {
if (bag.containsKey(config)) {
return (Boolean) bag.get(config);
} else {
// use War default config
return War.war.getWarzoneDefaultConfig().getBoolean(config);
}
}
public ScoreboardType getScoreboardType(WarzoneConfig config) {
if (bag.containsKey(config)) {
return (ScoreboardType)bag.get(config);
} else {
// use War default config
return War.war.getWarzoneDefaultConfig().getScoreboardType(config);
}
}
public boolean contains(WarzoneConfig config) {
return this.bag.containsKey(config);
}
public void reset() {
this.bag.clear();
}
public void loadFrom(ConfigurationSection warzoneConfigSection) {
for (WarzoneConfig config : WarzoneConfig.values()) {
if (warzoneConfigSection.contains(config.toString())) {
if (config.getConfigType().equals(Integer.class)) {
this.put(config, warzoneConfigSection.getInt(config.toString()));
} else if (config.getConfigType().equals(Boolean.class)) {
this.put(config, warzoneConfigSection.getBoolean(config.toString()));
} else if (config.getConfigType().equals(ScoreboardType.class)) {
this.put(config, ScoreboardType.getFromString(warzoneConfigSection.getString(config.toString())));
}
}
}
}
public void saveTo(ConfigurationSection warzoneConfigSection) {
for (WarzoneConfig config : WarzoneConfig.values()) {
if (this.bag.containsKey(config)) {
if (config.getConfigType().equals(Integer.class)
|| config.getConfigType().equals(Boolean.class)) {
warzoneConfigSection.set(config.toString(), this.bag.get(config));
} else {
warzoneConfigSection.set(config.toString(), this.bag.get(config).toString());
}
}
}
}
public String updateFromNamedParams(Map<String, String> namedParams) {
String returnMessage = "";
for (String namedParam : namedParams.keySet()) {
WarzoneConfig warzoneConfig = WarzoneConfig.warzoneConfigFromString(namedParam);
// param update
if (warzoneConfig != null) {
if (warzoneConfig.getConfigType().equals(Integer.class)) {
int intValue = Integer.parseInt(namedParams.get(namedParam));
this.bag.put(warzoneConfig, intValue);
} else if (warzoneConfig.getConfigType().equals(Boolean.class)) {
String onOff = namedParams.get(namedParam);
this.bag.put(warzoneConfig, onOff.equals("on") || onOff.equals("true"));
if (this.warzone != null && namedParam.equals(WarzoneConfig.AUTOASSIGN.toString())) {
this.warzone.getLobby().setLocation(this.warzone.getTeleport());
this.warzone.getLobby().initialize();
}
} else if (warzoneConfig.getConfigType().equals(ScoreboardType.class)) {
String type = namedParams.get(namedParam);
this.bag.put(warzoneConfig, ScoreboardType.getFromString(type));
}
returnMessage += " " + warzoneConfig.toString() + " set to " + namedParams.get(namedParam);
} else if (namedParam.equals("delete")) {
String toDelete = namedParams.get(namedParam);
warzoneConfig = WarzoneConfig.warzoneConfigFromString(toDelete);
// param delete (to restore inheritance)
if (warzoneConfig != null) {
this.bag.remove(warzoneConfig);
returnMessage += " " + warzoneConfig.toString() + " removed";
}
}
}
return returnMessage;
}
}

View File

@ -0,0 +1,37 @@
package com.tommytony.war.event;
import java.util.List;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import com.tommytony.war.Team;
import com.tommytony.war.Warzone;
public class WarBattleWinEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private List<Team> winningTeams;
private Warzone zone;
public WarBattleWinEvent(Warzone zone, List<Team> winningTeams) {
this.zone = zone;
this.winningTeams = winningTeams;
}
public Warzone getZone() {
return zone;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
public List<Team> getWinningTeams() {
return winningTeams;
}
}

View File

@ -0,0 +1,407 @@
package com.tommytony.war.event;
import com.tommytony.war.Team;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.TeamConfig;
import com.tommytony.war.config.WarConfig;
import com.tommytony.war.config.WarzoneConfig;
import com.tommytony.war.structure.Bomb;
import com.tommytony.war.structure.Cake;
import com.tommytony.war.structure.Monument;
import com.tommytony.war.utility.Compat;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.*;
import org.bukkit.event.world.StructureGrowEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author tommytony
*
*/
public class WarBlockListener implements Listener {
@EventHandler
public void onBlockPlace(final BlockPlaceEvent event) {
if (!War.war.isLoaded()) {
return;
}
Player player = event.getPlayer();
Block block = event.getBlock();
if (player == null || block == null) {
return;
}
Team team = Team.getTeamByPlayerName(player.getName());
Warzone zone = Warzone.getZoneByLocation(player);
// Monument capturing
if (team != null && zone != null && zone.isMonumentCenterBlock(block) && team.getKind().isTeamBlock(block.getState())) {
Monument monument = zone.getMonumentFromCenterBlock(block);
if (monument != null && !monument.hasOwner()) {
monument.capture(team);
zone.broadcast("zone.monument.capture", monument.getName(), team.getName());
event.setCancelled(false);
return; // important otherwise cancelled down a few line by isImportantblock
} else {
War.war.badMsg(player, "zone.monument.badblock");
cancelAndKeepItem(event);
return;
}
}
boolean isZoneMaker = War.war.isZoneMaker(player);
// prevent build in important parts
if (zone != null && (zone.isImportantBlock(block) || zone.isOpponentSpawnPeripheryBlock(team, block)) && (!isZoneMaker || team != null)) {
War.war.badMsg(player, "build.denied.location");
cancelAndKeepItem(event);
return;
}
// protect warzone lobbies
for (Warzone wz : War.war.getWarzones()) {
if (wz.getLobby() != null && wz.getLobby().getVolume() != null && wz.getLobby().getVolume().contains(block)) {
War.war.badMsg(player, "build.denied.location");
cancelAndKeepItem(event);
return;
}
}
// protect the hub
if (War.war.getWarHub() != null && War.war.getWarHub().getVolume().contains(block)) {
War.war.badMsg(player, "build.denied.location");
cancelAndKeepItem(event);
return;
}
// buildInZonesOnly
if (zone == null && War.war.getWarConfig().getBoolean(WarConfig.BUILDINZONESONLY) && !War.war.canBuildOutsideZone(player)) {
if (!War.war.getWarConfig().getBoolean(WarConfig.DISABLEBUILDMESSAGE)) {
War.war.badMsg(player, "build.denied.outside");
}
cancelAndKeepItem(event);
return;
}
// can't place a block of your team's color
if (team != null && block.getType() == team.getKind().getMaterial()) {
War.war.badMsg(player, "build.denied.teamblock");
cancelAndKeepItem(event);
return;
}
// a flag thief can't drop his flag
if (team != null && zone != null && zone.isFlagThief(player)) {
War.war.badMsg(player, "drop.flag.disabled");
cancelAndKeepItem(event);
return;
}
// a bomb thief can't drop his bomb
if (team != null && zone != null && zone.isBombThief(player)) {
War.war.badMsg(player, "drop.bomb.disabled");
cancelAndKeepItem(event);
return;
}
// a cake thief can't drop his cake
if (team != null && zone != null && zone.isCakeThief(player)) {
War.war.badMsg(player, "drop.cake.disabled");
cancelAndKeepItem(event);
return;
}
// unbreakableZoneBlocks
if (zone != null && (zone.getWarzoneConfig().getBoolean(WarzoneConfig.UNBREAKABLE) || team != null && !team.getTeamConfig().resolveBoolean(TeamConfig.PLACEBLOCK)) && (!isZoneMaker || team != null)) {
// if the zone is unbreakable, no one but zone makers can break blocks (even then, zone makers in a team can't break blocks)
War.war.badMsg(player, "build.denied.zone.place");
cancelAndKeepItem(event);
return;
}
if (team != null && !team.canModify(block.getType())) {
War.war.badMsg(player, "build.denied.zone.type");
cancelAndKeepItem(event);
return;
}
}
private void cancelAndKeepItem(BlockPlaceEvent event) {
event.setCancelled(true);
ItemStack inHand = event.getItemInHand();
ItemStack newItemInHand;
if (inHand.getType() == Material.FIRE) {
// Weird bukkit/mc behavior where item in hand is reported as fire while using flint & steel.
// Just give the user his f&s back but almost broken (max durability is 8).
newItemInHand = Compat.createDamagedIS(Material.FLINT_AND_STEEL, 1, 1);
} else {
newItemInHand = inHand.clone();
}
if (event.getHand() == EquipmentSlot.OFF_HAND) {
event.getPlayer().getInventory().setItemInOffHand(newItemInHand);
} else {
event.getPlayer().getInventory().setItemInMainHand(newItemInHand);
}
}
@EventHandler
// Do not allow moving of block into or from important zones
public void onBlockPistonExtend(final BlockPistonExtendEvent event) {
Warzone zone = Warzone.getZoneByLocation(event.getBlock().getLocation());
if (zone != null) {
for (Block b : event.getBlocks()) {
if (zone.isImportantBlock(b)) {
event.setCancelled(true);
return;
}
}
//noinspection deprecation
if (zone.isImportantBlock(event.getBlock().getRelative(event.getDirection(), event.getLength()+1))) {
event.setCancelled(true);
}
}
}
@EventHandler
public void onBlockPistonRetract(final BlockPistonRetractEvent event) {
Warzone zone = Warzone.getZoneByLocation(event.getBlock().getLocation());
if (zone!=null) {
Block b = event.getBlock().getRelative(event.getDirection(), 2);
if (zone.isImportantBlock(b)) {
event.setCancelled(true);
return;
}
}
}
@EventHandler
public void onBlockBreak(final BlockBreakEvent event) {
if (!War.war.isLoaded()) {
return;
}
Player player = event.getPlayer();
Block block = event.getBlock();
if (player != null && block != null) {
this.handleBreakOrDamage(player, block, event);
}
}
@EventHandler
public void onBlockDamage(final BlockDamageEvent event) {
if (!War.war.isLoaded()) {
return;
}
Player player = event.getPlayer();
Block block = event.getBlock();
Warzone playerZone = Warzone.getZoneByLocation(player);
if (player != null && block != null && playerZone != null && playerZone.getWarzoneConfig().getBoolean(WarzoneConfig.INSTABREAK)) {
Warzone blockZone = Warzone.getZoneByLocation(new Location(block.getWorld(), block.getX(), block.getY(), block.getZ()));
if (blockZone != null && blockZone == playerZone && block.getType() != Material.BEDROCK) {
event.setInstaBreak(true);
}
}
}
@EventHandler
public void onBlockBurn(final BlockBurnEvent event) {
Warzone zone = Warzone.getZoneByLocation(event.getBlock().getLocation());
if (zone != null && zone.isImportantBlock(event.getBlock())) {
event.setCancelled(true);
}
}
private void handleBreakOrDamage(Player player, Block block, Cancellable event) {
Warzone warzone = Warzone.getZoneByLocation(player);
Team team = Team.getTeamByPlayerName(player.getName());
boolean isZoneMaker = War.war.isZoneMaker(player);
if (warzone != null && team == null && !isZoneMaker) {
// can't actually destroy blocks in a warzone if not part of a team
War.war.badMsg(player, "build.denied.zone.outside");
event.setCancelled(true);
return;
}
// monument's center is destroyed
if (team != null && block != null && warzone != null && warzone.isMonumentCenterBlock(block)) {
Monument monument = warzone.getMonumentFromCenterBlock(block);
if (monument.hasOwner()) {
Team ownerTeam = monument.getOwnerTeam();
warzone.broadcast("zone.monument.lose", ownerTeam.getName(), monument.getName());
monument.uncapture();
}
event.setCancelled(false);
return;
}
// changes in parts of important areas
if (warzone != null && warzone.isImportantBlock(block) && (!isZoneMaker || team != null)) {
// breakage of spawn
if (team.isSpawnLocation(block.getLocation())) {
// let team members loot one block the spawn for monument captures
if (player.getInventory().containsAtLeast(team.getKind().getBlockHead(), 1)) {
War.war.badMsg(player, "build.denied.zone.multteam", team.getName());
event.setCancelled(true);
return;
} else {
event.setCancelled(false); // very important, otherwise could get cancelled but unbreakableZoneBlocks further down
return;
}
}
// stealing of flag
if (warzone.isEnemyTeamFlagBlock(team, block)) {
if (warzone.isFlagThief(player)) {
// detect audacious thieves
War.war.badMsg(player, "zone.stealextra.flag");
} else if (warzone.isBombThief(player) || warzone.isCakeThief(player)) {
War.war.badMsg(player, "zone.stealextra.other");
} else {
Team lostFlagTeam = warzone.getTeamForFlagBlock(block);
if (lostFlagTeam.getPlayers().size() != 0) {
// player just broke the flag block of other team: cancel to avoid drop, give player the block, set block to air
ItemStack teamKindBlock = lostFlagTeam.getKind().getBlockHead();
player.getInventory().clear();
player.getInventory().addItem(teamKindBlock);
warzone.addFlagThief(lostFlagTeam, player);
block.setType(Material.AIR);
for (Team t : warzone.getTeams()) {
t.teamcast("zone.steal.flag.broadcast", team.getKind().getColor() + player.getName() + ChatColor.WHITE, lostFlagTeam.getName());
if (t.getName().equals(lostFlagTeam.getName())) {
t.teamcast("zone.steal.flag.prevent", team.getKind().getColor() + player.getName() + ChatColor.WHITE, team.getName());
}
}
War.war.msg(player, "zone.steal.flag.notice", lostFlagTeam.getName());
} else {
War.war.msg(player, "zone.steal.flag.empty", lostFlagTeam.getName());
}
}
event.setCancelled(true);
return;
} else if (warzone.isBombBlock(block)) {
if (warzone.isBombThief(player)) {
// detect audacious thieves
War.war.badMsg(player, "zone.stealextra.bomb");
} else if (warzone.isFlagThief(player) || warzone.isCakeThief(player)) {
War.war.badMsg(player, "zone.stealextra.other");
} else {
Bomb bomb = warzone.getBombForBlock(block);
// player just broke the bomb block: cancel to avoid drop, give player the block, set block to air
ItemStack tntBlock = new ItemStack(Material.TNT);
tntBlock.setDurability((short)8);
player.getInventory().clear();
player.getInventory().addItem(tntBlock);
warzone.addBombThief(bomb, player);
block.setType(Material.AIR);
for (Team t : warzone.getTeams()) {
t.teamcast("zone.steal.bomb.broadcast", team.getKind().getColor() + player.getName() + ChatColor.WHITE, ChatColor.GREEN + bomb.getName() + ChatColor.WHITE);
t.teamcast("zone.steal.bomb.prevent", team.getKind().getColor() + player.getName() + ChatColor.WHITE);
}
War.war.msg(player, "zone.steal.bomb.notice", bomb.getName());
}
event.setCancelled(true);
return;
} else if (warzone.isCakeBlock(block)) {
if (warzone.isCakeThief(player)) {
// detect audacious thieves
War.war.badMsg(player, "zone.stealextra.cake");
} else if (warzone.isFlagThief(player) || warzone.isBombThief(player)) {
War.war.badMsg(player, "zone.stealextra.other");
} else {
Cake cake = warzone.getCakeForBlock(block);
// player just broke the cake block: cancel to avoid drop, give player the block, set block to air
ItemStack cakeBlock = new ItemStack(Material.CAKE);
cakeBlock.setDurability((short)8);
player.getInventory().clear();
player.getInventory().addItem(cakeBlock);
warzone.addCakeThief(cake, player);
block.setType(Material.AIR);
for (Team t : warzone.getTeams()) {
t.teamcast("zone.steal.cake.broadcast", team.getKind().getColor() + player.getName() + ChatColor.WHITE, ChatColor.GREEN + cake.getName() + ChatColor.WHITE);
t.teamcast("zone.steal.cake.prevent", team.getKind().getColor() + player.getName() + ChatColor.WHITE);
}
War.war.msg(player, "zone.steal.cake.notice", cake.getName());
}
event.setCancelled(true);
return;
} else if (!warzone.isMonumentCenterBlock(block)) {
War.war.badMsg(player, "build.denied.location");
event.setCancelled(true);
return;
}
}
// protect warzone lobbies
if (block != null) {
for (Warzone zone : War.war.getWarzones()) {
if (zone.getLobby() != null && zone.getLobby().getVolume() != null && zone.getLobby().getVolume().contains(block)) {
War.war.badMsg(player, "build.denied.location");
event.setCancelled(true);
return;
}
}
}
// protect the hub
if (War.war.getWarHub() != null && War.war.getWarHub().getVolume().contains(block)) {
War.war.badMsg(player, "build.denied.location");
event.setCancelled(true);
return;
}
// buildInZonesOnly
Warzone blockZone = Warzone.getZoneByLocation(new Location(block.getWorld(), block.getX(), block.getY(), block.getZ()));
if (blockZone == null && War.war.getWarConfig().getBoolean(WarConfig.BUILDINZONESONLY) && !War.war.canBuildOutsideZone(player)) {
if (!War.war.getWarConfig().getBoolean(WarConfig.DISABLEBUILDMESSAGE)) {
War.war.badMsg(player, "build.denied.outside");
}
event.setCancelled(true);
return;
}
// unbreakableZoneBlocks
if (blockZone != null && blockZone.getWarzoneConfig().getBoolean(WarzoneConfig.UNBREAKABLE) && (!isZoneMaker || (isZoneMaker && team != null))) {
// if the zone is unbreakable, no one but zone makers can break blocks (even then, zone makers in a team can't break blocks
War.war.badMsg(player, "build.denied.zone.break");
event.setCancelled(true);
return;
}
if (team != null && !team.canModify(block.getType())) {
War.war.badMsg(player, "build.denied.zone.type");
event.setCancelled(true);
return;
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onStructureGrowth(final StructureGrowEvent event) {
Warzone zone = Warzone.getZoneByLocation(event.getLocation());
if (zone != null) {
List<BlockState> canceledBlocks = new ArrayList<BlockState>();
for (BlockState state : event.getBlocks()) {
if (!zone.getVolume().contains(state.getLocation())
|| zone.isImportantBlock(state.getBlock())) {
canceledBlocks.add(state);
}
}
for (BlockState state : canceledBlocks) {
event.getBlocks().remove(state);
}
}
}
}

View File

@ -0,0 +1,551 @@
package com.tommytony.war.event;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.text.MessageFormat;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.*;
import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason;
import org.bukkit.event.hanging.HangingPlaceEvent;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.projectiles.ProjectileSource;
import org.bukkit.util.Vector;
import com.tommytony.war.Team;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.TeamConfig;
import com.tommytony.war.config.WarConfig;
import com.tommytony.war.config.WarzoneConfig;
import com.tommytony.war.job.DeferredBlockResetsJob;
import com.tommytony.war.structure.Bomb;
import com.tommytony.war.utility.LoadoutSelection;
/**
* Handles Entity-Events
*
* @author tommytony, Tim Düsterhus
* @package com.tommytony.war.event
*/
public class WarEntityListener implements Listener {
/**
* Handles PVP-Damage
*
* @param event
* fired event
*/
private void handlerAttackDefend(EntityDamageByEntityEvent event) {
Entity attacker = event.getDamager();
Entity defender = event.getEntity();
// Maybe an arrow was thrown
if (attacker != null && event.getDamager() instanceof Projectile && ((Projectile)event.getDamager()).getShooter() instanceof Player){
attacker = ((Player)((Projectile)event.getDamager()).getShooter());
}
if (attacker != null && defender != null && attacker instanceof Player && defender instanceof Player) {
// only let adversaries (same warzone, different team) attack each other
Player a = (Player) attacker;
Player d = (Player) defender;
Warzone attackerWarzone = Warzone.getZoneByPlayerName(a.getName());
Team attackerTeam = Team.getTeamByPlayerName(a.getName());
Warzone defenderWarzone = Warzone.getZoneByPlayerName(d.getName());
Team defenderTeam = Team.getTeamByPlayerName(d.getName());
if ((attackerTeam != null && defenderTeam != null && attackerTeam != defenderTeam && attackerWarzone == defenderWarzone)
|| (attackerTeam != null && defenderTeam != null && attacker.getEntityId() == defender.getEntityId())) {
LoadoutSelection defenderLoadoutState = defenderWarzone.getLoadoutSelections().get(d.getName());
if (defenderLoadoutState != null && defenderLoadoutState.isStillInSpawn()) {
War.war.badMsg(a, "pvp.target.spawn");
event.setCancelled(true);
return;
}
LoadoutSelection attackerLoadoutState = attackerWarzone.getLoadoutSelections().get(a.getName());
if (attackerLoadoutState != null && attackerLoadoutState.isStillInSpawn()) {
War.war.badMsg(a, "pvp.self.spawn");
event.setCancelled(true);
return;
}
// Make sure none of them are locked in by respawn timer
if (defenderWarzone.isRespawning(d)) {
War.war.badMsg(a, "pvp.target.respawn");
event.setCancelled(true);
return;
} else if (attackerWarzone.isRespawning(a)) {
War.war.badMsg(a, "pvp.self.respawn");
event.setCancelled(true);
return;
}
if(!defenderWarzone.getPvpReady()) {
//if the timer is still tickin we gotta handle defense! (there be notchz in virgina)
event.setCancelled(true);
return;
}
if (!attackerWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.PVPINZONE)) {
// spleef-like, non-pvp, zone
event.setCancelled(true);
return;
}
// Detect death, prevent it and respawn the player
if (event.getDamage() >= d.getHealth()) {
if (defenderWarzone.getReallyDeadFighters().contains(d.getName())) {
// don't re-kill a dead person
return;
}
WarPlayerDeathEvent event1 = new WarPlayerDeathEvent(defenderWarzone, d, a, event.getCause());
War.war.getServer().getPluginManager().callEvent(event1);
if (!defenderWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.REALDEATHS)) {
// fast respawn, don't really die
event.setCancelled(true);
}
if (d == a) {
defenderWarzone.handleSuicide(d);
} else {
defenderWarzone.handleKill(a, d, event.getDamager());
}
} else if (defenderWarzone.isBombThief(d) && d.getLocation().distance(a.getLocation()) < 2) {
// Close combat, close enough to detonate
Bomb bomb = defenderWarzone.getBombForThief(d);
// Kill the bomber
WarPlayerDeathEvent event1 = new WarPlayerDeathEvent(defenderWarzone, d, null, event.getCause());
War.war.getServer().getPluginManager().callEvent(event1);
defenderWarzone.handleDeath(d);
if (defenderWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.REALDEATHS)) {
// and respawn him and remove from deadmen (cause realdeath + handleDeath means no respawn and getting queued up for onPlayerRespawn)
defenderWarzone.getReallyDeadFighters().remove(d.getName());
defenderWarzone.respawnPlayer(defenderTeam, d);
}
// Blow up bomb
if (!defenderWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.UNBREAKABLE)) {
defenderWarzone.getWorld().createExplosion(a.getLocation(), 2F);
}
// bring back tnt
bomb.getVolume().resetBlocks();
bomb.addBombBlocks();
// Notify everyone
for (Team t : defenderWarzone.getTeams()) {
t.sendAchievement(attackerTeam.getKind().getColor() + a.getName() + ChatColor.YELLOW + " made ",
defenderTeam.getKind().getColor() + d.getName() + ChatColor.YELLOW + " blow up!", new ItemStack(Material.TNT), 10000);
t.teamcast("pvp.kill.bomb", attackerTeam.getKind().getColor() + a.getName() + ChatColor.WHITE,
defenderTeam.getKind().getColor() + d.getName() + ChatColor.WHITE);
}
}
} else if (attackerTeam != null && defenderTeam != null && attackerTeam == defenderTeam && attackerWarzone == defenderWarzone && attacker.getEntityId() != defender.getEntityId()) {
// same team, but not same person
if (attackerWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.FRIENDLYFIRE)) {
War.war.badMsg(a, "pvp.ff.enabled"); // if ff is on, let the attack go through
} else {
War.war.badMsg(a, "pvp.ff.disabled");
event.setCancelled(true); // ff is off
}
} else if (attackerTeam == null && defenderTeam == null && War.war.canPvpOutsideZones(a)) {
// let normal PVP through is its not turned off or if you have perms
} else if (attackerTeam == null && defenderTeam == null && !War.war.canPvpOutsideZones(a)) {
if (!War.war.getWarConfig().getBoolean(WarConfig.DISABLEPVPMESSAGE)) {
War.war.badMsg(a, "pvp.outside.permission");
}
event.setCancelled(true); // global pvp is off
} else {
if (attackerTeam == null) {
War.war.badMsg(a, "pvp.self.notplaying");
} else if (defenderTeam == null) {
War.war.badMsg(a, "pvp.target.notplaying");
} else if (attacker != null && defender != null && attacker.getEntityId() == defender.getEntityId()) {
// You just hit yourself, probably with a bouncing arrow
} else if (attackerTeam == defenderTeam) {
War.war.badMsg(a, "pvp.ff.disabled");
} else if (attackerWarzone != defenderWarzone) {
War.war.badMsg(a, "pvp.target.otherzone");
}
event.setCancelled(true); // can't attack someone inside a warzone if you're not in a team
}
} else if (defender instanceof Player) {
// attacked by dispenser arrow most probably
// Detect death, prevent it and respawn the player
Player d = (Player) defender;
Warzone defenderWarzone = Warzone.getZoneByPlayerName(d.getName());
if (d != null && defenderWarzone != null && event.getDamage() >= d.getHealth()) {
LoadoutSelection defenderLoadoutState = defenderWarzone.getLoadoutSelections().get(d.getName());
if (defenderLoadoutState != null && defenderLoadoutState.isStillInSpawn()) {
event.setCancelled(true);
return;
}
if (defenderWarzone.getReallyDeadFighters().contains(d.getName())) {
// don't re-kill a dead person
return;
}
WarPlayerDeathEvent event1 = new WarPlayerDeathEvent(defenderWarzone, d, null, event.getCause());
War.war.getServer().getPluginManager().callEvent(event1);
if (!defenderWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.REALDEATHS)) {
// fast respawn, don't really die
event.setCancelled(true);
}
defenderWarzone.handleNaturalKill(d, event);
}
}
}
/**
* Protects important structures from explosions
*
* @see EntityListener.onEntityExplode()
*/
@EventHandler
public void onEntityExplode(final EntityExplodeEvent event) {
if (!War.war.isLoaded()) {
return;
}
// protect zones elements, lobbies and warhub from creepers and tnt
List<Block> explodedBlocks = event.blockList();
List<Block> dontExplode = new ArrayList<Block>();
boolean explosionInAWarzone = event.getEntity() != null && Warzone.getZoneByLocation(event.getEntity().getLocation()) != null;
if (!explosionInAWarzone && War.war.getWarConfig().getBoolean(WarConfig.TNTINZONESONLY) && event.getEntity() instanceof TNTPrimed) {
// if tntinzonesonly:true, no tnt blows up outside zones
event.setCancelled(true);
return;
}
for (Block block : explodedBlocks) {
if (block.getType() == Material.TNT) {
continue; // don't restore TNT (failed to track down regression cause)
}
if (War.war.getWarHub() != null && War.war.getWarHub().getVolume().contains(block)) {
dontExplode.add(block);
} else {
boolean inOneZone = false;
for (Warzone zone : War.war.getWarzones()) {
if (zone.isImportantBlock(block)) {
dontExplode.add(block);
if (zone.isBombBlock(block)) {
// tnt doesn't get reset like normal blocks, gotta schedule a later reset just for the Bomb
// structure's tnt block
DeferredBlockResetsJob job = new DeferredBlockResetsJob();
BlockState tnt = block.getState();
tnt.setType(Material.TNT);
job.add(tnt);
War.war.getServer().getScheduler().scheduleSyncDelayedTask(War.war, job, 10);
}
inOneZone = true;
break;
} else if (zone.getLobby() != null && zone.getLobby().getVolume().contains(block)) {
dontExplode.add(block);
inOneZone = true;
break;
} else if (zone.getVolume().contains(block)) {
inOneZone = true;
}
}
if (!inOneZone && explosionInAWarzone) {
// if the explosion originated in warzone, always rollback
dontExplode.add(block);
}
}
}
int dontExplodeSize = dontExplode.size();
if (dontExplode.size() > 0) {
// Reset the exploded blocks that shouldn't have exploded (some of these are zone artifacts, if rollbackexplosion some may be outside-of-zone blocks
DeferredBlockResetsJob job = new DeferredBlockResetsJob();
for (Block dont : dontExplode) {
job.add(dont.getState());
}
War.war.getServer().getScheduler().scheduleSyncDelayedTask(War.war, job);
// Changed explosion yield following proportion of explosion prevention (makes drops less buggy too)
int explodedSize = explodedBlocks.size();
float middleYeild = (float)(explodedSize - dontExplodeSize) / (float)explodedSize;
float newYeild = middleYeild * event.getYield();
event.setYield(newYeild);
}
}
/**
* Handles damage on Players
*
* @see EntityListener.onEntityDamage()
*/
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onEntityDamage(final EntityDamageEvent event) {
if (!War.war.isLoaded()) {
return;
}
Entity entity = event.getEntity();
if (!(entity instanceof Player)) {
return;
}
Player player = (Player) entity;
// prevent godmode
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
if (zone != null) {
event.setCancelled(false);
}
// pass pvp-damage
if (event instanceof EntityDamageByEntityEvent) {
this.handlerAttackDefend((EntityDamageByEntityEvent) event);
} else {
Team team = Team.getTeamByPlayerName(player.getName());
if (zone != null && team != null) {
LoadoutSelection playerLoadoutState = zone.getLoadoutSelections().get(player.getName());
if (team.isSpawnLocation(player.getLocation())
&& playerLoadoutState != null && playerLoadoutState.isStillInSpawn()) {
// don't let a player still in spawn get damaged
event.setCancelled(true);
} else if (event.getDamage() >= player.getHealth()) {
if (zone.getReallyDeadFighters().contains(player.getName())) {
// don't re-count the death points of an already dead person
return;
}
// Detect death, prevent it and respawn the player
WarPlayerDeathEvent event1 = new WarPlayerDeathEvent(zone, player, null, event.getCause());
War.war.getServer().getPluginManager().callEvent(event1);
if (!zone.getWarzoneConfig().getBoolean(WarzoneConfig.REALDEATHS)) {
// fast respawn, don't really die
event.setCancelled(true);
}
zone.handleNaturalKill(player, event);
}
}
}
}
/**
* Prevents creatures from spawning in warzones if no creatures is active
*
* @see EntityListener.onCreatureSpawn()
*/
@EventHandler
public void onCreatureSpawn(final CreatureSpawnEvent event) {
if (!War.war.isLoaded()) {
return;
}
Location location = event.getLocation();
Warzone zone = Warzone.getZoneByLocation(location);
if (zone != null && zone.getWarzoneConfig().getBoolean(WarzoneConfig.NOCREATURES)) {
event.setCancelled(true);
}
}
/**
* Prevents health regaining caused by peaceful mode
*
* @see EntityListener.onEntityRegainHealth()
*/
@EventHandler
public void onEntityRegainHealth(final EntityRegainHealthEvent event) {
if (!War.war.isLoaded()) {
return;
}
Entity entity = event.getEntity();
if (!(entity instanceof Player)) {
return;
}
Player player = (Player) entity;
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
if (zone != null) {
Team team = Team.getTeamByPlayerName(player.getName());
if (event.getRegainReason() == RegainReason.SATIATED
&& team.getTeamConfig().resolveBoolean(TeamConfig.NOHUNGER)) {
// noHunger setting means you can't auto-heal with full hunger bar (use saturation instead to control how fast you get hungry)
event.setCancelled(true);
} else if (event.getRegainReason() == RegainReason.REGEN) {
// disable peaceful mode regen
event.setCancelled(true);
}
}
}
@EventHandler
public void onFoodLevelChange(final FoodLevelChangeEvent event) {
if (!War.war.isLoaded() || !(event.getEntity() instanceof Player)) {
return;
}
Player player = (Player) event.getEntity();
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
Team team = Team.getTeamByPlayerName(player.getName());
if (zone != null && team.getTeamConfig().resolveBoolean(TeamConfig.NOHUNGER)){
event.setCancelled(true);
}
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onPlayerDeath(final PlayerDeathEvent event) {
Player player = event.getEntity();
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
if (zone != null) {
event.getDrops().clear();
if (!zone.getWarzoneConfig().getBoolean(WarzoneConfig.REALDEATHS)) {
// catch the odd death that gets away from us when usually intercepting and preventing deaths
zone.handleDeath(player);
Team team = Team.getTeamByPlayerName(player.getName());
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.DEATHMESSAGES)) {
zone.broadcast("pvp.death.other", team.getKind().getColor() + player.getName());
}
War.war.getLogger().log(Level.WARNING, "We missed the death of player {0} - something went wrong.", player.getName());
} else {
event.setDeathMessage("");
}
}
}
@EventHandler
public void onExplosionPrime(final ExplosionPrimeEvent event) {
if (!War.war.isLoaded()) {
return;
}
Location eventLocation = event.getEntity().getLocation();
for (Warzone zone : War.war.getWarzones()) {
if (zone.isBombBlock(eventLocation.getBlock())) {
// prevent the Bomb from exploding on its pedestral
event.setCancelled(true);
return;
}
}
}
@EventHandler
public void onProjectileHit(final ProjectileHitEvent event) {
if (!War.war.isLoaded()) {
return;
}
if (event.getEntityType() == EntityType.EGG) {
if (event.getEntity().hasMetadata("warAirstrike")) {
Location loc = event.getEntity().getLocation();
Warzone zone = Warzone.getZoneByLocation(loc);
if (zone == null) {
return;
}
Location tntPlace = new Location(loc.getWorld(), loc.getX(), Warzone.getZoneByLocation(loc).getVolume().getMaxY(), loc.getZ());
loc.getWorld().spawnEntity(tntPlace, EntityType.PRIMED_TNT);
loc.getWorld().spawnEntity(tntPlace.clone().add(new Vector(2, 0, 0)), EntityType.PRIMED_TNT);
loc.getWorld().spawnEntity(tntPlace.clone().add(new Vector(-2, 0, 0)), EntityType.PRIMED_TNT);
loc.getWorld().spawnEntity(tntPlace.clone().add(new Vector(0, 0, 2)), EntityType.PRIMED_TNT);
loc.getWorld().spawnEntity(tntPlace.clone().add(new Vector(0, 0, -2)), EntityType.PRIMED_TNT);
}
}
}
@EventHandler
public void onProjectileLaunch(final ProjectileLaunchEvent event) {
if (!War.war.isLoaded()) {
return;
}
if (event.getEntityType() == EntityType.EGG) {
ProjectileSource shooter = event.getEntity().getShooter();
if (shooter instanceof Player) {
Player player = (Player) shooter;
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
Team team = Team.getTeamByPlayerName(player.getName());
if (zone != null) {
if (War.war.getKillstreakReward().getAirstrikePlayers().remove(player.getName())) {
event.getEntity().setMetadata("warAirstrike", new FixedMetadataValue(War.war, true));
zone.broadcast("zone.airstrike", team.getKind().getColor() + player.getName() + ChatColor.WHITE);
}
}
}
}
}
@EventHandler
public void onPaintingBreakByEntity(final HangingBreakByEntityEvent event) {
if (!War.war.isLoaded()) {
return;
}
if (!(event.getRemover() instanceof Player)) {
return;
}
Player player = (Player) event.getRemover();
Warzone zone = Warzone.getZoneByLocation(event.getEntity().getLocation());
Team team = Team.getTeamByPlayerName(player.getName());
boolean isZoneMaker = War.war.isZoneMaker(player);
if (team == null && isZoneMaker) {
return;
}
if (zone != null && zone.getWarzoneConfig().getBoolean(WarzoneConfig.UNBREAKABLE)) {
event.setCancelled(true);
War.war.badMsg(player, "build.denied.zone.break");
}
}
@EventHandler
public void onPaintingPlaceByEntity(final HangingPlaceEvent event) {
if (!War.war.isLoaded()) {
return;
}
Player player = event.getPlayer();
Warzone zone = Warzone.getZoneByLocation(event.getBlock().getLocation());
Team team = Team.getTeamByPlayerName(player.getName());
boolean isZoneMaker = War.war.isZoneMaker(player);
if (team == null && isZoneMaker) {
return;
}
if (zone != null && (zone.getWarzoneConfig().getBoolean(WarzoneConfig.UNBREAKABLE)
|| (team != null && !team.getTeamConfig().resolveBoolean(TeamConfig.PLACEBLOCK)))) {
event.setCancelled(true);
War.war.badMsg(player, "build.denied.zone.place");
}
}
@EventHandler
public void onEntityTeleport(final EntityTeleportEvent event) {
if (!War.war.isLoaded()) {
return;
}
if (event.getEntityType() == EntityType.WOLF) {
if (Warzone.getZoneByLocation(event.getTo()) != null) {
// prevent wolves from teleporting to players in zones
event.setCancelled(true);
event.setTo(event.getFrom());
}
}
}
}

View File

@ -0,0 +1,50 @@
package com.tommytony.war.event;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import com.tommytony.war.Warzone;
public class WarPlayerDeathEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private Player victim;
private Warzone zone;
private Entity killer;
private DamageCause cause;
public WarPlayerDeathEvent(Warzone zone, Player victim, Entity killer,
DamageCause cause) {
this.zone = zone;
this.victim = victim;
this.killer = killer;
this.cause = cause;
}
public Warzone getZone() {
return zone;
}
public Entity getKiller() {
return killer;
}
public DamageCause getCause() {
return cause;
}
public Player getVictim() {
return victim;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -0,0 +1,26 @@
package com.tommytony.war.event;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class WarPlayerLeaveEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private String player;
public WarPlayerLeaveEvent(String player) {
this.player = player;
}
public String getQuitter() {
return player;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -0,0 +1,949 @@
package com.tommytony.war.event;
import com.tommytony.war.Team;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.Warzone.LeaveCause;
import com.tommytony.war.command.ZoneSetter;
import com.tommytony.war.config.FlagReturn;
import com.tommytony.war.config.TeamConfig;
import com.tommytony.war.config.WarConfig;
import com.tommytony.war.config.WarzoneConfig;
import com.tommytony.war.structure.Bomb;
import com.tommytony.war.structure.Cake;
import com.tommytony.war.structure.WarHub;
import com.tommytony.war.structure.ZoneLobby;
import com.tommytony.war.utility.Direction;
import com.tommytony.war.utility.Loadout;
import com.tommytony.war.utility.LoadoutSelection;
import com.tommytony.war.volume.Volume;
import org.apache.commons.lang.Validate;
import org.bukkit.*;
import org.bukkit.block.BlockFace;
import org.bukkit.block.Sign;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.*;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
/**
* @author tommytony, Tim Düsterhus
*/
public class WarPlayerListener implements Listener {
private java.util.Random random = new java.util.Random();
private HashMap<String, Location> latestLocations = new HashMap<String, Location>();
/**
* Correctly removes quitting players from warzones
*
* @see PlayerQuitEvent
*/
@EventHandler
public void onPlayerQuit(final PlayerQuitEvent event) {
if (War.war.isLoaded()) {
Player player = event.getPlayer();
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
if (zone != null) {
zone.handlePlayerLeave(player, zone.getEndTeleport(LeaveCause.DISCONNECT), true);
}
if (War.war.isWandBearer(player)) {
War.war.removeWandBearer(player);
}
}
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onPlayerJoin(final PlayerJoinEvent event) {
String autojoinName = War.war.getWarConfig().getString(WarConfig.AUTOJOIN);
boolean autojoinEnabled = !autojoinName.isEmpty();
if (autojoinEnabled) { // Won't be able to find warzone if unset
Warzone autojoinWarzone = Warzone.getZoneByNameExact(autojoinName);
if (autojoinWarzone == null) {
War.war.getLogger().log(Level.WARNING, "Failed to find autojoin warzone ''{0}''.", new Object[] {autojoinName});
return;
}
if (autojoinWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.DISABLED) || autojoinWarzone.isReinitializing()) {
War.war.badMsg(event.getPlayer(), "join.disabled");
event.getPlayer().teleport(autojoinWarzone.getTeleport());
} else if (!autojoinWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.JOINMIDBATTLE) && autojoinWarzone.isEnoughPlayers()) {
War.war.badMsg(event.getPlayer(), "join.progress");
event.getPlayer().teleport(autojoinWarzone.getTeleport());
} else if (autojoinWarzone.isFull()) {
War.war.badMsg(event.getPlayer(), "join.full.all");
event.getPlayer().teleport(autojoinWarzone.getTeleport());
} else if (autojoinWarzone.isFull(event.getPlayer())) {
War.war.badMsg(event.getPlayer(), "join.permission.all");
event.getPlayer().teleport(autojoinWarzone.getTeleport());
} else { // Player will only ever be autoassigned to a team
autojoinWarzone.autoAssign(event.getPlayer());
}
}
}
@EventHandler
public void onPlayerDropItem(final PlayerDropItemEvent event) {
if (War.war.isLoaded()) {
Player player = event.getPlayer();
Team team = Team.getTeamByPlayerName(player.getName());
if (team != null) {
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
if (zone.isFlagThief(player)) {
// a flag thief can't drop his flag
War.war.badMsg(player, "drop.flag.disabled");
event.setCancelled(true);
} else if (zone.isBombThief(player)) {
// a bomb thief can't drop his bomb
War.war.badMsg(player, "drop.bomb.disabled");
event.setCancelled(true);
} else if (zone.isCakeThief(player)) {
// a cake thief can't drop his cake
War.war.badMsg(player, "drop.cake.disabled");
event.setCancelled(true);
} else if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.NODROPS)) {
War.war.badMsg(player, "drop.item.disabled");
event.setCancelled(true);
} else {
Item item = event.getItemDrop();
if (item != null) {
ItemStack itemStack = item.getItemStack();
if (itemStack != null && team.getKind().isTeamItem(itemStack)) {
// Can't drop your team's kind block
War.war.badMsg(player, "drop.team", team.getName());
event.setCancelled(true);
return;
}
if (zone.isNearWall(player.getLocation()) && itemStack != null
&& !team.getTeamConfig().resolveBoolean(TeamConfig.BORDERDROP)) {
War.war.badMsg(player, "drop.item.border");
event.setCancelled(true);
return;
}
if (zone.getLoadoutSelections().keySet().contains(player.getName())
&& zone.getLoadoutSelections().get(player.getName()).isStillInSpawn()) {
// still at spawn
War.war.badMsg(player, "drop.item.spawn");
event.setCancelled(true);
return;
}
}
}
}
if (War.war.isWandBearer(player)) {
Item item = event.getItemDrop();
if (item.getItemStack().getType() == Material.WOODEN_SWORD) {
String zoneName = War.war.getWandBearerZone(player);
War.war.removeWandBearer(player);
War.war.msg(player, "drop.wand", zoneName);
}
}
}
}
private static final int MINIMUM_TEAM_BLOCKS = 1;
@EventHandler
public void onPlayerPickupItem(final EntityPickupItemEvent event) {
if (War.war.isLoaded()) {
if (!(event.getEntity() instanceof Player)) {
return;
}
Player player = (Player) event.getEntity();
Team team = Team.getTeamByPlayerName(player.getName());
if (team != null) {
Warzone zone = team.getZone();
if (zone.isFlagThief(player)) {
// a flag thief can't pick up anything
event.setCancelled(true);
} else {
Item item = event.getItem();
if (item != null) {
ItemStack itemStack = item.getItemStack();
if (itemStack != null && team.getKind().isTeamItem(itemStack) &&
player.getInventory().containsAtLeast(team.getKind().getBlockHead(), MINIMUM_TEAM_BLOCKS)) {
// Can't pick up a second precious block
event.setCancelled(true);
}
}
}
}
}
}
@EventHandler
public void onPlayerCommandPreprocess(final PlayerCommandPreprocessEvent event) {
if (War.war.isLoaded()) {
Player player = event.getPlayer();
Team talkingPlayerTeam = Team.getTeamByPlayerName(player.getName());
if (talkingPlayerTeam != null) {
String msg = event.getMessage();
String[] split = msg.split(" ");
if (!War.war.isWarAdmin(player) && split.length > 0 && split[0].startsWith("/")) {
String command = split[0].substring(1);
if (!command.equals("war") && !command.equals("zones") && !command.equals("warzones") && !command.equals("zone") && !command.equals("warzone") && !command.equals("teams") && !command.equals("join") && !command.equals("leave") && !command.equals("team") && !command.equals("warhub") && !command.equals("zonemaker")) {
// allow white commands
for (String whiteCommand : War.war.getCommandWhitelist()) {
if (whiteCommand.equals(command)) {
return;
}
}
War.war.badMsg(player, "command.disabled");
event.setCancelled(true);
}
}
}
}
}
@EventHandler
public void onPlayerKick(final PlayerKickEvent event) {
if (War.war.isLoaded()) {
Player player = event.getPlayer();
Warzone warzone = Warzone.getZoneByLocation(player);
if (warzone != null) {
// kick player from warzone as well
warzone.handlePlayerLeave(player, warzone.getEndTeleport(LeaveCause.DISCONNECT), true);
}
}
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (War.war.isLoaded()) {
Player player = event.getPlayer();
if (event.getItem() != null && event.getItem().getType() == Material.WOODEN_SWORD && War.war.isWandBearer(player)) {
String zoneName = War.war.getWandBearerZone(player);
ZoneSetter setter = new ZoneSetter(player, zoneName);
if (event.getAction() == Action.LEFT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_AIR) {
War.war.badMsg(player, "wand.toofar");
} else if (event.getAction() == Action.LEFT_CLICK_BLOCK) {
setter.placeCorner1(event.getClickedBlock());
event.setUseItemInHand(Result.ALLOW);
} else if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
setter.placeCorner2(event.getClickedBlock());
event.setUseItemInHand(Result.ALLOW);
}
}
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
if (zone != null && zone.getLoadoutSelections().containsKey(player.getName())
&& zone.getLoadoutSelections().get(player.getName()).isStillInSpawn()) {
event.setUseItemInHand(Result.DENY);
event.setCancelled(true);
// Replace message with sound to reduce spamminess.
// Whenever a player dies in the middle of conflict they will
// likely respawn still trying to use their items to attack
// another player.
player.playSound(player.getLocation(), Sound.ENTITY_ITEM_BREAK, 1, 0);
}
if (zone != null && event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getClickedBlock().getType() == Material.ENDER_CHEST && !zone.getWarzoneConfig().getBoolean(WarzoneConfig.ALLOWENDER)) {
event.setCancelled(true);
War.war.badMsg(player, "use.ender");
}
Team team = Team.getTeamByPlayerName(player.getName());
if (zone != null && team != null && event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getClickedBlock().getType() == Material.ENCHANTING_TABLE && team.getTeamConfig().resolveBoolean(TeamConfig.XPKILLMETER)) {
event.setCancelled(true);
War.war.badMsg(player, "use.enchant");
if (zone.getAuthors().contains(player.getName())) {
War.war.badMsg(player, "use.xpkillmeter");
}
}
if (zone != null && team != null && event.getAction() == Action.RIGHT_CLICK_BLOCK && event.getClickedBlock().getType() == Material.ANVIL && team.getTeamConfig().resolveBoolean(TeamConfig.XPKILLMETER)) {
event.setCancelled(true);
War.war.badMsg(player, "use.anvil");
if (zone.getAuthors().contains(player.getName())) {
War.war.badMsg(player, "use.xpkillmeter");
}
}
if (zone != null && team != null && event.getAction() == Action.RIGHT_CLICK_BLOCK
&& event.getClickedBlock().getState() instanceof InventoryHolder
&& zone.isFlagThief(player)) {
event.setCancelled(true);
War.war.badMsg(player, "drop.flag.disabled");
}
if (zone == null && event.getAction() == Action.RIGHT_CLICK_BLOCK
&& (event.getClickedBlock().getType() == Material.CHEST || event.getClickedBlock().getType() == Material.TRAPPED_CHEST)
&& Warzone.getZoneByLocation(event.getClickedBlock().getLocation()) != null
&& !War.war.isZoneMaker(event.getPlayer())) {
// prevent opening chests inside a warzone if a player is not a zone maker
event.setCancelled(true);
player.playSound(player.getLocation(), Sound.BLOCK_CHEST_LOCKED, 1, 0);
}
}
if (event.getAction() == Action.RIGHT_CLICK_BLOCK
|| event.getAction() == Action.RIGHT_CLICK_AIR) {
Player player = event.getPlayer();
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
if (zone != null && zone.getWarzoneConfig().getBoolean(WarzoneConfig.SOUPHEALING)) {
ItemStack item = event.getItem();
if ((item != null) && (item.getType() == Material.MUSHROOM_STEW)) {
if (player.getHealth() < 20) {
player.setHealth(Math.min(20, player.getHealth() + 7));
item.setType(Material.BOWL);
} else if (player.getFoodLevel() < 20) {
player.setFoodLevel(Math.min(20, player.getFoodLevel() + 6));
player.setSaturation(player.getSaturation() + 7.2f);
item.setType(Material.BOWL);
}
}
}
}
}
@EventHandler
public void onPlayerMove(final PlayerMoveEvent event) {
if (!War.war.isLoaded()) {
return;
}
Player player = event.getPlayer();
Location playerLoc = event.getTo(); // Don't call again we need same result.
Location previousLocation = latestLocations.get(player.getName());
if (previousLocation != null &&
playerLoc.getBlockX() == previousLocation.getBlockX() &&
playerLoc.getBlockY() == previousLocation.getBlockY() &&
playerLoc.getBlockZ() == previousLocation.getBlockZ() &&
playerLoc.getWorld() == previousLocation.getWorld()) {
// we only care when people change location
return;
}
latestLocations.put(player.getName(), playerLoc);
// Signs can automatically teleport you to specific or random warzones
if (playerLoc.getBlock().getType() == Material.SIGN) {
Sign sign = (Sign) playerLoc.getBlock().getState();
if (sign.getLine(0).equals("[zone]")) {
Warzone indicated = Warzone.getZoneByName(sign.getLine(1));
if (indicated != null) {
player.teleport(indicated.getTeleport());
} else if (sign.getLine(1).equalsIgnoreCase("$random")) {
List<Warzone> warzones = War.war.getEnabledWarzones();
if (warzones.size() == 0) return;
int zone = random.nextInt(warzones.size());
Warzone random = warzones.get(zone);
player.teleport(random.getTeleport());
} else if (sign.getLine(1).equalsIgnoreCase("$active")) {
List<Warzone> warzones = War.war.getActiveWarzones();
if (warzones.size() == 0) warzones = War.war.getEnabledWarzones();
if (warzones.size() == 0) return;
int zone = random.nextInt(warzones.size());
Warzone random = warzones.get(zone);
player.teleport(random.getTeleport());
}
}
}
Warzone locZone = Warzone.getZoneByLocation(playerLoc);
ZoneLobby locLobby = ZoneLobby.getLobbyByLocation(playerLoc);
boolean isMaker = War.war.isZoneMaker(player);
// Zone walls
Team currentTeam = Team.getTeamByPlayerName(player.getName());
Warzone playerWarzone = Warzone.getZoneByPlayerName(player.getName()); // this uses the teams, so it asks: get the player's team's warzone
boolean protecting = false;
if (currentTeam != null) {
if (playerWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.GLASSWALLS)) {
protecting = playerWarzone.protectZoneWallAgainstPlayer(player);
}
} else {
Warzone nearbyZone = War.war.zoneOfZoneWallAtProximity(playerLoc);
if (nearbyZone != null && nearbyZone.getWarzoneConfig().getBoolean(WarzoneConfig.GLASSWALLS) && !isMaker) {
protecting = nearbyZone.protectZoneWallAgainstPlayer(player);
}
}
if (!protecting) {
// zone makers still need to delete their walls
// make sure to delete any wall guards as you leave
for (Warzone zone : War.war.getWarzones()) {
zone.dropZoneWallGuardIfAny(player);
}
}
// Warzone lobby gates
if (locLobby != null && currentTeam == null && locLobby.isInAnyGate(playerLoc)) {
Warzone zone = locLobby.getZone();
Team locTeamGate = locLobby.getTeamGate(playerLoc);
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.DISABLED) || zone.isReinitializing()) {
War.war.badMsg(player, "join.disabled");
event.setTo(zone.getTeleport());
} else if (!zone.getWarzoneConfig().getBoolean(WarzoneConfig.JOINMIDBATTLE) && zone.isEnoughPlayers()) {
War.war.badMsg(player, "join.progress");
event.setTo(zone.getTeleport());
} else if (zone.isFull()) {
War.war.badMsg(player, "join.full.all");
event.setTo(zone.getTeleport());
} else if (zone.isFull(player)) {
War.war.badMsg(player, "join.permission.all");
event.setTo(zone.getTeleport());
} else if (locTeamGate != null && locTeamGate.isFull()) {
War.war.badMsg(player, "join.full.single", locTeamGate.getName());
event.setTo(zone.getTeleport());
} else if (locTeamGate != null && !War.war.canPlayWar(player, locTeamGate)) {
War.war.badMsg(player, "join.permission.single", locTeamGate.getName());
event.setTo(zone.getTeleport());
} else if (zone.getLobby().isAutoAssignGate(playerLoc)) {
zone.autoAssign(player);
} else if (locTeamGate != null) {
zone.assign(player, locTeamGate);
}
return;
} else if (locLobby != null && currentTeam == null
&& locLobby.isInWarHubLinkGate(playerLoc)
&& War.war.getWarHub() != null) {
War.war.msg(player, "warhub.teleport");
event.setTo(War.war.getWarHub().getLocation());
return;
}
// Warhub zone gates
WarHub hub = War.war.getWarHub();
if (hub != null && hub.getVolume().contains(player.getLocation())) {
Warzone zone = hub.getDestinationWarzoneForLocation(playerLoc);
if (zone != null && zone.getTeleport() != null) {
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.AUTOJOIN)
&& zone.getTeams().size() >= 1 && currentTeam == null) {
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.DISABLED) || zone.isReinitializing()) {
War.war.badMsg(player, "join.disabled");
event.setTo(hub.getLocation());
} else if (!zone.getWarzoneConfig().getBoolean(WarzoneConfig.JOINMIDBATTLE) && zone.isEnoughPlayers()) {
War.war.badMsg(player, "join.progress");
event.setTo(hub.getLocation());
} else if (zone.isFull()) {
War.war.badMsg(player, "join.full.all");
event.setTo(hub.getLocation());
} else if (zone.isFull(player)) {
War.war.badMsg(player, "join.permission.all");
event.setTo(hub.getLocation());
} else {
zone.autoAssign(player);
}
return;
}
event.setTo(zone.getTeleport());
War.war.msg(player, "zone.teleport", zone.getName());
return;
}
}
boolean isLeaving = playerWarzone != null && playerWarzone.getLobby().isLeavingZone(playerLoc);
Team playerTeam = Team.getTeamByPlayerName(player.getName());
if (isLeaving) { // already in a team and in warzone, leaving
// same as leave
if (playerTeam != null) {
boolean atSpawnAlready = playerTeam.isSpawnLocation(playerLoc);
if (!atSpawnAlready) {
playerWarzone.handlePlayerLeave(player, playerWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.AUTOJOIN) ?
War.war.getWarHub().getLocation() : playerWarzone.getTeleport(), event, true);
return;
}
return;
}
}
if (playerWarzone != null) {
// Player belongs to a warzone team but is outside: he snuck out or is at spawn and died
if (locZone == null && playerTeam != null && playerWarzone.getLobby() != null && !playerWarzone.getLobby().getVolume().contains(playerLoc) && !isLeaving) {
List<BlockFace> nearestWalls = playerWarzone.getNearestWalls(playerLoc);
if (!playerWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.REALDEATHS)) {
War.war.badMsg(player, "zone.leavenotice");
}
if(nearestWalls != null && nearestWalls.size() > 0) {
// First, try to bump the player back in
int northSouthMove = 0;
int eastWestMove = 0;
int upDownMove = 0;
int moveDistance = 1;
if (nearestWalls.contains(Direction.NORTH())) {
// move south
northSouthMove += moveDistance;
} else if (nearestWalls.contains(Direction.SOUTH())) {
// move north
northSouthMove -= moveDistance;
}
if (nearestWalls.contains(Direction.EAST())) {
// move west
eastWestMove += moveDistance;
} else if (nearestWalls.contains(Direction.WEST())) {
// move east
eastWestMove -= moveDistance;
}
if (nearestWalls.contains(BlockFace.UP)) {
upDownMove -= moveDistance;
} else if (nearestWalls.contains(BlockFace.DOWN)) {
// fell off the map, back to spawn (still need to drop objects)
playerWarzone.dropAllStolenObjects(event.getPlayer(), false);
playerWarzone.respawnPlayer(event, playerTeam, event.getPlayer());
return;
}
event.setTo(new Location(playerLoc.getWorld(),
playerLoc.getX() + northSouthMove,
playerLoc.getY() + upDownMove,
playerLoc.getZ() + eastWestMove,
playerLoc.getYaw(),
playerLoc.getPitch()));
return;
// Otherwise, send him to spawn (first make sure he drops his flag/cake/bomb to prevent auto-cap and as punishment)
} else {
playerWarzone.dropAllStolenObjects(event.getPlayer(), false);
playerWarzone.respawnPlayer(event, playerTeam, event.getPlayer());
return;
}
}
LoadoutSelection loadoutSelectionState = playerWarzone.getLoadoutSelections().get(player.getName());
FlagReturn flagReturn = playerTeam.getTeamConfig().resolveFlagReturn();
if (!playerTeam.isSpawnLocation(playerLoc)) {
if (!playerWarzone.isEnoughPlayers() && loadoutSelectionState != null && loadoutSelectionState.isStillInSpawn()) {
// Be sure to keep only players that just respawned locked inside the spawn for minplayer/minteams restrictions - otherwise
// this will conflict with the can't-renter-spawn bump just a few lines below
War.war.badMsg(player, "zone.spawn.minplayers", playerWarzone.getWarzoneConfig().getInt(WarzoneConfig.MINPLAYERS),
playerWarzone.getWarzoneConfig().getInt(WarzoneConfig.MINTEAMS));
event.setTo(playerTeam.getRandomSpawn());
return;
}
if (playerWarzone.isRespawning(player)) {
int rt = playerTeam.getTeamConfig().resolveInt(TeamConfig.RESPAWNTIMER);
War.war.badMsg(player, "zone.spawn.timer", rt);
event.setTo(playerTeam.getRandomSpawn());
return;
}
if (playerWarzone.isReinitializing()) {
// don't let players wander about outside spawns during reset
// (they could mess up the blocks that have already been reset
// before the start of the new battle)
War.war.msg(player, "zone.battle.reset");
event.setTo(playerTeam.getRandomSpawn());
return;
}
} else if (loadoutSelectionState != null && !loadoutSelectionState.isStillInSpawn()
&& !playerWarzone.isCakeThief(player)
&& (flagReturn.equals(FlagReturn.BOTH) || flagReturn.equals(FlagReturn.SPAWN))
&& !playerWarzone.isFlagThief(player)) {
// player is in spawn, but has left already: he should NOT be let back in - kick him out gently
// if he sticks around too long.
// (also, be sure you aren't preventing the flag or cake from being captured)
// if (!CantReEnterSpawnJob.getPlayersUnderSuspicion().contains(player.getName())) {
// CantReEnterSpawnJob job = new CantReEnterSpawnJob(player, playerTeam);
// War.war.getServer().getScheduler().scheduleSyncDelayedTask(War.war, job, 12);
// }
return;
}
// Monuments
if (playerTeam != null && playerWarzone.nearAnyOwnedMonument(playerLoc, playerTeam) && player.getHealth() < 20 && player.getHealth() > 0 // don't heal the dead
&& this.random.nextInt(7) == 3) { // one chance out of many of getting healed
int currentHp = (int) player.getHealth();
int newHp = Math.min(20, currentHp + locZone.getWarzoneConfig().getInt(WarzoneConfig.MONUMENTHEAL));
player.setHealth(newHp);
double heartNum = ((double) newHp - currentHp) / 2;
War.war.msg(player, "zone.monument.voodoo", heartNum);
return;
}
// Flag capture
if (playerWarzone.isFlagThief(player)) {
// smoky
if (System.currentTimeMillis() % 13 == 0) {
playerWarzone.getWorld().playEffect(player.getLocation(), Effect.POTION_BREAK, playerTeam.getKind().getPotionEffectColor());
}
// Make sure game ends can't occur simultaneously.
// See Warzone.handleDeath() for details.
boolean inSpawn = playerTeam.isSpawnLocation(player.getLocation());
boolean inFlag = (playerTeam.getFlagVolume() != null && playerTeam.getFlagVolume().contains(player.getLocation()));
if (playerTeam.getTeamConfig().resolveFlagReturn().equals(FlagReturn.BOTH)) {
if (!inSpawn && !inFlag) {
return;
}
} else if (playerTeam.getTeamConfig().resolveFlagReturn().equals(FlagReturn.SPAWN)) {
if (inFlag) {
War.war.badMsg(player, "zone.flagreturn.spawn");
return;
} else if (!inSpawn) {
return;
}
} else if (playerTeam.getTeamConfig().resolveFlagReturn().equals(FlagReturn.FLAG)) {
if (inSpawn) {
War.war.badMsg(player, "zone.flagreturn.flag");
return;
} else if (!inFlag) {
return;
}
}
if (!playerTeam.getPlayers().contains(player)) {
// Make sure player is still part of team, game may have ended while waiting)
// Ignore the scorers that happened immediately after the game end.
return;
}
if (playerWarzone.isTeamFlagStolen(playerTeam) && playerTeam.getTeamConfig().resolveBoolean(TeamConfig.FLAGMUSTBEHOME)) {
War.war.badMsg(player, "zone.flagreturn.deadlock");
} else {
// flags can be captured at own spawn or own flag pole
if (playerWarzone.isReinitializing()) {
// Battle already ended or interrupted
playerWarzone.respawnPlayer(event, playerTeam, player);
} else {
// All good - proceed with scoring
playerTeam.addPoint();
Team victim = playerWarzone.getVictimTeamForFlagThief(player);
// Notify everyone
for (Team t : playerWarzone.getTeams()) {
t.teamcast("zone.flagcapture.broadcast", playerTeam.getKind().getColor() + player.getName() + ChatColor.WHITE,
victim.getName(), playerTeam.getName());
}
// Detect win conditions
if (playerTeam.getPoints() >= playerTeam.getTeamConfig().resolveInt(TeamConfig.MAXSCORE)) {
if (playerWarzone.hasPlayerState(player.getName())) {
playerWarzone.restorePlayerState(player);
}
playerWarzone.handleScoreCapReached(playerTeam.getName());
event.setTo(playerWarzone.getTeleport());
} else {
// just added a point
victim.getFlagVolume().resetBlocks(); // bring back flag to team that lost it
victim.initializeTeamFlag();
playerWarzone.respawnPlayer(event, playerTeam, player);
playerTeam.resetSign();
playerWarzone.getLobby().resetTeamGateSign(playerTeam);
}
}
playerWarzone.removeFlagThief(player);
return;
}
}
// Bomb detonation
if (playerWarzone.isBombThief(player)) {
// smoky
playerWarzone.getWorld().playEffect(player.getLocation(), Effect.SMOKE, 0);
// Make sure game ends can't occur simultaneously.
// Not thread safe. See Warzone.handleDeath() for details.
boolean inEnemySpawn = false;
Team victim = null;
for (Team team : playerWarzone.getTeams()) {
if (team != playerTeam
&& team.isSpawnLocation(player.getLocation())
&& team.getPlayers().size() > 0) {
inEnemySpawn = true;
victim = team;
break;
}
}
if (inEnemySpawn && playerTeam.getPlayers().contains(player)) {
// Made sure player is still part of team, game may have ended while waiting.
// Ignored the scorers that happened immediately after the game end.
Bomb bomb = playerWarzone.getBombForThief(player);
// Boom!
if (!playerWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.UNBREAKABLE)) {
// Don't blow up if warzone is unbreakable
playerWarzone.getWorld().createExplosion(player.getLocation(), 2F);
}
if (playerWarzone.isReinitializing()) {
// Battle already ended or interrupted
playerWarzone.respawnPlayer(event, playerTeam, player);
} else {
// All good - proceed with scoring
playerTeam.addPoint();
// Notify everyone
for (Team t : playerWarzone.getTeams()) {
t.teamcast("zone.bomb.broadcast", playerTeam.getKind().getColor() + player.getName() + ChatColor.WHITE,
victim.getName(), playerTeam.getName());
}
// Detect win conditions
if (playerTeam.getPoints() >= playerTeam.getTeamConfig().resolveInt(TeamConfig.MAXSCORE)) {
if (playerWarzone.hasPlayerState(player.getName())) {
playerWarzone.restorePlayerState(player);
}
playerWarzone.handleScoreCapReached(playerTeam.getName());
event.setTo(playerWarzone.getTeleport());
} else {
// just added a point
// restore bombed team's spawn
for (Volume spawnVolume : victim.getSpawnVolumes().values()) {
spawnVolume.resetBlocks();
}
victim.initializeTeamSpawns();
// bring back tnt
bomb.getVolume().resetBlocks();
bomb.addBombBlocks();
playerWarzone.respawnPlayer(event, playerTeam, player);
playerTeam.resetSign();
playerWarzone.getLobby().resetTeamGateSign(playerTeam);
}
}
playerWarzone.removeBombThief(player);
return;
}
}
// Cake retrieval
if (playerWarzone.isCakeThief(player)) {
// smoky
if (System.currentTimeMillis() % 13 == 0) {
playerWarzone.getWorld().playEffect(player.getLocation(), Effect.POTION_BREAK, playerTeam.getKind().getPotionEffectColor());
}
// Make sure game ends can't occur simultaneously.
// Not thread safe. See Warzone.handleDeath() for details.
boolean inSpawn = playerTeam.isSpawnLocation(player.getLocation());
if (inSpawn && playerTeam.getPlayers().contains(player)) {
// Made sure player is still part of team, game may have ended while waiting.
// Ignored the scorers that happened immediately after the game end.
boolean hasOpponent = false;
for (Team t : playerWarzone.getTeams()) {
if (t != playerTeam && t.getPlayers().size() > 0) {
hasOpponent = true;
}
}
// Don't let someone alone make points off cakes
if (hasOpponent) {
Cake cake = playerWarzone.getCakeForThief(player);
if (playerWarzone.isReinitializing()) {
// Battle already ended or interrupted
playerWarzone.respawnPlayer(event, playerTeam, player);
} else {
// All good - proceed with scoring
// Woot! Cake effect: 1 pt + full lifepool
playerTeam.addPoint();
playerTeam.setRemainingLives(playerTeam.getTeamConfig().resolveInt(TeamConfig.LIFEPOOL));
// Notify everyone
for (Team t : playerWarzone.getTeams()) {
t.teamcast("zone.cake.broadcast", playerTeam.getKind().getColor() + player.getName() + ChatColor.WHITE,
ChatColor.GREEN + cake.getName() + ChatColor.WHITE, playerTeam.getName());
}
// Detect win conditions
if (playerTeam.getPoints() >= playerTeam.getTeamConfig().resolveInt(TeamConfig.MAXSCORE)) {
if (playerWarzone.hasPlayerState(player.getName())) {
playerWarzone.restorePlayerState(player);
}
playerWarzone.handleScoreCapReached(playerTeam.getName());
event.setTo(playerWarzone.getTeleport());
} else {
// just added a point
// bring back cake
cake.getVolume().resetBlocks();
cake.addCakeBlocks();
playerWarzone.respawnPlayer(event, playerTeam, player);
playerTeam.resetSign();
playerWarzone.getLobby().resetTeamGateSign(playerTeam);
}
}
playerWarzone.removeCakeThief(player);
}
return;
}
}
// Class selection lock
if (!playerTeam.isSpawnLocation(player.getLocation()) &&
playerWarzone.getLoadoutSelections().keySet().contains(player.getName())
&& playerWarzone.getLoadoutSelections().get(player.getName()).isStillInSpawn()) {
playerWarzone.getLoadoutSelections().get(player.getName()).setStillInSpawn(false);
}
} else if (locZone != null && locZone.getLobby() != null && !locZone.getLobby().isLeavingZone(playerLoc) && !isMaker) {
// player is not in any team, but inside warzone boundaries, get him out
Warzone zone = Warzone.getZoneByLocation(playerLoc);
event.setTo(zone.getTeleport());
War.war.badMsg(player, "zone.noteamnotice");
}
}
@EventHandler
public void onPlayerToggleSneak(PlayerToggleSneakEvent event) {
if (War.war.isLoaded() && event.isSneaking()) {
Warzone playerWarzone = Warzone.getZoneByLocation(event.getPlayer());
Team playerTeam = Team.getTeamByPlayerName(event.getPlayer().getName());
if (playerWarzone != null && playerTeam != null && playerTeam.getInventories().resolveLoadouts().keySet().size() > 1 && playerTeam.isSpawnLocation(event.getPlayer().getLocation())) {
if (playerWarzone.getLoadoutSelections().keySet().contains(event.getPlayer().getName())
&& playerWarzone.getLoadoutSelections().get(event.getPlayer().getName()).isStillInSpawn()) {
LoadoutSelection selection = playerWarzone.getLoadoutSelections().get(event.getPlayer().getName());
List<Loadout> loadouts = new ArrayList<Loadout>(playerTeam.getInventories().resolveNewLoadouts());
for (Iterator<Loadout> it = loadouts.iterator(); it.hasNext();) {
Loadout ldt = it.next();
if (ldt.getName().equals("first") ||
(ldt.requiresPermission() && !event.getPlayer().hasPermission(ldt.getPermission()))) {
it.remove();
}
}
int currentIndex = (selection.getSelectedIndex() + 1) % loadouts.size();
selection.setSelectedIndex(currentIndex);
playerWarzone.equipPlayerLoadoutSelection(event.getPlayer(), playerTeam, false, true);
} else {
War.war.badMsg(event.getPlayer(), "zone.loadout.reenter");
}
}
}
}
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerRespawn(PlayerRespawnEvent event) {
Warzone playingZone = Warzone.getZoneByPlayerName(event.getPlayer().getName());
Warzone deadZone = Warzone.getZoneForDeadPlayer(event.getPlayer());
if (playingZone == null && deadZone != null) {
// Game ended while player was dead, so restore state
deadZone.getReallyDeadFighters().remove(event.getPlayer().getName());
if (deadZone.hasPlayerState(event.getPlayer().getName())) {
deadZone.restorePlayerState(event.getPlayer());
}
event.setRespawnLocation(deadZone.getEndTeleport(LeaveCause.DISCONNECT));
return;
} else if (playingZone == null) {
// Player not playing war
return;
} else if (deadZone == null) {
// Player is not a 'really' dead player, nothing to do here
return;
}
Team team = playingZone.getPlayerTeam(event.getPlayer().getName());
Validate.notNull(team, String.format(
"Failed to find a team for player %s in warzone %s on respawn.",
event.getPlayer().getName(), playingZone.getName()));
playingZone.getReallyDeadFighters().remove(event.getPlayer().getName());
event.setRespawnLocation(team.getRandomSpawn());
playingZone.respawnPlayer(team, event.getPlayer());
}
@EventHandler
public void onPlayerTeleport(final PlayerTeleportEvent event) {
if (War.war.isLoaded()) {
Warzone playerWarzone = Warzone.getZoneByPlayerName(event.getPlayer().getName());
Team playerTeam = Team.getTeamByPlayerName(event.getPlayer().getName());
if (playerWarzone != null) {
if (!playerWarzone.getVolume().contains(event.getTo())) {
// Prevent teleporting out of the warzone
if (!playerWarzone.getWarzoneConfig().getBoolean(WarzoneConfig.REALDEATHS)) {
War.war.badMsg(event.getPlayer(), "Use /leave (or /war leave) to exit the zone.");
}
playerWarzone.dropAllStolenObjects(event.getPlayer(), false);
playerWarzone.respawnPlayer(event, playerTeam, event.getPlayer());
}
}
}
}
@EventHandler
public void onPlayerExpChange(PlayerExpChangeEvent event) {
if (War.war.isLoaded()) {
Team team = Team.getTeamByPlayerName(event.getPlayer().getName());
if (team != null && team.getTeamConfig().resolveBoolean(TeamConfig.XPKILLMETER)) {
event.setAmount(0);
}
}
}
@EventHandler(priority = EventPriority.LOW)
public void onPlayerChat(final AsyncPlayerChatEvent event) {
Team team = Team.getTeamByPlayerName(event.getPlayer().getName());
if (team != null && team.isInTeamChat(event.getPlayer())) {
event.setCancelled(true);
team.sendTeamChatMessage(event.getPlayer(), event.getMessage());
}
}
@EventHandler
public void onInventoryClick(final InventoryClickEvent event) {
if (!(event.getWhoClicked() instanceof Player)) {
return;
}
Player player = (Player) event.getWhoClicked();
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
if (zone == null) {
return;
}
if (zone.isThief(player)) {
// Prevent thieves from taking their bomb/wool/cake into a chest, etc.
event.setCancelled(true);
player.playSound(player.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 10, 10);
} else if (event.getSlotType() == InventoryType.SlotType.ARMOR && event.getSlot() == 39
&& zone.getWarzoneConfig().getBoolean(WarzoneConfig.BLOCKHEADS)) {
// Magically give player a wool block when they click their helmet
ItemStack teamBlock = zone.getPlayerTeam(player.getName()).getKind().getBlockHead();
player.getInventory().remove(teamBlock.getType());
// Deprecated behavior cannot be removed as it is essential to this function
//noinspection deprecation
event.setCursor(teamBlock);
event.setCancelled(true);
}
}
public void purgeLatestPositions() {
this.latestLocations.clear();
}
@EventHandler
public void onBucketEmpty(PlayerBucketEmptyEvent event) {
Player player = (Player) event.getPlayer();
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
if (zone == null) {
return;
}
if (zone.isImportantBlock(event.getBlockClicked())) {
event.setCancelled(true);
player.playSound(player.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 10, 10);
}
}
}

View File

@ -0,0 +1,39 @@
package com.tommytony.war.event;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
public class WarPlayerThiefEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private Player player;
private StolenObject type;
public WarPlayerThiefEvent(Player thief, StolenObject stolen) {
this.player = thief;
this.type = stolen;
}
public Player getThief() {
return player;
}
public StolenObject getStolenObject() {
return type;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
public enum StolenObject {
FLAG,
BOMB,
CAKE
}
}

View File

@ -0,0 +1,30 @@
package com.tommytony.war.event;
import java.util.List;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import com.tommytony.war.Team;
public class WarScoreCapEvent extends Event {
private static final HandlerList handlers = new HandlerList();
private List<Team> winningTeams;
public List<Team> getWinningTeams() {
return winningTeams;
}
public WarScoreCapEvent(List<Team> winningTeams) {
this.winningTeams = winningTeams;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
}

View File

@ -0,0 +1,17 @@
package com.tommytony.war.job;
import com.tommytony.war.volume.Volume;
public class BlockResetJob implements Runnable {
private final Volume volume;
public BlockResetJob(Volume volume) {
this.volume = volume;
}
public void run() {
this.volume.resetBlocks();
}
}

View File

@ -0,0 +1,119 @@
package com.tommytony.war.job;
import com.tommytony.war.Team;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.TeamConfig;
import com.tommytony.war.structure.CapturePoint;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
public class CapturePointTimer extends BukkitRunnable {
@Override
public void run() {
if (!War.war.isLoaded()) {
return;
}
for (Player player : War.war.getServer().getOnlinePlayers()) {
Warzone zone = Warzone.getZoneByPlayerName(player.getName());
Team team = Team.getTeamByPlayerName(player.getName());
if (zone == null || team == null) {
continue;
}
for (CapturePoint cp : zone.getCapturePoints()) {
if (cp.getVolume().contains(player.getLocation())) {
// player is maintaining or contesting capture point.
if (cp.getController() == null) {
// take control of unclaimed point
incrementStrength(cp, player, zone, team);
} else if (cp.getController() != team.getKind()) {
// contest other team's point
decrementStrength(cp, player, zone, team);
} else if (cp.getController() == team.getKind()) {
// maintain your team's point
incrementStrength(cp, player, zone, team);
}
}
}
}
for (Warzone zone : War.war.getWarzones()) {
for (CapturePoint cp : zone.getCapturePoints()) {
if (cp.getController() != null && cp.getController() != cp.getDefaultController()
&& cp.getStrength() == cp.getMaxStrength()) {
int controlTime = cp.getControlTime() + 1;
cp.setControlTime(controlTime);
if (controlTime % cp.getMaxStrength() == 0) {
// give points for every control time which is a multiple of the time taken to capture
Team team = zone.getTeamByKind(cp.getController());
team.addPoint();
zone.broadcast("zone.capturepoint.addpoint",
cp.getController().getFormattedName(), cp.getName());
// Detect win conditions
if (team.getPoints() >= team.getTeamConfig().resolveInt(TeamConfig.MAXSCORE)) {
zone.handleScoreCapReached(team.getName());
} else {
// just added a point
team.resetSign();
zone.getLobby().resetTeamGateSign(team);
}
}
}
}
}
}
private static void decrementStrength(CapturePoint cp, Player player, Warzone zone, Team team) {
int strength = cp.getStrength();
if (strength < 1) {
// strength is already at minimum, ensure attributes are wiped
cp.setController(null);
cp.setStrength(0);
return;
}
strength -= 1;
if (strength == 0) {
if (cp.antiChatSpam()) {
zone.broadcast("zone.capturepoint.lose", cp.getController().getFormattedName(), cp.getName());
}
cp.setControlTime(0);
cp.setController(null);
} else if (strength == cp.getMaxStrength() - 1) {
if (cp.antiChatSpam()) {
zone.broadcast("zone.capturepoint.contest", cp.getName(),
team.getKind().getColor() + player.getName() + ChatColor.WHITE);
}
}
cp.setStrength(strength);
}
private static void incrementStrength(CapturePoint cp, Player player, Warzone zone, Team team) {
int strength = cp.getStrength();
if (strength > cp.getMaxStrength()) {
// cap strength at CapturePoint.MAX_STRENGTH
cp.setStrength(cp.getMaxStrength());
return;
} else if (strength == cp.getMaxStrength()) {
// do nothing
return;
}
strength += 1;
if (strength == cp.getMaxStrength()) {
if (cp.antiChatSpam()) {
zone.broadcast("zone.capturepoint.capture", cp.getController().getFormattedName(), cp.getName());
}
team.addPoint();
} else if (strength == 1) {
if (cp.antiChatSpam()) {
zone.broadcast("zone.capturepoint.fortify", team.getKind().getFormattedName(), cp.getName());
}
cp.setController(team.getKind());
}
cp.setStrength(strength);
}
}

View File

@ -0,0 +1,47 @@
package com.tommytony.war.job;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.World;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import com.tommytony.war.utility.DeferredBlockReset;
public class DeferredBlockResetsJob implements Runnable {
List<BlockState> deferred = new ArrayList<BlockState>();
public DeferredBlockResetsJob() {
}
@Deprecated
public DeferredBlockResetsJob(World humor) {
}
public void add(BlockState pleaseResetLater) {
this.deferred.add(pleaseResetLater);
}
@Deprecated
public void add(DeferredBlockReset humor) {
}
public boolean isEmpty() {
return this.deferred.isEmpty();
}
public void run() {
for (BlockState reset : this.deferred) {
reset.update(true, false);
for (Entity ent : reset.getWorld().getEntities()) {
if (ent instanceof Item
&& ent.getLocation().distance(reset.getLocation()) < 2) {
ent.remove();
}
}
}
}
}

View File

@ -0,0 +1,87 @@
package com.tommytony.war.job;
import java.util.HashMap;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import com.tommytony.war.Team;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.WarzoneConfig;
/**
* Sets the helmet again onto the players heads. Also limits the number of blocks being held.
*
* @author Tim Düsterhus
*/
public class HelmetProtectionTask implements Runnable {
public void run() {
if (!War.war.isLoaded()) {
return;
}
for (Warzone zone : War.war.getWarzones()) {
for (Team team : zone.getTeams()) {
for (Player player : team.getPlayers()) {
PlayerInventory playerInv = player.getInventory();
Material teamBlockMaterial;
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.BLOCKHEADS)) {
teamBlockMaterial = team.getKind().getMaterial();
// 1) Replace missing block head
if (playerInv.getHelmet() == null || playerInv.getHelmet().getType() != Material.LEATHER_HELMET) {
playerInv.setHelmet(team.getKind().getHat());
}
// 2) Get rid of extra blocks in inventory: only keep one
HashMap<Integer, ? extends ItemStack> blocks = playerInv.all(teamBlockMaterial);
if (blocks.size() > 1 || (blocks.size() == 1 && blocks.get(blocks.keySet().iterator().next()).getAmount() > 1)) {
int i = 0;
int removed = 0;
for (ItemStack item : playerInv.getContents()) {
// remove only same colored wool
if (item != null && item.getType() == teamBlockMaterial) {
playerInv.clear(i);
removed++;
}
i++;
}
int firstEmpty = playerInv.firstEmpty();
if (firstEmpty > 0) {
playerInv.setItem(firstEmpty, team.getKind().getBlockHead());
}
if (removed > 1) {
War.war.badMsg(player, "All that " + team.getName() + " wool must have been heavy!");
}
}
}
// check for thieves without their treasure in their hands
if (zone.isFlagThief(player)) {
Team victim = zone.getVictimTeamForFlagThief(player);
player.getInventory().setItemInMainHand(null);
player.getInventory().setItemInOffHand(null);
player.getInventory().setHeldItemSlot(0);
player.getInventory().addItem(new ItemStack(victim.getKind().getMaterial(), 2240));
} else if (zone.isBombThief(player)) {
player.getInventory().setItemInMainHand(null);
player.getInventory().setItemInOffHand(null);
player.getInventory().setHeldItemSlot(0);
player.getInventory().addItem(new ItemStack(Material.TNT, 2240));
} else if (zone.isCakeThief(player)) {
player.getInventory().setItemInMainHand(null);
player.getInventory().setItemInOffHand(null);
player.getInventory().setHeldItemSlot(0);
player.getInventory().addItem(new ItemStack(Material.CAKE, 2240));
}
}
}
}
}
}

View File

@ -0,0 +1,26 @@
package com.tommytony.war.job;
import org.bukkit.entity.Player;
import com.tommytony.war.Warzone;
public class InitZoneJob implements Runnable {
private final Warzone zone;
private final Player respawnExempted;
public InitZoneJob(Warzone zone) {
this.zone = zone;
this.respawnExempted = null;
}
public InitZoneJob(Warzone warzone, Player respawnExempted) {
this.zone = warzone;
this.respawnExempted = respawnExempted;
}
public void run() {
this.zone.initializeZone(this.respawnExempted);
}
}

View File

@ -0,0 +1,28 @@
package com.tommytony.war.job;
import org.bukkit.entity.Player;
import com.tommytony.war.Team;
import com.tommytony.war.Warzone;
public class LoadoutResetJob implements Runnable {
private final Player player;
private final Warzone zone;
private final Team team;
private final boolean isFirstRespawn;
private final boolean isToggle;
public LoadoutResetJob(Warzone zone, Team team, Player player, boolean isFirstRespawn, boolean isToggle) {
this.zone = zone;
this.team = team;
this.player = player;
this.isFirstRespawn = isFirstRespawn;
this.isToggle = isToggle;
}
public void run() {
this.zone.equipPlayerLoadoutSelection(player, team, isFirstRespawn, isToggle);
}
}

View File

@ -0,0 +1,95 @@
package com.tommytony.war.job;
import com.google.common.collect.ImmutableList;
import com.tommytony.war.War;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.logging.Level;
import org.bukkit.OfflinePlayer;
import org.bukkit.scheduler.BukkitRunnable;
/**
* Job to insert kills and deaths information to MySQL database.
*
* @author cmastudios
*/
public class LogKillsDeathsJob extends BukkitRunnable {
private final ImmutableList<KillsDeathsRecord> records;
public LogKillsDeathsJob(final ImmutableList<KillsDeathsRecord> records) {
this.records = records;
}
@Override
/**
* Adds all #records to database at #databaseURL. Will attempt to open a
* connection to the database at #databaseURL. This method is thread safe.
*/
public void run() {
Connection conn = null;
try {
conn = War.war.getMysqlConfig().getConnection();
Statement createStmt = conn.createStatement();
createStmt.executeUpdate("CREATE TABLE IF NOT EXISTS `war_kills` (`date` datetime NOT NULL, `player` varchar(16) NOT NULL, `kills` int(11) NOT NULL, `deaths` int(11) NOT NULL, KEY `date` (`date`)) ENGINE=InnoDB DEFAULT CHARSET=latin1");
createStmt.close();
PreparedStatement stmt = conn.prepareStatement("INSERT INTO war_kills (date, player, kills, deaths) VALUES (NOW(), ?, ?, ?)");
conn.setAutoCommit(false);
for (KillsDeathsRecord kdr : records) {
stmt.setString(1, kdr.getPlayer().getName());
stmt.setInt(2, kdr.getKills());
stmt.setInt(3, kdr.getDeaths());
stmt.addBatch();
}
stmt.executeBatch();
conn.commit();
stmt.close();
final String deleteClause =
War.war.getMysqlConfig().getLoggingDeleteClause();
if (!deleteClause.isEmpty()) {
Statement deleteStmt = conn.createStatement();
deleteStmt.executeUpdate(
"DELETE FROM war_kills " + deleteClause);
deleteStmt.close();
conn.commit();
}
} catch (SQLException ex) {
War.war.getLogger().log(Level.SEVERE,
"Inserting kill-death logs into database", ex);
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException ex) {
}
}
}
}
public static final class KillsDeathsRecord {
private final OfflinePlayer player;
private final int kills;
private final int deaths;
public KillsDeathsRecord(OfflinePlayer player, int kills, int deaths) {
this.player = player;
this.kills = kills;
this.deaths = deaths;
}
public OfflinePlayer getPlayer() {
return player;
}
public int getKills() {
return kills;
}
public int getDeaths() {
return deaths;
}
}
}

View File

@ -0,0 +1,25 @@
package com.tommytony.war.job;
import java.util.List;
import org.bukkit.Location;
import org.bukkit.inventory.ItemStack;
public class LootDropperTask implements Runnable {
private final List<ItemStack> drop;
private final Location location;
public LootDropperTask(Location location, List<ItemStack> drop) {
this.location = location;
this.drop = drop;
}
public void run() {
for (ItemStack item : this.drop) {
if (item != null) {
this.location.getWorld().dropItemNaturally(this.location, item);
}
}
}
}

View File

@ -0,0 +1,171 @@
package com.tommytony.war.job;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.mapper.ZoneVolumeMapper;
import com.tommytony.war.structure.ZoneLobby;
import com.tommytony.war.volume.ZoneVolume;
import org.bukkit.Material;
import org.bukkit.block.BlockState;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.sql.Connection;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.text.NumberFormat;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
public class PartialZoneResetJob extends BukkitRunnable implements Cloneable {
// Watch out, this command sender's map is shared between all concurrent reset jobs on different warzones
// - gotta make sure to notify the correct player that sent the command
private static Map<Warzone, CommandSender> sendersToNotify = Collections.synchronizedMap(new HashMap<Warzone, CommandSender>());
private final Warzone zone;
private final ZoneVolume volume;
private final int speed;
private final int total;
private int completed = 0;
private final long startTime = System.currentTimeMillis();
private long messageCounter = System.currentTimeMillis();
boolean[][][] changes;
public static final long MESSAGE_INTERVAL = 7500;
// Ticks between job runs
public static final int JOB_INTERVAL = 1;
private int totalChanges = 0;
private NumberFormat formatter = new DecimalFormat("#0.00");
private Connection conn;
/**
* Reset a warzone's blocks at a certain speed.
*
* @param zone
* Warzone to reset.
* @param speed
* Blocks to modify per #INTERVAL.
*/
public PartialZoneResetJob(Warzone zone, int speed) throws SQLException {
this.zone = zone;
this.volume = zone.getVolume();
this.speed = speed;
this.total = volume.getTotalSavedBlocks();
this.changes = new boolean[volume.getSizeX()][volume.getSizeY()][volume.getSizeZ()];
}
@Override
public void run() {
try {
if (conn == null || conn.isClosed()) {
conn = ZoneVolumeMapper.getZoneConnection(volume, zone.getName());
}
if (completed >= total) {
int airChanges = 0;
int minX = volume.getMinX(), minY = volume.getMinY(), minZ = volume.getMinZ();
air: for (int x = volume.getMinX(); x <= volume.getMaxX(); x++) {
for (int y = volume.getMinY(); y <= volume.getMaxY(); y++) {
for (int z = volume.getMinZ(); z <= volume.getMaxZ(); z++) {
int xi = x - minX, yi = y - minY, zi = z - minZ;
if (!changes[xi][yi][zi]) {
changes[xi][yi][zi] = true;
airChanges++;
BlockState state = volume.getWorld().getBlockAt(x, y, z).getState();
if (state.getType() != Material.AIR) {
state.setType(Material.AIR);
state.update(true, false);
}
if (airChanges >= speed) {
this.displayStatusMessage();
break air;
}
}
}
}
}
totalChanges += airChanges;
if (this.doneAir()) {
volume.resetEntities(conn);
String secondsAsText = formatter.format(((double)(System.currentTimeMillis() - startTime)) / 1000);
String message = MessageFormat.format(
War.war.getString("zone.battle.resetcomplete"), secondsAsText);
this.sendMessageToAllWarzonePlayers(message);
PartialZoneResetJob.setSenderToNotify(zone, null); // stop notifying for this zone
zone.initializeZone();
War.war.getLogger().log(Level.INFO, "Finished reset cycle for warzone {0} (took {1} seconds)",
new Object[]{volume.getName(), secondsAsText});
conn.close();
} else {
War.war.getServer().getScheduler().runTaskLater(War.war, (Runnable) this.clone(), JOB_INTERVAL);
}
} else {
int solidChanges = volume.resetSection(conn, completed, speed, changes);
completed += solidChanges;
totalChanges += solidChanges;
this.displayStatusMessage();
War.war.getServer().getScheduler().runTaskLater(War.war, (Runnable) this.clone(), JOB_INTERVAL);
}
} catch (SQLException e) {
War.war.getLogger().log(Level.WARNING, "Failed to load zone during reset loop", e);
}
}
private void sendMessageToAllWarzonePlayers(String message) {
for (Player player : War.war.getServer().getOnlinePlayers()) {
ZoneLobby lobby = ZoneLobby.getLobbyByLocation(player);
if (player != PartialZoneResetJob.sendersToNotify.get(zone)
&& (zone.getPlayers().contains(player)
|| (lobby != null && lobby.getZone() == zone))) {
War.war.msg(player, message);
}
}
if (PartialZoneResetJob.sendersToNotify.get(zone) != null) {
War.war.msg(PartialZoneResetJob.sendersToNotify.get(zone), message);
}
}
private void displayStatusMessage() {
if (System.currentTimeMillis() - messageCounter > MESSAGE_INTERVAL) {
String secondsAsText = formatter.format(((double)(System.currentTimeMillis() - startTime)) / 1000);
messageCounter = System.currentTimeMillis();
int percent = (int) (((double) totalChanges / (double) volume.size()) * 100);
String message = MessageFormat.format(
War.war.getString("zone.battle.resetprogress"),
percent, secondsAsText);
this.sendMessageToAllWarzonePlayers(message);
}
}
@Override
protected PartialZoneResetJob clone() {
try {
return (PartialZoneResetJob) super.clone();
} catch (CloneNotSupportedException e) {
throw new Error(e);
}
}
public static void setSenderToNotify(Warzone warzone, CommandSender sender) {
PartialZoneResetJob.sendersToNotify.put(warzone, sender);
}
private boolean doneAir() {
int minX = volume.getMinX(), minY = volume.getMinY(), minZ = volume.getMinZ();
for (int x = volume.getMinX(); x <= volume.getMaxX(); x++) {
for (int y = volume.getMinY(); y <= volume.getMaxY(); y++) {
for (int z = volume.getMinZ(); z <= volume.getMaxZ(); z++) {
int xi = x - minX, yi = y - minY, zi = z - minZ;
if (!changes[xi][yi][zi]) {
return false;
}
}
}
}
return true;
}
}

View File

@ -0,0 +1,75 @@
package com.tommytony.war.job;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.mapper.VolumeMapper;
import com.tommytony.war.structure.WarHub;
import com.tommytony.war.volume.Volume;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection;
import java.sql.SQLException;
import java.util.logging.Level;
public class RestoreYmlWarhubJob implements Runnable {
private final ConfigurationSection warhubConfig;
public RestoreYmlWarhubJob(ConfigurationSection warhubConfig) {
this.warhubConfig = warhubConfig;
}
public void run() {
int hubX = warhubConfig.getInt("x");
int hubY = warhubConfig.getInt("y");
int hubZ = warhubConfig.getInt("z");
String worldName = warhubConfig.getString("world");
String hubOrientation = warhubConfig.getString("orientation");
// materials
if (warhubConfig.isItemStack("materials.floor")) {
War.war.getWarhubMaterials().setFloorBlock(
warhubConfig.getItemStack("materials.floor"));
}
if (warhubConfig.isItemStack("materials.outline")) {
War.war.getWarhubMaterials().setOutlineBlock(
warhubConfig.getItemStack("materials.outline"));
}
if (warhubConfig.isItemStack("materials.gate")) {
War.war.getWarhubMaterials().setGateBlock(
warhubConfig.getItemStack("materials.gate"));
}
if (warhubConfig.isItemStack("materials.light")) {
War.war.getWarhubMaterials().setLightBlock(
warhubConfig.getItemStack("materials.light"));
}
World world = War.war.getServer().getWorld(worldName);
if (world != null) {
Location hubLocation = new Location(world, hubX, hubY, hubZ);
WarHub hub = new WarHub(hubLocation, hubOrientation);
War.war.setWarHub(hub);
Volume vol;
try {
vol = VolumeMapper.loadSimpleVolume("warhub", world);
} catch (SQLException e) {
throw new RuntimeException(e);
}
hub.setVolume(vol);
hub.getVolume().resetBlocks();
hub.initialize();
// In the previous job started by the mapper, warzones were created, but their lobbies are missing the war hub gate (because it didn't exist yet)
for (Warzone zone : War.war.getWarzones()) {
if (zone.getLobby() != null) {
zone.getLobby().getVolume().resetBlocks();
zone.getLobby().initialize();
}
}
War.war.log("Warhub ready.", Level.INFO);
} else {
War.war.log("Failed to restore warhub. The specified world (name: " + worldName + ") does not exist!", Level.WARNING);
}
}
}

View File

@ -0,0 +1,100 @@
package com.tommytony.war.job;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.WarzoneConfig;
import com.tommytony.war.mapper.WarzoneYmlMapper;
import org.bukkit.Bukkit;
import org.mcstats.Metrics;
import org.mcstats.Metrics.Graph;
import java.sql.SQLException;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
public class RestoreYmlWarzonesJob implements Runnable {
private final List<String> warzones;
public RestoreYmlWarzonesJob(List<String> warzones) {
this.warzones = warzones;
}
public void run() {
War.war.getWarzones().clear();
if (this.warzones != null) {
for (String warzoneName : this.warzones) {
if (warzoneName != null && !warzoneName.equals("")) {
War.war.log("Loading zone " + warzoneName + "...", Level.INFO);
Warzone zone = WarzoneYmlMapper.load(warzoneName);
if (zone != null) { // could have failed, would've been logged already
War.war.getWarzones().add(zone);
try {
zone.getVolume().loadCorners();
} catch (SQLException ex) {
War.war.log("Failed to load warzone " + warzoneName + ": " + ex.getMessage(), Level.WARNING);
throw new RuntimeException(ex);
}
if (zone.getLobby() != null) {
zone.getLobby().getVolume().resetBlocks();
}
if (zone.getWarzoneConfig().getBoolean(WarzoneConfig.RESETONLOAD)) {
zone.getVolume().resetBlocks();
}
zone.initializeZone();
}
}
}
if (War.war.getWarzones().size() > 0) {
War.war.log("Warzones ready.", Level.INFO);
final int zones = War.war.getWarzones().size();
try {
Metrics metrics = new Metrics(War.war);
Graph warzoneCount = metrics.createGraph("Warzones");
warzoneCount.addPlotter(new FixedPlotter("Count", zones));
Graph language = metrics.createGraph("Language");
String langName = War.war.getLoadedLocale().getDisplayLanguage(Locale.ENGLISH);
if (langName.isEmpty()) {
langName = "English";
}
language.addPlotter(new PlotterEnabled(langName));
Graph plugins = metrics.createGraph("Extensions");
if (Bukkit.getPluginManager().isPluginEnabled("WorldEdit")) {
plugins.addPlotter(new PlotterEnabled("WorldEdit"));
}
plugins.addPlotter(new PlotterEnabled("War")); // of course
metrics.start();
} catch (Exception ignored) {
}
}
}
}
private static class FixedPlotter extends Metrics.Plotter {
private final int value;
public FixedPlotter(final String name, final int value) {
super(name);
this.value = value;
}
@Override
public int getValue() {
return value;
}
}
private static class PlotterEnabled extends Metrics.Plotter {
public PlotterEnabled(final String name) {
super(name);
}
@Override
public int getValue() {
return 1;
}
}
}

View File

@ -0,0 +1,44 @@
package com.tommytony.war.job;
import com.tommytony.war.War;
import com.tommytony.war.Warzone;
import com.tommytony.war.config.ScoreboardType;
import com.tommytony.war.config.WarzoneConfig;
import org.bukkit.scheduler.BukkitRunnable;
/**
* Switches scoreboards periodically
* Github #790
*/
public class ScoreboardSwitchTimer extends BukkitRunnable {
@Override
public void run() {
if (!War.war.isLoaded()) {
return;
}
for (Warzone zone : War.war.getEnabledWarzones()) {
if (zone.getWarzoneConfig().getScoreboardType(WarzoneConfig.SCOREBOARD) == ScoreboardType.SWITCHING) {
switch (zone.getScoreboardType()) {
case SWITCHING:
zone.setScoreboardType(ScoreboardType.POINTS);
break;
case POINTS:
zone.setScoreboardType(ScoreboardType.LIFEPOOL);
break;
case LIFEPOOL:
zone.setScoreboardType(ScoreboardType.TOPKILLS);
break;
case TOPKILLS:
zone.setScoreboardType(ScoreboardType.PLAYERCOUNT);
break;
case PLAYERCOUNT:
zone.setScoreboardType(ScoreboardType.POINTS);
break;
default:
break;
}
zone.updateScoreboard();
}
}
}
}

View File

@ -0,0 +1,51 @@
package com.tommytony.war.job;
import com.tommytony.war.War;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.scheduler.BukkitRunnable;
public class TeleportPlayerJob extends BukkitRunnable {
private final Player player;
private final Location location;
private final Location originalLocation;
private final double originalHealth;
public TeleportPlayerJob(Player player, Location location) {
this.player = player;
this.location = location;
this.originalLocation = player.getLocation().clone();
this.originalHealth = player.getHealth();
}
@Override
public void run() {
if (!player.isOnline()) {
} else if (hasPlayerMoved()) {
War.war.badMsg(player, "command.tp.moved");
} else if (hasPlayerTakenDamage()) {
War.war.badMsg(player, "command.tp.damaged");
} else {
player.teleport(location, PlayerTeleportEvent.TeleportCause.COMMAND);
War.war.msg(player, "command.tp.success");
}
}
boolean hasPlayerMoved() {
final double MAX_MOVE_TOLERANCE = 1.5;
return distance3D(player.getLocation(), originalLocation) > MAX_MOVE_TOLERANCE;
}
boolean hasPlayerTakenDamage() {
final double MAX_DAMAGE_TOLERANCE = 2;
return Math.abs(originalHealth - player.getHealth()) > MAX_DAMAGE_TOLERANCE;
}
double distance3D(Location pos1, Location pos2) {
double distX = pos2.getX() - pos1.getX();
double distY = pos2.getY() - pos1.getY();
double distZ = pos2.getZ() - pos1.getZ();
return Math.sqrt(Math.pow(distX, 2) + Math.pow(distY, 2) + Math.pow(distZ, 2));
}
}

View File

@ -0,0 +1,22 @@
package com.tommytony.war.job;
import com.tommytony.war.Warzone;
/**
* @author grinning
*/
public class ZoneTimeJob implements Runnable {
private Warzone zone;
public ZoneTimeJob(Warzone zone) {
this.zone = zone;
}
@Override
public void run() {
zone.setPvpReady(true);
}
}

Some files were not shown because too many files have changed in this diff Show More