Skip to content
Snippets Groups Projects
Commit 0cdaa3b5 authored by Noe Caratini's avatar Noe Caratini
Browse files

fix(dwd): Added correct drops to Dark Water Dragon mobs + small cleanup

parent 43281da7
No related branches found
No related tags found
No related merge requests found
......@@ -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);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment