L2JMobius

C6 Death bomb

ver · 13 · 5804

Offline ver

  • Knight
  • ***
    • Posts: 70
Hello,

There is a NPC skill Death Bomb (4614) which is not working correctly on Interlude.
First of all - in skills XML there is no
Code: [Select]
<set name="isSuicideAttack" val="true" /> part.

After above added to skills XML mob uses it as a suicide (and dies) however:
1. mob uses that skill at the begining of a fight - so when char runs over aggro area (Forge of God) where there are many of mobs like that - some of'em simply explode right away, without even reaching a player - I found in other chronicles that skill suppose have extra conditions like 15 or 30% hp and some success chance
2. when mob explode it does not "transform" to corpse alike - mob simply gets HP = 0, doDie method runs, but mob still looks alive (walking, or standing) - then dissapear after 7 sec.


Best regards


Online Mobius

  • Distinguished King
  • *****
    • Posts: 16153
Try this.
Code: [Select]
Index: dist/game/data/stats/skills/4600-4699.xml
===================================================================
--- dist/game/data/stats/skills/4600-4699.xml (revision 9918)
+++ dist/game/data/stats/skills/4600-4699.xml (working copy)
@@ -296,12 +296,12 @@
  <set name="target" val="ONE" />
  <set name="reuseDelay" val="10000" />
  <set name="hitTime" val="1500" />
- <!-- test -->
  <set name="skillType" val="MDAM" />
  <set name="isMagic" val="true" />
  <set name="operateType" val="ACTIVE" />
  <set name="castRange" val="600" />
  <set name="effectRange" val="1100" />
+ <set name="isSuicideAttack" val="true" />
  </skill>
  <skill id="4615" levels="12" name="Bleed">
  <!-- You suffer a wound that continually reduces HP. Effect 2. -->
Index: java/org/l2jmobius/gameserver/ai/AttackableAI.java
===================================================================
--- java/org/l2jmobius/gameserver/ai/AttackableAI.java (revision 9976)
+++ java/org/l2jmobius/gameserver/ai/AttackableAI.java (working copy)
@@ -871,6 +871,11 @@
  {
  for (Skill sk : skills)
  {
+ if (sk.isSuicideAttack() && (_actor.getCurrentHp() > (_actor.getMaxHp() / 2))) // 50% ?
+ {
+ continue;
+ }
+
  final int castRange = sk.getCastRange();
  boolean inRange = false;
  if ((dist2 >= ((castRange * castRange) / 9.0)) && (dist2 <= (castRange * castRange)) && (castRange > 70))
@@ -962,6 +967,7 @@
  _actor.setTarget(_actor);
  }
  }
+
  // GeoData Los Check here
  if (!useSkillSelf && !GeoEngine.getInstance().canSeeTarget(_actor, _actor.getTarget()))
  {


Offline ver

  • Knight
  • ***
    • Posts: 70
Nope, it is not.
I guess there suppose to be return instead of continue, to stop the function.


I managed to add simmilar checks in org.l2jmobius.gameserver.model.actor.Creature in doCast method.
(my code is kind'a customed a bit, but you'll get the point)

Code: [Select]
if (skill.isSuicideAttack())
{
if (getStatus().getHpRatio() > 0.30 || Rnd.chance(50))   // Fail on 50% cases when hp > 30%
{
getAI().notifyEvent(CtrlEvent.EVT_CANCEL);
return;
}
}

And it does work, however mob stays on his feet after exploding with 0 hp with AI Idle (i guess), and with this part i can't handle


Online Mobius

  • Distinguished King
  • *****
    • Posts: 16153
Iteration should continue to cast other skills.

Try doDie(self instead of null) on skill effect.


Offline ver

  • Knight
  • ***
    • Posts: 70
Quote
Iteration should continue to cast other skills.
Right.
Well... it was bugging me, because your fix suppose to work, so I've tweaked the condition in AttackableAI to this:

Code: [Select]
if (sk.isSuicideAttack())
{
LOGGER.warning("suicide fail HP " + _actor.getStatus().getHpRatio());
if (_actor.getStatus().getHpRatio() > 0.30)
{
continue;
}
if (Rnd.chance(70))
{
LOGGER.warning("suicide fail chance");
continue;
}
}

And guess what - it worked!. Kinda...
Mob used the boom skill 3 times. Two first were "blocked" by HP ratio condition (mobs hp was at around 82%).
And then, he used boom 3rd time (after few sec of being attacked, with no action from player side at all) - and exploded.

I've also left logger at Creature.doCast() and this is how it all looks:

2022.03.21 18:28:43,384 WARNING 29      org.l2jmobius.gameserver.ai.CreatureAI  suicide fail HP 0.8241425389755012
2022.03.21 18:28:43,424 WARNING 24      org.l2jmobius.gameserver.ai.CreatureAI  suicide fail HP 0.8241425389755012
2022.03.21 18:28:55,382 WARNING 29      org.l2jmobius.gameserver.model.actor.Creature    creature.doCast skill : Hold
2022.03.21 18:29:04,072 WARNING 30      org.l2jmobius.gameserver.model.actor.Creature    creature.doCast skill : NPC Death Bomb

I think mobs skills must be handled in yet another place.

BTW skill and conditions - I tried to use conditions in a skill definition (xml). Exactly the same as Frenzy is defined (no more than 30% hp). And it worked just when a player tried to use the skill - condition was not set (or checked?) when skill was used by a NPC.

Quote
Try doDie(self instead of null) on skill effect.
Where? in Mdam skill handler at useSkill method?
If yes - I tried:
Code: [Select]
creature.doDie(creature);
No luck. Mob was still on his feets after death...


Online Mobius

  • Distinguished King
  • *****
    • Posts: 16153
getHpRatio? Rnd.chance?

Try this.
Code: [Select]
Index: dist/game/data/stats/skills/4600-4699.xml
===================================================================
--- dist/game/data/stats/skills/4600-4699.xml (revision 9918)
+++ dist/game/data/stats/skills/4600-4699.xml (working copy)
@@ -296,12 +296,13 @@
  <set name="target" val="ONE" />
  <set name="reuseDelay" val="10000" />
  <set name="hitTime" val="1500" />
- <!-- test -->
  <set name="skillType" val="MDAM" />
  <set name="isMagic" val="true" />
  <set name="operateType" val="ACTIVE" />
  <set name="castRange" val="600" />
  <set name="effectRange" val="1100" />
+ <set name="isSuicideAttack" val="true" />
+ <set name="maxChance" val="30" />
  </skill>
  <skill id="4615" levels="12" name="Bleed">
  <!-- You suffer a wound that continually reduces HP. Effect 2. -->
Index: java/org/l2jmobius/gameserver/ai/AttackableAI.java
===================================================================
--- java/org/l2jmobius/gameserver/ai/AttackableAI.java (revision 9976)
+++ java/org/l2jmobius/gameserver/ai/AttackableAI.java (working copy)
@@ -871,6 +871,11 @@
  {
  for (Skill sk : skills)
  {
+ if (sk.isSuicideAttack() && ((_actor.getCurrentHp() > (_actor.getMaxHp() / 3)) || (sk.getMaxChance() < Rnd.get(100))))
+ {
+ continue;
+ }
+
  final int castRange = sk.getCastRange();
  boolean inRange = false;
  if ((dist2 >= ((castRange * castRange) / 9.0)) && (dist2 <= (castRange * castRange)) && (castRange > 70))
@@ -962,6 +967,7 @@
  _actor.setTarget(_actor);
  }
  }
+
  // GeoData Los Check here
  if (!useSkillSelf && !GeoEngine.getInstance().canSeeTarget(_actor, _actor.getTarget()))
  {
Index: java/org/l2jmobius/gameserver/handler/skillhandlers/Mdam.java
===================================================================
--- java/org/l2jmobius/gameserver/handler/skillhandlers/Mdam.java (revision 9918)
+++ java/org/l2jmobius/gameserver/handler/skillhandlers/Mdam.java (working copy)
@@ -137,8 +137,8 @@
 
  if (skill.isSuicideAttack())
  {
+ creature.setCurrentHp(0);
  creature.doDie(null);
- creature.setCurrentHp(0);
  }
  }
 
Index: java/org/l2jmobius/gameserver/handler/skillhandlers/Pdam.java
===================================================================
--- java/org/l2jmobius/gameserver/handler/skillhandlers/Pdam.java (revision 9918)
+++ java/org/l2jmobius/gameserver/handler/skillhandlers/Pdam.java (working copy)
@@ -353,8 +353,8 @@
 
  if (skill.isSuicideAttack() && !creature.isInvul())
  {
+ creature.setCurrentHp(0);
  creature.doDie(null);
- creature.setCurrentHp(0);
  }
  }
 


Offline ver

  • Knight
  • ***
    • Posts: 70
Quote
getHpRatio? Rnd.chance?
Yea... ignore ;)

Your fix is partially working. Exactly this part:
Code: [Select]
Index: java/org/l2jmobius/gameserver/handler/skillhandlers/Pdam.java
===================================================================
--- java/org/l2jmobius/gameserver/handler/skillhandlers/Pdam.java (revision 9918)
+++ java/org/l2jmobius/gameserver/handler/skillhandlers/Pdam.java (working copy)
@@ -353,8 +353,8 @@
 
  if (skill.isSuicideAttack() && !creature.isInvul())
  {
+ creature.setCurrentHp(0);
  creature.doDie(null);
- creature.setCurrentHp(0);
  }
  }
Mob is dieing and changing into corpse.

However the first part is not workig correctly. I left my debugs in actor.Creature.doCast and added new one. I have used your code to avoid any mistunderstandings... (with suicide doubled condition)
Code: [Select]
for (Skill sk : skills)
{
LOGGER.warning("try to use skill: " + sk.getName());
if (sk.isSuicideAttack())
{
LOGGER.warning("suicide");
if (sk.isSuicideAttack() && ((_actor.getCurrentHp() > (_actor.getMaxHp() / 3)) || (sk.getMaxChance() < Rnd.get(100))))
{
LOGGER.warning("fail");
continue;
}
}

This is a debug right after hitting a mob (mob has over 90% hp):

2022.03.22 15:55:44,558 WARNING 18      org.l2jmobius.gameserver.model.actor.Creature    creature.doCast skill : Hold
2022.03.22 15:55:45,527 WARNING 31      org.l2jmobius.gameserver.ai.CreatureAI  try to use skill: Races
2022.03.22 15:55:45,527 WARNING 31      org.l2jmobius.gameserver.ai.CreatureAI  try to use skill: Strong Type
2022.03.22 15:55:45,527 WARNING 31      org.l2jmobius.gameserver.ai.CreatureAI  try to use skill: Hold
2022.03.22 15:55:45,527 WARNING 31      org.l2jmobius.gameserver.ai.CreatureAI  try to use skill: NPC High Level
2022.03.22 15:55:45,527 WARNING 31      org.l2jmobius.gameserver.ai.CreatureAI  try to use skill: NPC Death Bomb
2022.03.22 15:55:45,527 WARNING 31      org.l2jmobius.gameserver.ai.CreatureAI  suicide
2022.03.22 15:55:45,527 WARNING 31      org.l2jmobius.gameserver.ai.CreatureAI  fail
2022.03.22 15:55:45,528 WARNING 31      org.l2jmobius.gameserver.ai.CreatureAI  try to use skill: P. Def. Modifiers
2022.03.22 15:55:52,527 WARNING 30      org.l2jmobius.gameserver.model.actor.Creature    creature.doCast skill : NPC Death Bomb

After first death bomb use game client started the animation. Mob exploded but did no damage. Condition was true, but why client started the animation?
With second usage (mob still had over 90% hp) - poof, npc used death bomb and exploded. Somehow, I really dont know how but it looks like it was triggered from somewhere else - not via CreatureAI.

Im really confused... Maybe Im doing something wrong?


Online Mobius

  • Distinguished King
  • *****
    • Posts: 16153
sk.getMaxChance() < Rnd.get(100)

->

sk.getMaxChance() > Rnd.get(100)

?


Offline ver

  • Knight
  • ***
    • Posts: 70
Its just a chance thing... 30% or 70% - doesn't really matter for testing.
I believe the problem is elsewhere - mob started the skill and AI didn't catch it at all (so conditions were not triggered).

Take a look at timings from my log:

2022.03.22 15:55:45,527 WARNING 31      org.l2jmobius.gameserver.ai.CreatureAI  try to use skill: NPC Death Bomb
2022.03.22 15:55:45,527 WARNING 31      org.l2jmobius.gameserver.ai.CreatureAI  suicide
2022.03.22 15:55:45,527 WARNING 31      org.l2jmobius.gameserver.ai.CreatureAI  fail
2022.03.22 15:55:45,528 WARNING 31      org.l2jmobius.gameserver.ai.CreatureAI  try to use skill: P. Def. Modifiers
2022.03.22 15:55:52,527 WARNING 30      org.l2jmobius.gameserver.model.actor.Creature    creature.doCast skill : NPC Death Bomb

In first like there is a skill catched by AI (15:55:45) - and worked fine (except the chance sign thing you mentioned in last post), and the last line (it was the last line at all, not just a last line of the log slice I pasted) was at 15:45:52 - 7 sec later. So it was 2nd use of that skill, where mob exploded and died.

I understand you might be frustrated now. I do, really. So, all in all - I wanted to thank you for your support and willing to help - I really appreciate it.


Offline ver

  • Knight
  • ***
    • Posts: 70
Ha! I've found it!

There is another skill loop below...
Code: [Select]

if (!_actor.isMuted() /* && _rnd.nextInt(100) <= 5 */)
{
boolean useSkillSelf = true;
for (Skill sk : skills)
{
 ....

conditions must be repeated there as well - and then it works.
Or moved to Creature.doCast method. Or at least moved into the main skill usage condition, right above
Code: [Select]
clientStopMoving(null);
Allthou I dont like how it works. Mob explodes and then standing for a 1 sec after animation is over. Later it changes into a corpse and drop a loot.
Mob should be changed into corpse instantly when animation starts.. but maybe its just my game client?


Online Mobius

  • Distinguished King
  • *****
    • Posts: 16153

Offline ver

  • Knight
  • ***
    • Posts: 70
Sure, check it out.
I've also added suicide to other skills which missed it.
In AttackableAI I used Rnd.get(99) to count the chance, because maxChance default is 99.

 
Code: [Select]
diff --git a/L2J_Mobius_C6_Interlude/dist/game/data/stats/skills/4600-4699.xml b/L2J_Mobius_C6_Interlude/dist/game/data/stats/skills/4600-4699.xml
index 9db00f21fd..989f14095e 100644
--- a/L2J_Mobius_C6_Interlude/dist/game/data/stats/skills/4600-4699.xml
+++ b/L2J_Mobius_C6_Interlude/dist/game/data/stats/skills/4600-4699.xml
@@ -296,12 +296,13 @@
  <set name="target" val="ONE" />
  <set name="reuseDelay" val="10000" />
  <set name="hitTime" val="1500" />
- <!-- test -->
  <set name="skillType" val="MDAM" />
  <set name="isMagic" val="true" />
  <set name="operateType" val="ACTIVE" />
  <set name="castRange" val="600" />
  <set name="effectRange" val="1100" />
+ <set name="isSuicideAttack" val="true" />
+ <set name="maxChance" val="30" />
  </skill>
  <skill id="4615" levels="12" name="Bleed">
  <!-- You suffer a wound that continually reduces HP. Effect 2. -->
diff --git a/L2J_Mobius_C6_Interlude/dist/game/data/stats/skills/5000-5099.xml b/L2J_Mobius_C6_Interlude/dist/game/data/stats/skills/5000-5099.xml
index a2a342bb0f..a4af9bc2fb 100644
--- a/L2J_Mobius_C6_Interlude/dist/game/data/stats/skills/5000-5099.xml
+++ b/L2J_Mobius_C6_Interlude/dist/game/data/stats/skills/5000-5099.xml
@@ -222,6 +222,7 @@
  <set name="effectRange" val="120" />
  <set name="skillTime" val="2000" />
  <set name="hitTime" val="2000" />
+ <set name="isSuicideAttack" val="true" />
  <set name="isMagic" val="false" />
  </skill>
  <skill id="5012" levels="1" name="Breath of Scarlet">
@@ -1539,6 +1540,7 @@
  <set name="skillRadius" val="250" />
  <set name="target" val="AREA" />
  <set name="skillType" val="MDAM" />
+ <set name="isSuicideAttack" val="true" />
  <set name="operateType" val="ACTIVE" />
  <set name="castRange" val="-1" />
  </skill>
@@ -1574,6 +1576,7 @@
  <set name="skillRadius" val="100" />
  <set name="target" val="AREA" />
  <set name="skillType" val="MDAM" />
+ <set name="isSuicideAttack" val="true" />
  <set name="operateType" val="ACTIVE" />
  <set name="castRange" val="-1" />
  </skill>
diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/ai/AttackableAI.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/ai/AttackableAI.java
index 58c2749587..288cea2bcd 100644
--- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/ai/AttackableAI.java
+++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/ai/AttackableAI.java
@@ -883,6 +883,11 @@ public class AttackableAI extends CreatureAI
 
  if (((sk.getSkillType() == SkillType.BUFF) || (sk.getSkillType() == SkillType.HEAL) || inRange) && !_actor.isSkillDisabled(sk) && (_actor.getCurrentMp() >= _actor.getStat().getMpConsume(sk)) && !sk.isPassive() && (Rnd.get(100) <= 5))
  {
+ if (sk.isSuicideAttack() && ((_actor.getCurrentHp() > (_actor.getMaxHp() / 3)) || (Rnd.get(99) > sk.getMaxChance())))
+ {
+ continue;
+ }
+
  if ((sk.getSkillType() == SkillType.BUFF) || (sk.getSkillType() == SkillType.HEAL))
  {
  if ((sk.getSkillType() == SkillType.HEAL) && (_actor.getCurrentHp() > (int) (_actor.getMaxHp() / 1.5)))
@@ -965,11 +970,17 @@ public class AttackableAI extends CreatureAI
  _actor.setTarget(_actor);
  }
  }
+
  // GeoData Los Check here
  if (!useSkillSelf && !GeoEngine.getInstance().canSeeTarget(_actor, _actor.getTarget()))
  {
  return;
  }
+
+ if (sk.isSuicideAttack() && ((_actor.getCurrentHp() > (_actor.getMaxHp() / 3)) || (Rnd.get(99) > sk.getMaxChance())))
+ {
+ continue;
+ }
 
  final WorldObject oldTarget = _actor.getTarget();
  clientStopMoving(null);
diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/handler/skillhandlers/Mdam.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/handler/skillhandlers/Mdam.java
index 360f294f6e..2a9e7bb8ee 100644
--- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/handler/skillhandlers/Mdam.java
+++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/handler/skillhandlers/Mdam.java
@@ -137,8 +137,8 @@ public class Mdam implements ISkillHandler
 
  if (skill.isSuicideAttack())
  {
- creature.doDie(null);
  creature.setCurrentHp(0);
+ creature.doDie(null);
  }
  }
 
diff --git a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/handler/skillhandlers/Pdam.java b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/handler/skillhandlers/Pdam.java
index 3b7ae272ad..8c3eb3bd45 100644
--- a/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/handler/skillhandlers/Pdam.java
+++ b/L2J_Mobius_C6_Interlude/java/org/l2jmobius/gameserver/handler/skillhandlers/Pdam.java
@@ -351,10 +351,10 @@ public class Pdam implements ISkillHandler
  creature.removeSs();
  }
 
- if (skill.isSuicideAttack() && !creature.isInvul())
+ if (skill.isSuicideAttack())
  {
- creature.doDie(null);
  creature.setCurrentHp(0);
+ creature.doDie(null);
  }
  }
 



Online Mobius

  • Distinguished King
  • *****
    • Posts: 16153
100 is exclusive, Rnd.get(100) returns 0 to 99.
Code: [Select]
/**
* @param bound (int)
* @return a random int value between zero (inclusive) and the specified bound (exclusive).
*/
public static int get(int bound)
{
return bound <= 0 ? 0 : ThreadLocalRandom.current().nextInt(bound);
}

Committed with https://bitbucket.org/MobiusDev/l2j_mobius/commits/675e94ea83f20716946f80a957eed2dd62125566