--- a/net/minecraft/world/entity/raid/Raids.java
+++ b/net/minecraft/world/entity/raid/Raids.java
@@ -27,6 +27,7 @@
 import net.minecraft.world.phys.Vec3;
 
 public class Raids extends SavedData {
+
     private static final String RAID_FILE_ID = "raids";
     public final Map<Integer, Raid> raidMap = Maps.newHashMap();
     private final ServerLevel level;
@@ -36,8 +37,8 @@
     public static SavedData.Factory<Raids> factory(ServerLevel world) {
         return new SavedData.Factory<>(() -> {
             return new Raids(world);
-        }, (nbt) -> {
-            return load(world, nbt);
+        }, (nbttagcompound) -> {
+            return Raids.load(world, nbttagcompound);
         }, DataFixTypes.SAVED_DATA_RAIDS);
     }
 
@@ -48,15 +49,16 @@
     }
 
     public Raid get(int id) {
-        return this.raidMap.get(id);
+        return (Raid) this.raidMap.get(id);
     }
 
     public void tick() {
         ++this.tick;
-        Iterator<Raid> iterator = this.raidMap.values().iterator();
+        Iterator iterator = this.raidMap.values().iterator();
+
+        while (iterator.hasNext()) {
+            Raid raid = (Raid) iterator.next();
 
-        while(iterator.hasNext()) {
-            Raid raid = iterator.next();
             if (this.level.getGameRules().getBoolean(GameRules.RULE_DISABLE_RAIDS)) {
                 raid.stop();
             }
@@ -77,11 +79,7 @@
     }
 
     public static boolean canJoinRaid(Raider raider, Raid raid) {
-        if (raider != null && raid != null && raid.getLevel() != null) {
-            return raider.isAlive() && raider.canJoinRaid() && raider.getNoActionTime() <= 2400 && raider.level().dimensionType() == raid.getLevel().dimensionType();
-        } else {
-            return false;
-        }
+        return raider != null && raid != null && raid.getLevel() != null ? raider.isAlive() && raider.canJoinRaid() && raider.getNoActionTime() <= 2400 && raider.level().dimensionType() == raid.getLevel().dimensionType() : false;
     }
 
     @Nullable
@@ -91,49 +89,67 @@
         } else if (this.level.getGameRules().getBoolean(GameRules.RULE_DISABLE_RAIDS)) {
             return null;
         } else {
-            DimensionType dimensionType = player.level().dimensionType();
-            if (!dimensionType.hasRaids()) {
+            DimensionType dimensionmanager = player.level().dimensionType();
+
+            if (!dimensionmanager.hasRaids()) {
                 return null;
             } else {
-                BlockPos blockPos = player.blockPosition();
-                List<PoiRecord> list = this.level.getPoiManager().getInRange((poiType) -> {
-                    return poiType.is(PoiTypeTags.VILLAGE);
-                }, blockPos, 64, PoiManager.Occupancy.IS_OCCUPIED).toList();
+                BlockPos blockposition = player.blockPosition();
+                List<PoiRecord> list = this.level.getPoiManager().getInRange((holder) -> {
+                    return holder.is(PoiTypeTags.VILLAGE);
+                }, blockposition, 64, PoiManager.Occupancy.IS_OCCUPIED).toList();
                 int i = 0;
-                Vec3 vec3 = Vec3.ZERO;
+                Vec3 vec3d = Vec3.ZERO;
 
-                for(PoiRecord poiRecord : list) {
-                    BlockPos blockPos2 = poiRecord.getPos();
-                    vec3 = vec3.add((double)blockPos2.getX(), (double)blockPos2.getY(), (double)blockPos2.getZ());
-                    ++i;
+                for (Iterator iterator = list.iterator(); iterator.hasNext(); ++i) {
+                    PoiRecord villageplacerecord = (PoiRecord) iterator.next();
+                    BlockPos blockposition1 = villageplacerecord.getPos();
+
+                    vec3d = vec3d.add((double) blockposition1.getX(), (double) blockposition1.getY(), (double) blockposition1.getZ());
                 }
 
-                BlockPos blockPos3;
+                BlockPos blockposition2;
+
                 if (i > 0) {
-                    vec3 = vec3.scale(1.0D / (double)i);
-                    blockPos3 = BlockPos.containing(vec3);
+                    vec3d = vec3d.scale(1.0D / (double) i);
+                    blockposition2 = BlockPos.containing(vec3d);
                 } else {
-                    blockPos3 = blockPos;
+                    blockposition2 = blockposition;
                 }
 
-                Raid raid = this.getOrCreateRaid(player.serverLevel(), blockPos3);
-                boolean bl = false;
+                Raid raid = this.getOrCreateRaid(player.serverLevel(), blockposition2);
+                boolean flag = false;
+
                 if (!raid.isStarted()) {
+                    /* CraftBukkit - moved down
                     if (!this.raidMap.containsKey(raid.getId())) {
                         this.raidMap.put(raid.getId(), raid);
                     }
+                    */
 
-                    bl = true;
-                } else if (raid.getBadOmenLevel() < raid.getMaxBadOmenLevel()) {
-                    bl = true;
+                    flag = true;
+                    // CraftBukkit start - fixed a bug with raid: players could add up Bad Omen level even when the raid had finished
+                } else if (raid.isInProgress() && raid.getBadOmenLevel() < raid.getMaxBadOmenLevel()) {
+                    flag = true;
+                    // CraftBukkit end
                 } else {
                     player.removeEffect(MobEffects.BAD_OMEN);
-                    player.connection.send(new ClientboundEntityEventPacket(player, (byte)43));
+                    this.level.broadcastEntityEvent(player, net.minecraft.world.entity.EntityEvent.BAD_OMEN_TRIGGERED /* (byte) 43 */); // Paper - Fix MC-253884
                 }
 
-                if (bl) {
+                if (flag) {
+                    // CraftBukkit start
+                    if (!org.bukkit.craftbukkit.v1_20_R2.event.CraftEventFactory.callRaidTriggerEvent(raid, player)) {
+                        player.removeEffect(MobEffects.BAD_OMEN);
+                        return null;
+                    }
+
+                    if (!this.raidMap.containsKey(raid.getId())) {
+                        this.raidMap.put(raid.getId(), raid);
+                    }
+                    // CraftBukkit end
                     raid.absorbBadOmen(player);
-                    player.connection.send(new ClientboundEntityEventPacket(player, (byte)43));
+                    this.level.broadcastEntityEvent(player, net.minecraft.world.entity.EntityEvent.BAD_OMEN_TRIGGERED /* (byte) 43 */); // Paper - Fix MC-253884
                     if (!raid.hasFirstWaveSpawned()) {
                         player.awardStat(Stats.RAID_TRIGGER);
                         CriteriaTriggers.BAD_OMEN.trigger(player);
@@ -148,37 +164,43 @@
 
     private Raid getOrCreateRaid(ServerLevel world, BlockPos pos) {
         Raid raid = world.getRaidAt(pos);
+
         return raid != null ? raid : new Raid(this.getUniqueId(), world, pos);
     }
 
     public static Raids load(ServerLevel world, CompoundTag nbt) {
-        Raids raids = new Raids(world);
-        raids.nextAvailableID = nbt.getInt("NextAvailableID");
-        raids.tick = nbt.getInt("Tick");
-        ListTag listTag = nbt.getList("Raids", 10);
+        Raids persistentraid = new Raids(world);
 
-        for(int i = 0; i < listTag.size(); ++i) {
-            CompoundTag compoundTag = listTag.getCompound(i);
-            Raid raid = new Raid(world, compoundTag);
-            raids.raidMap.put(raid.getId(), raid);
+        persistentraid.nextAvailableID = nbt.getInt("NextAvailableID");
+        persistentraid.tick = nbt.getInt("Tick");
+        ListTag nbttaglist = nbt.getList("Raids", 10);
+
+        for (int i = 0; i < nbttaglist.size(); ++i) {
+            CompoundTag nbttagcompound1 = nbttaglist.getCompound(i);
+            Raid raid = new Raid(world, nbttagcompound1);
+
+            persistentraid.raidMap.put(raid.getId(), raid);
         }
 
-        return raids;
+        return persistentraid;
     }
 
     @Override
     public CompoundTag save(CompoundTag nbt) {
         nbt.putInt("NextAvailableID", this.nextAvailableID);
         nbt.putInt("Tick", this.tick);
-        ListTag listTag = new ListTag();
+        ListTag nbttaglist = new ListTag();
+        Iterator iterator = this.raidMap.values().iterator();
 
-        for(Raid raid : this.raidMap.values()) {
-            CompoundTag compoundTag = new CompoundTag();
-            raid.save(compoundTag);
-            listTag.add(compoundTag);
+        while (iterator.hasNext()) {
+            Raid raid = (Raid) iterator.next();
+            CompoundTag nbttagcompound1 = new CompoundTag();
+
+            raid.save(nbttagcompound1);
+            nbttaglist.add(nbttagcompound1);
         }
 
-        nbt.put("Raids", listTag);
+        nbt.put("Raids", nbttaglist);
         return nbt;
     }
 
@@ -193,13 +215,16 @@
     @Nullable
     public Raid getNearbyRaid(BlockPos pos, int searchDistance) {
         Raid raid = null;
-        double d = (double)searchDistance;
+        double d0 = (double) searchDistance;
+        Iterator iterator = this.raidMap.values().iterator();
 
-        for(Raid raid2 : this.raidMap.values()) {
-            double e = raid2.getCenter().distSqr(pos);
-            if (raid2.isActive() && e < d) {
-                raid = raid2;
-                d = e;
+        while (iterator.hasNext()) {
+            Raid raid1 = (Raid) iterator.next();
+            double d1 = raid1.getCenter().distSqr(pos);
+
+            if (raid1.isActive() && d1 < d0) {
+                raid = raid1;
+                d0 = d1;
             }
         }
 
