From 0cdaa3b517aed2165f9aaebd0b0294a6556154fa Mon Sep 17 00:00:00 2001 From: Noe Caratini <caratinin@gmail.com> Date: Tue, 7 Jun 2022 13:01:41 +0100 Subject: [PATCH] fix(dwd): Added correct drops to Dark Water Dragon mobs + small cleanup --- .../ai/individual/DarkWaterDragon.java | 120 ++++++++++-------- 1 file changed, 69 insertions(+), 51 deletions(-) diff --git a/src/main/java/com/l2jserver/datapack/ai/individual/DarkWaterDragon.java b/src/main/java/com/l2jserver/datapack/ai/individual/DarkWaterDragon.java index e56725db8b..24a6e43c48 100644 --- a/src/main/java/com/l2jserver/datapack/ai/individual/DarkWaterDragon.java +++ b/src/main/java/com/l2jserver/datapack/ai/individual/DarkWaterDragon.java @@ -18,18 +18,20 @@ */ package com.l2jserver.datapack.ai.individual; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - +import com.l2jserver.commons.util.Rnd; import com.l2jserver.datapack.ai.npc.AbstractNpcAI; import com.l2jserver.gameserver.ai.CtrlIntention; -import com.l2jserver.gameserver.data.xml.impl.NpcData; import com.l2jserver.gameserver.model.actor.L2Attackable; import com.l2jserver.gameserver.model.actor.L2Character; import com.l2jserver.gameserver.model.actor.L2Npc; import com.l2jserver.gameserver.model.actor.instance.L2PcInstance; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import static com.l2jserver.gameserver.config.Configuration.rates; + /** * Dark Water Dragon's AI. */ @@ -41,8 +43,14 @@ public final class DarkWaterDragon extends AbstractNpcAI { private static final int DETRACTOR1 = 22270; private static final int DETRACTOR2 = 22271; private static final Set<Integer> SECOND_SPAWN = ConcurrentHashMap.newKeySet(); // Used to track if second Shades were already spawned - private static Set<Integer> MY_TRACKING_SET = ConcurrentHashMap.newKeySet(); // Used to track instances of npcs - private static Map<Integer, L2PcInstance> ID_MAP = new ConcurrentHashMap<>(); // Used to track instances of npcs + // Items + private static final int BLUE_SEED_OF_EVIL = 9595; + private static final int RED_SEED_OF_EVIL = 9596; + private static final int WATER_DRAGON_SCALE = 9691; + private static final int WATER_DRAGON_CLAW = 9700; + private static final int SPIRIT_OF_THE_LAKE = 9689; + private static final Set<Integer> MY_TRACKING_SET = ConcurrentHashMap.newKeySet(); // Used to track instances of npcs + private static final Map<Integer, L2PcInstance> ID_MAP = new ConcurrentHashMap<>(); // Used to track instances of npcs public DarkWaterDragon() { super(DarkWaterDragon.class.getSimpleName(), "ai/individual"); @@ -64,32 +72,23 @@ public final class DarkWaterDragon extends AbstractNpcAI { @Override public String onAdvEvent(String event, L2Npc npc, L2PcInstance player) { if (npc != null) { - if (event.equalsIgnoreCase("first_spawn")) // timer to start timer "1" - { + if (event.equalsIgnoreCase("first_spawn")) { // timer to start timer "1" startQuestTimer("1", 40000, npc, null, true); // spawns detractor every 40 seconds - } else if (event.equalsIgnoreCase("second_spawn")) // timer to start timer "2" - { + } else if (event.equalsIgnoreCase("second_spawn")) { // timer to start timer "2" startQuestTimer("2", 40000, npc, null, true); // spawns detractor every 40 seconds - } else if (event.equalsIgnoreCase("third_spawn")) // timer to start timer "3" - { + } else if (event.equalsIgnoreCase("third_spawn")) { // timer to start timer "3" startQuestTimer("3", 40000, npc, null, true); // spawns detractor every 40 seconds - } else if (event.equalsIgnoreCase("fourth_spawn")) // timer to start timer "4" - { + } else if (event.equalsIgnoreCase("fourth_spawn")) { // timer to start timer "4" startQuestTimer("4", 40000, npc, null, true); // spawns detractor every 40 seconds - } else if (event.equalsIgnoreCase("1")) // spawns a detractor - { + } else if (event.equalsIgnoreCase("1")) { // spawns a detractor addSpawn(DETRACTOR1, (npc.getX() + 100), (npc.getY() + 100), npc.getZ(), 0, false, 40000); - } else if (event.equalsIgnoreCase("2")) // spawns a detractor - { + } else if (event.equalsIgnoreCase("2")) { // spawns a detractor addSpawn(DETRACTOR2, (npc.getX() + 100), (npc.getY() - 100), npc.getZ(), 0, false, 40000); - } else if (event.equalsIgnoreCase("3")) // spawns a detractor - { + } else if (event.equalsIgnoreCase("3")) { // spawns a detractor addSpawn(DETRACTOR1, (npc.getX() - 100), (npc.getY() + 100), npc.getZ(), 0, false, 40000); - } else if (event.equalsIgnoreCase("4")) // spawns a detractor - { + } else if (event.equalsIgnoreCase("4")) { // spawns a detractor addSpawn(DETRACTOR2, (npc.getX() - 100), (npc.getY() - 100), npc.getZ(), 0, false, 40000); - } else if (event.equalsIgnoreCase("fafurion_despawn")) // Fafurion Kindred disappears and drops reward - { + } else if (event.equalsIgnoreCase("fafurion_despawn")) { // Fafurion Kindred disappears and drops reward cancelQuestTimer("fafurion_poison", npc, null); cancelQuestTimer("1", npc, null); cancelQuestTimer("2", npc, null); @@ -99,12 +98,12 @@ public final class DarkWaterDragon extends AbstractNpcAI { MY_TRACKING_SET.remove(npc.getObjectId()); player = ID_MAP.remove(npc.getObjectId()); if (player != null) { - ((L2Attackable) npc).doItemDrop(NpcData.getInstance().getTemplate(18485), player); + calculateDrop(npc, player, WATER_DRAGON_SCALE, 100.0); + calculateDrop(npc, player, WATER_DRAGON_CLAW, 33.0); } npc.deleteMe(); - } else if (event.equalsIgnoreCase("fafurion_poison")) // Reduces Fafurions hp like it is poisoned - { + } else if (event.equalsIgnoreCase("fafurion_poison")) { // Reduces Fafurions hp like it is poisoned if (npc.getCurrentHp() <= 500) { cancelQuestTimer("fafurion_despawn", npc, null); cancelQuestTimer("first_spawn", npc, null); @@ -129,11 +128,10 @@ public final class DarkWaterDragon extends AbstractNpcAI { int npcId = npc.getId(); int npcObjId = npc.getObjectId(); if (npcId == DRAGON) { - if (!MY_TRACKING_SET.contains(npcObjId)) // this allows to handle multiple instances of npc - { + final L2Character originalAttacker = isSummon ? attacker.getSummon() : attacker; + if (!MY_TRACKING_SET.contains(npcObjId)) { // this allows to handle multiple instances of npc MY_TRACKING_SET.add(npcObjId); // Spawn first 5 shades on first attack on Dark Water Dragon - L2Character originalAttacker = isSummon ? attacker.getSummon() : attacker; spawnShade(originalAttacker, SHADE1, npc.getX() + 100, npc.getY() + 100, npc.getZ()); spawnShade(originalAttacker, SHADE2, npc.getX() + 100, npc.getY() - 100, npc.getZ()); spawnShade(originalAttacker, SHADE1, npc.getX() - 100, npc.getY() + 100, npc.getZ()); @@ -142,7 +140,6 @@ public final class DarkWaterDragon extends AbstractNpcAI { } else if ((npc.getCurrentHp() < (npc.getMaxHp() / 2.0)) && !(SECOND_SPAWN.contains(npcObjId))) { SECOND_SPAWN.add(npcObjId); // Spawn second 5 shades on half hp of on Dark Water Dragon - L2Character originalAttacker = isSummon ? attacker.getSummon() : attacker; spawnShade(originalAttacker, SHADE2, npc.getX() + 100, npc.getY() + 100, npc.getZ()); spawnShade(originalAttacker, SHADE1, npc.getX() + 100, npc.getY() - 100, npc.getZ()); spawnShade(originalAttacker, SHADE2, npc.getX() - 100, npc.getY() + 100, npc.getZ()); @@ -157,28 +154,49 @@ public final class DarkWaterDragon extends AbstractNpcAI { public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon) { int npcId = npc.getId(); int npcObjId = npc.getObjectId(); - if (npcId == DRAGON) { - MY_TRACKING_SET.remove(npcObjId); - SECOND_SPAWN.remove(npcObjId); - L2Attackable faf = (L2Attackable) addSpawn(FAFURION, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0); // spawns Fafurion Kindred when Dard Water Dragon is dead - ID_MAP.put(faf.getObjectId(), killer); - } else if (npcId == FAFURION) { - cancelQuestTimer("fafurion_poison", npc, null); - cancelQuestTimer("fafurion_despawn", npc, null); - cancelQuestTimer("first_spawn", npc, null); - cancelQuestTimer("second_spawn", npc, null); - cancelQuestTimer("third_spawn", npc, null); - cancelQuestTimer("fourth_spawn", npc, null); - cancelQuestTimer("1", npc, null); - cancelQuestTimer("2", npc, null); - cancelQuestTimer("3", npc, null); - cancelQuestTimer("4", npc, null); - MY_TRACKING_SET.remove(npcObjId); - ID_MAP.remove(npcObjId); + switch (npcId) { + case DRAGON -> { + MY_TRACKING_SET.remove(npcObjId); + SECOND_SPAWN.remove(npcObjId); + L2Attackable faf = (L2Attackable) addSpawn(FAFURION, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0); // spawns Fafurion Kindred when Dard Water Dragon is dead + ID_MAP.put(faf.getObjectId(), killer); + calculateDrop(npc, killer, RED_SEED_OF_EVIL, 77.0); + } + case FAFURION -> { + cancelQuestTimer("fafurion_poison", npc, null); + cancelQuestTimer("fafurion_despawn", npc, null); + cancelQuestTimer("first_spawn", npc, null); + cancelQuestTimer("second_spawn", npc, null); + cancelQuestTimer("third_spawn", npc, null); + cancelQuestTimer("fourth_spawn", npc, null); + cancelQuestTimer("1", npc, null); + cancelQuestTimer("2", npc, null); + cancelQuestTimer("3", npc, null); + cancelQuestTimer("4", npc, null); + MY_TRACKING_SET.remove(npcObjId); + ID_MAP.remove(npcObjId); + } + case SHADE1 -> calculateDrop(npc, killer, BLUE_SEED_OF_EVIL, 9.87); + case SHADE2 -> calculateDrop(npc, killer, BLUE_SEED_OF_EVIL, 9.95); + case DETRACTOR1, DETRACTOR2 -> { + calculateDrop(npc, killer, SPIRIT_OF_THE_LAKE, 100.0); + calculateDrop(npc, killer, BLUE_SEED_OF_EVIL, 10.08); + } } return super.onKill(npc, killer, isSummon); } + private void calculateDrop(final L2Npc npc, final L2PcInstance killer, final int itemId, final double dropRate) { + final int finalRate = (int) ((dropRate * 100) * rates().getDeathDropChanceMultiplier()); + if (Rnd.get(10000) <= finalRate) { + int finalAmount = rates().getDeathDropAmountMultiplier().intValue(); + if (finalRate > 10000) { + finalAmount *= finalRate / 10000 + (Rnd.get(10000) <= finalRate % 10000 ? 1 : 0); + } + npc.dropItem(killer, itemId, finalAmount); + } + } + @Override public String onSpawn(L2Npc npc) { int npcId = npc.getId(); @@ -204,7 +222,7 @@ public final class DarkWaterDragon extends AbstractNpcAI { return super.onSpawn(npc); } - public void spawnShade(L2Character attacker, int npcId, int x, int y, int z) { + private void spawnShade(L2Character attacker, int npcId, int x, int y, int z) { final L2Npc shade = addSpawn(npcId, x, y, z, 0, false, 0); shade.setRunning(); ((L2Attackable) shade).addDamageHate(attacker, 0, 999); -- GitLab