Merge branch 'master' into monster-tracks-player
This commit is contained in:
commit
bad2700bda
|
@ -1,26 +1,33 @@
|
|||
name: Build MobArena
|
||||
name: build
|
||||
|
||||
on: push
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: 'Checkout source code'
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: 'Set up JDK'
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'adopt'
|
||||
|
||||
- name: 'Cache dependencies'
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.m2
|
||||
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
|
||||
restore-keys: ${{ runner.os }}-m2
|
||||
|
||||
- name: 'Build, test, and package'
|
||||
run: mvn -B package --file pom.xml
|
||||
|
||||
- name: 'Upload artifact'
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
|
|
11
changelog.md
11
changelog.md
|
@ -17,12 +17,14 @@ These changes will (most likely) be included in the next version.
|
|||
- Pet names are now per-class configurable via the optional `pet-name` property, which defaults to `<display-name>'s pet` (the `<player-name>` variable is also supported).
|
||||
- New per-arena setting `auto-leave-on-end` can be used to automatically "kick" spectators when the current session ends.
|
||||
- New per-arena setting `monster-tracks-player` can be used to make monsters always follow a player. If monsters lose their target and can not find a closer one, they will follow their last known target. If their last known target dies or leaves the arena, they will follow a random target.
|
||||
- New per-arena setting `clear-wave-leeway` allows for tweaking the number of mobs allowed to be alive before the next wave spawns. The setting affects `clear-wave-before-next`, `clear-wave-before-boss`, and the final wave check, and it defaults to 0.
|
||||
- New per-arena setting `auto-ignite-fuse` makes the fuse time for auto-ignited TNT configurable. The unit is ticks and defaults to 80.
|
||||
- Added boss abilities `disorient-all`, `fetch-all`, `pull-all`, and `throw-all`. These abilities work like their target-specific and distance-based counterparts, but affect all players in the arena.
|
||||
- (API) MobArena's internal command handler now supports registering pre-instantiated subcommand instances. This should make it easier for extensions to avoid the Singleton anti-pattern for command dependencies.
|
||||
- (API) MobArena now fires MobArenaPreReloadEvent and MobArenaReloadEvent before and after, respectively, reloading its config-file. This should allow extensions and other plugins to better respond to configuration changes.
|
||||
|
||||
### Changed
|
||||
- MobArena now targets the Minecraft 1.17 version of the Spigot API (but still works on 1.13-1.16). This should make it easier to tackle feature requests and bug reports related to modern Minecraft.
|
||||
- MobArena now targets the Minecraft 1.19 version of the Spigot API (but still works on 1.13-1.18). This should make it easier to tackle feature requests and bug reports related to modern Minecraft.
|
||||
- Monsters are no longer stripped of the _weapons_ they spawn with naturally, only their _armor_. This should improve forwards compatibility with new weapon-reliant monsters.
|
||||
- The regex pattern for the player list command is now less greedy, so it will only match on `/ma players`, `/ma playerlist`, and `/ma player-list`. The previous pattern matched on anything that starts with `player`, which rendered the `/ma player-stats` command in MobArenaStats impossible to invoke.
|
||||
|
||||
|
@ -30,11 +32,18 @@ These changes will (most likely) be included in the next version.
|
|||
- Pillagers and vindicators no longer spawn without their much-needed weapons.
|
||||
- Piglins, piglin brutes, and hoglins no longer zombify. This fixes a bug where the mobs would despawn due to the zombification process.
|
||||
- Zombies, husks, drowned, zombie villagers, piglins, hoglins, and zoglins without the `baby` prefix are now forced into adulthood to prevent them from occasionally spawning as babies.
|
||||
- Evokers are once again capable of spawning vexes on 1.18.1+.
|
||||
- Reward groups with `nothing` in them no longer cause errors when earned/granted.
|
||||
- The title-based announcer and the title-based boss health bar have been fixed to work with the breaking change to the Title API in Spigot 1.17.
|
||||
- Arena Signs now correctly update for arenas that don't have `kebab-case` names in the config-file.
|
||||
- Block explosion events cancelled by other plugins now remain cancelled unless MobArena specifically uncancels them for an arena.
|
||||
- Flaming arrows now ignite TNT blocks in the arena.
|
||||
- Players no longer take fall damage when they leave (or get removed from) an arena while falling.
|
||||
- Players no longer take damage from projectiles shot by pets of other players.
|
||||
- Normal shulker boxes are now properly removed from inventories of players using the My Items class.
|
||||
- Class pets are now correctly removed from the arena when their owner dies, rather than when they leave.
|
||||
- MobArena no longer nags players with the `mobarena.admin.teleport` permission when they engage in a teleport that would have otherwise been blocked.
|
||||
- MobArena now correctly sets the source property on auto-ignited TNT.
|
||||
|
||||
## [0.106] - 2021-05-09
|
||||
### Added
|
||||
|
|
4
pom.xml
4
pom.xml
|
@ -89,7 +89,7 @@
|
|||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.17-R0.1-SNAPSHOT</version>
|
||||
<version>1.19-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -97,7 +97,7 @@
|
|||
<dependency>
|
||||
<groupId>com.github.MilkBowl</groupId>
|
||||
<artifactId>VaultAPI</artifactId>
|
||||
<version>1.7</version>
|
||||
<version>1.7.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
|
|
@ -295,7 +295,7 @@ public class ArenaClass
|
|||
case SHULKER_SHELL:
|
||||
return true;
|
||||
}
|
||||
return type.name().endsWith("_SHULKER_BOX");
|
||||
return type.name().endsWith("SHULKER_BOX");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -810,6 +810,9 @@ public class ArenaImpl implements Arena
|
|||
}
|
||||
leavingPlayers.add(p);
|
||||
|
||||
// Remove pets.
|
||||
monsterManager.removePets(p);
|
||||
|
||||
// Clear inventory if player is an arena player, and unmount
|
||||
if (arenaPlayers.contains(p)) {
|
||||
unmount(p);
|
||||
|
@ -866,6 +869,9 @@ public class ArenaImpl implements Arena
|
|||
ArenaPlayerDeathEvent event = new ArenaPlayerDeathEvent(p, this, last);
|
||||
plugin.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
// Remove pets.
|
||||
monsterManager.removePets(p);
|
||||
|
||||
// Clear the player's inventory, and unmount
|
||||
if (arenaPlayers.remove(p)) {
|
||||
unmount(p);
|
||||
|
@ -1131,9 +1137,6 @@ public class ArenaImpl implements Arena
|
|||
}
|
||||
});
|
||||
|
||||
// Remove pets.
|
||||
monsterManager.removePets(p);
|
||||
|
||||
// readyPlayers before lobbyPlayers because of startArena sanity-checks
|
||||
readyPlayers.remove(p);
|
||||
specPlayers.remove(p);
|
||||
|
|
|
@ -91,9 +91,6 @@ import org.bukkit.material.Attachable;
|
|||
import org.bukkit.material.Bed;
|
||||
import org.bukkit.material.Door;
|
||||
import org.bukkit.material.Redstone;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.metadata.MetadataValue;
|
||||
import org.bukkit.metadata.Metadatable;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.projectiles.ProjectileSource;
|
||||
|
@ -128,6 +125,7 @@ public class ArenaListener
|
|||
private boolean allowTeleport,
|
||||
canShare,
|
||||
autoIgniteTNT;
|
||||
private int autoIgniteFuse;
|
||||
|
||||
private Set<Player> banned;
|
||||
|
||||
|
@ -154,6 +152,7 @@ public class ArenaListener
|
|||
this.allowTeleport = s.getBoolean("allow-teleporting", false);
|
||||
this.canShare = s.getBoolean("share-items-in-arena", true);
|
||||
this.autoIgniteTNT = s.getBoolean("auto-ignite-tnt", false);
|
||||
this.autoIgniteFuse = s.getInt("auto-ignite-fuse", 80);
|
||||
this.useClassChests = s.getBoolean("use-class-chests", false);
|
||||
|
||||
this.classLimits = arena.getClassLimitManager();
|
||||
|
@ -293,10 +292,10 @@ public class ArenaListener
|
|||
}
|
||||
stack.setAmount(stack.getAmount() - 1);
|
||||
TNTPrimed tnt = b.getWorld().spawn(b.getRelative(BlockFace.UP).getLocation(), TNTPrimed.class);
|
||||
setPlanter(tnt, event.getPlayer());
|
||||
tnt.setSource(event.getPlayer());
|
||||
tnt.setFuseTicks(Math.max(0, autoIgniteFuse));
|
||||
return;
|
||||
}
|
||||
setPlanter(b, event.getPlayer());
|
||||
}
|
||||
|
||||
// Any other block we don't care about if we're not protecting
|
||||
|
@ -313,20 +312,6 @@ public class ArenaListener
|
|||
}
|
||||
}
|
||||
|
||||
private void setPlanter(Metadatable tnt, Player planter) {
|
||||
tnt.setMetadata("mobarena-planter", new FixedMetadataValue(plugin, planter));
|
||||
}
|
||||
|
||||
private Player getPlanter(Metadatable tnt) {
|
||||
List<MetadataValue> values = tnt.getMetadata("mobarena-planter");
|
||||
for (MetadataValue value : values) {
|
||||
if (value.getOwningPlugin().equals(plugin)) {
|
||||
return (Player) value.value();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void onBlockForm(BlockFormEvent event) {
|
||||
// If the arena isn't protected, care
|
||||
if (!protect) return;
|
||||
|
@ -366,16 +351,7 @@ public class ArenaListener
|
|||
case FLINT_AND_STEEL:
|
||||
if (arena.inEditMode()) return;
|
||||
if (arena.isRunning()) {
|
||||
if (b.getType() == Material.TNT) {
|
||||
Player planter = getPlanter(b);
|
||||
if (planter != null) {
|
||||
b.setType(Material.AIR);
|
||||
TNTPrimed tnt = b.getWorld().spawn(b.getLocation(), TNTPrimed.class);
|
||||
setPlanter(tnt, planter);
|
||||
}
|
||||
} else {
|
||||
arena.addBlock(event.getBlock().getRelative(BlockFace.UP));
|
||||
}
|
||||
arena.addBlock(b.getRelative(BlockFace.UP));
|
||||
break;
|
||||
}
|
||||
case LIGHTNING:
|
||||
|
@ -424,15 +400,23 @@ public class ArenaListener
|
|||
* reason means MobArena didn't trigger the event. However, we
|
||||
* make an exception for certain mobs that spawn as results of
|
||||
* other entities spawning them, e.g. when Evokers summon Vexes.
|
||||
* Note that the "spell" reason was introduced somewhere between
|
||||
* 1.18 and 1.18.1, so "default" is kept only for compatibility
|
||||
* with older server versions. Also note the use of `switch` as
|
||||
* a workaround for the NoSuchFieldError that would occur if we
|
||||
* used a simple equality check.
|
||||
*/
|
||||
if (reason == SpawnReason.DEFAULT) {
|
||||
if (event.getEntityType() == EntityType.VEX) {
|
||||
event.setCancelled(false);
|
||||
monsters.addMonster(event.getEntity());
|
||||
} else {
|
||||
event.setCancelled(true);
|
||||
switch (reason) {
|
||||
case DEFAULT:
|
||||
case SPELL: {
|
||||
if (event.getEntityType() == EntityType.VEX) {
|
||||
event.setCancelled(false);
|
||||
monsters.addMonster(event.getEntity());
|
||||
} else {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If not custom, we probably don't want it, so get rid of it
|
||||
|
@ -687,7 +671,7 @@ public class ArenaListener
|
|||
}
|
||||
|
||||
if (damager instanceof TNTPrimed) {
|
||||
damager = getPlanter(damager);
|
||||
damager = ((TNTPrimed) damager).getSource();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -738,6 +722,12 @@ public class ArenaListener
|
|||
}
|
||||
|
||||
if (arena.inArena(player)) {
|
||||
// Cancel damage from pets (and their projectiles)
|
||||
if (monsters.hasPet(damager)) {
|
||||
event.setCancelled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Cancel PvP damage if disabled
|
||||
if (!pvpEnabled && damager instanceof Player && !damager.equals(player)) {
|
||||
event.setCancelled(true);
|
||||
|
@ -1307,23 +1297,20 @@ public class ArenaListener
|
|||
if (region.contains(to)) {
|
||||
// Inside -> inside
|
||||
if (!(arena.inArena(p) || arena.inLobby(p))) {
|
||||
arena.getMessenger().tell(p, Msg.WARP_TO_ARENA);
|
||||
return TeleportResponse.REJECT;
|
||||
return reject(p, Msg.WARP_TO_ARENA);
|
||||
}
|
||||
return TeleportResponse.ALLOW;
|
||||
} else {
|
||||
// Inside -> outside
|
||||
if (arena.getAllPlayers().contains(p)) {
|
||||
arena.getMessenger().tell(p, Msg.WARP_FROM_ARENA);
|
||||
return TeleportResponse.REJECT;
|
||||
return reject(p, Msg.WARP_FROM_ARENA);
|
||||
}
|
||||
return TeleportResponse.IDGAF;
|
||||
}
|
||||
} else {
|
||||
if (region.contains(to)) {
|
||||
// Outside -> inside
|
||||
arena.getMessenger().tell(p, Msg.WARP_TO_ARENA);
|
||||
return TeleportResponse.REJECT;
|
||||
return reject(p, Msg.WARP_TO_ARENA);
|
||||
} else {
|
||||
// Outside -> outside
|
||||
return TeleportResponse.IDGAF;
|
||||
|
@ -1331,6 +1318,15 @@ public class ArenaListener
|
|||
}
|
||||
}
|
||||
|
||||
private TeleportResponse reject(Player p, Msg message) {
|
||||
if (p.hasPermission("mobarena.admin.teleport")) {
|
||||
return TeleportResponse.IDGAF;
|
||||
}
|
||||
|
||||
arena.getMessenger().tell(p, message);
|
||||
return TeleportResponse.REJECT;
|
||||
}
|
||||
|
||||
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
|
||||
Player p = event.getPlayer();
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ public class MASpawnThread implements Runnable
|
|||
|
||||
private int playerCount, monsterLimit;
|
||||
private boolean waveClear, bossClear, preBossClear, wavesAsLevel;
|
||||
private int clearLeeway;
|
||||
private int waveInterval;
|
||||
private int nextWaveDelay;
|
||||
|
||||
|
@ -76,6 +77,7 @@ public class MASpawnThread implements Runnable
|
|||
waveClear = arena.getSettings().getBoolean("clear-wave-before-next", false);
|
||||
bossClear = arena.getSettings().getBoolean("clear-boss-before-next", false);
|
||||
preBossClear = arena.getSettings().getBoolean("clear-wave-before-boss", false);
|
||||
clearLeeway = arena.getSettings().getInt("clear-wave-leeway", 0);
|
||||
wavesAsLevel = arena.getSettings().getBoolean("display-waves-as-level", false);
|
||||
waveInterval = arena.getSettings().getInt("wave-interval", 3);
|
||||
nextWaveDelay = arena.getSettings().getInt("next-wave-delay", 0);
|
||||
|
@ -308,18 +310,18 @@ public class MASpawnThread implements Runnable
|
|||
return false;
|
||||
}
|
||||
|
||||
// Check for wave and pre boss clear
|
||||
if (waveClear && !monsterManager.getMonsters().isEmpty()) {
|
||||
// Check for wave clear
|
||||
if (waveClear && monsterManager.getMonsters().size() > clearLeeway) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for pre boss clear
|
||||
if (preBossClear && waveManager.getNext().getType() == WaveType.BOSS && !monsterManager.getMonsters().isEmpty()) {
|
||||
if (preBossClear && waveManager.getNext().getType() == WaveType.BOSS && monsterManager.getMonsters().size() > clearLeeway) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for final wave
|
||||
if (!monsterManager.getMonsters().isEmpty() && waveManager.getWaveNumber() == waveManager.getFinalWave()) {
|
||||
if (monsterManager.getMonsters().size() > clearLeeway && waveManager.getWaveNumber() == waveManager.getFinalWave()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -369,10 +369,9 @@ public class MAGlobalListener implements Listener
|
|||
/*
|
||||
* If we reach this point, no arena has specifically allowed the
|
||||
* teleport, but one or more arenas may have rejected it, so we
|
||||
* may have to cancel the event. If the player has the teleport
|
||||
* override permission, however, we don't cancel.
|
||||
* may have to cancel the event.
|
||||
*/
|
||||
if (!allow && !event.getPlayer().hasPermission("mobarena.admin.teleport")) {
|
||||
if (!allow) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,13 @@ abstract class MovePlayerStep extends PlayerStep {
|
|||
public void run() {
|
||||
location = player.getLocation();
|
||||
|
||||
player.setFallDistance(0);
|
||||
player.teleport(destination.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void undo() {
|
||||
player.setFallDistance(0);
|
||||
player.teleport(location);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ default-class: ''
|
|||
clear-wave-before-next: false
|
||||
clear-boss-before-next: false
|
||||
clear-wave-before-boss: false
|
||||
clear-wave-leeway: 0
|
||||
soft-restore: false
|
||||
soft-restore-drops: false
|
||||
require-empty-inv-join: false
|
||||
|
@ -33,6 +34,7 @@ food-regen: false
|
|||
lock-food-level: true
|
||||
player-time-in-arena: world
|
||||
auto-ignite-tnt: false
|
||||
auto-ignite-fuse: 80
|
||||
auto-start-timer: 0
|
||||
start-delay-timer: 0
|
||||
auto-ready: false
|
||||
|
|
Loading…
Reference in New Issue