Merge branch 'master' into monster-tracks-player

This commit is contained in:
OreoKirby 2022-07-29 10:58:50 -04:00 committed by GitHub
commit bad2700bda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 79 additions and 59 deletions

View File

@ -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:

View File

@ -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

View File

@ -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>

View File

@ -295,7 +295,7 @@ public class ArenaClass
case SHULKER_SHELL:
return true;
}
return type.name().endsWith("_SHULKER_BOX");
return type.name().endsWith("SHULKER_BOX");
}
}
}

View File

@ -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);

View File

@ -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();

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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