L2JMobius

Secret of Empire Normal attack + skill bug

greg21 · 15 · 4828

Offline greg21

  • Heir
  • **
    • Posts: 10
First you use the attack action and then while you throw the arrow you are going to cast a skill, that skill cancels the normal attack action and it deals almost -50% damage too, the normal thing is to finish the normal attack action first and then it casts the skill. This bug exists on fafurion and classic secret of empire too. The thing that i cant understand it's that on every old chronicle pack that bug doesn't exist and on l2jmobius interlude too but on classic and fafurion it does. Anyway is anybody who knows where is the code for the skill cast? on which file?



Offline greg21

  • Heir
  • **
    • Posts: 10
At least how can i check if the certain second im attacking? Or where can i find the code of the normal attack action?


Online Mobius

  • Distinguished King
  • *****
    • Posts: 16064

Offline greg21

  • Heir
  • **
    • Posts: 10
I thought that it used to work but the mob was under the para command. So when the monster attacks too the character is unable to move or attack. After some more days i found a fix for every weapon and you deal the normal skill damage and not the half of the damage. You can use the skill if you are pushing the f1-f12 button many times, the skill is not on queue when you are trying to use a skill while you are dealing a normal hit, like when you are trying to use a skill when you are already using another one. The skill it has to be on queue if you are trying to cast it when you are dealing a normal hit. And now im trying to find a way to do it. When i went to creature.java and i used the command doCast() i casted the queued skill but i had no damage and now im trying to use the real queue function from the skillcaster but i can't understand this code
 
Code: [Select]

public boolean abortCast()
{
return abortCast(SkillCaster::isAnyNormalType);
}

/**
* Try to break this character's casting using the given filters.
* @param filter
* @return {@code true} if a skill casting has been aborted, {@code false} otherwise.
*/
public boolean abortCast(Predicate<SkillCaster> filter)
{
final SkillCaster skillCaster = getSkillCaster(SkillCaster::canAbortCast, filter);
if (skillCaster != null)
{
skillCaster.stopCasting(true);
if (isPlayer())
{
getActingPlayer().setQueuedSkill(null, null, false, false);
}
return true;
}
return false;
}
so much and im trying to understand it so i can fix the problem. The function stopCasting in SkillCaster.java has the queue code

Also you can't make the stopCasting function public static from just public so you can use it from another file easy because errors are happening when you are using skills.


Offline greg21

  • Heir
  • **
    • Posts: 10
Ok guys after the explosion of my brain i finally found the fix. Now you can't use a skill while you are using the normal hit action, also you deal the normal skill damage after the normal hit action and also the skill is on queue if you push the skill button while you are already attacking by normal hit so you cast it automatically after the attack. Here is the fix

The fix for the normal skill damage is this:

Go to L2J_Mobius_Classic_2.4_SecretOfEmpire\java\org\l2jmobius\gameserver\model\actor\Creature.java

and after the code
Code: [Select]
if (isFakePlayer() && (target.isPlayable() || target.isFakePlayer()))
{
final Npc npc = ((Npc) this);
if (!npc.isScriptValue(1))
{
npc.setScriptValue(1); // in combat
broadcastInfo(); // update flag status
QuestManager.getInstance().getQuest("PvpFlaggingStopTask").notifyEvent("FLAG_CHECK", npc, null);
}
}

put this one

Code: [Select]
// Always try to charge soulshots.
if (!isChargedShot(ShotType.SOULSHOTS) && !isChargedShot(ShotType.BLESSED_SOULSHOTS))
{
rechargeShots(true, false, false);
}

Now the fix for the skill while you are attacking is this

Go to L2J_Mobius_Classic_2.4_SecretOfEmpire\java\org\l2jmobius\gameserver\model\actor\instance\PlayerInstance.java

And after this code

Code: [Select]
if (!doubleCast && isCastingNow(SkillCaster::isAnyNormalType))
{
// Do not queue skill if called by an item.
if (item == null)
{
// Create a new SkillUseHolder object and queue it in the player _queuedSkill
setQueuedSkill(usedSkill, item, forceUse, dontMove);
}
sendPacket(ActionFailed.STATIC_PACKET);
return false;
}

put this

Code: [Select]
if (!doubleCast && isAttackingNow())
{
// Do not queue skill if called by an item.
if (item == null)
{
// Create a new SkillUseHolder object and queue it in the player _queuedSkill
setQueuedSkill(usedSkill, item, forceUse, dontMove);
}
sendPacket(ActionFailed.STATIC_PACKET);
return false;
}

And finally go to the file L2J_Mobius_Classic_2.4_SecretOfEmpire\java\org\l2jmobius\gameserver\ai\PlayerAI.java

Go to this function

Code: [Select]
private void thinkAttack()
{

and make it like that

Code: [Select]
private void thinkAttack()
{
final PlayerInstance currPlayer = _actor.getActingPlayer();
final SkillUseHolder queuedSkill = currPlayer.getQueuedSkill();
final WorldObject target = getTarget();

if ((queuedSkill != null))
{
_actor.abortAttack();
currPlayer.useMagic(queuedSkill.getSkill(), queuedSkill.getItem(), queuedSkill.isCtrlPressed(),
                        queuedSkill.isShiftPressed());
currPlayer.setQueuedSkill(null, null, false, false);
return;
}

if ((target == null) || !target.isCreature())
{
return;
}
if (checkTargetLostOrDead((Creature) target))
{
// Notify the target
setTarget(null);
return;
}
if (maybeMoveToPawn(target, _actor.getPhysicalAttackRange()))
{
return;
}

clientStopMoving(null);
_actor.doAutoAttack((Creature) target);

}

Thats it falks you are welcome.



Online Mobius

  • Distinguished King
  • *****
    • Posts: 16064
Patch.
Code: [Select]
Index: java/org/l2jmobius/gameserver/ai/PlayerAI.java
===================================================================
--- java/org/l2jmobius/gameserver/ai/PlayerAI.java (revision 8817)
+++ java/org/l2jmobius/gameserver/ai/PlayerAI.java (working copy)
@@ -29,6 +29,7 @@
 import org.l2jmobius.gameserver.model.actor.Summon;
 import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
 import org.l2jmobius.gameserver.model.actor.instance.StaticObjectInstance;
+import org.l2jmobius.gameserver.model.holders.SkillUseHolder;
 import org.l2jmobius.gameserver.model.interfaces.ILocational;
 import org.l2jmobius.gameserver.model.skills.Skill;
 import org.l2jmobius.gameserver.model.skills.targets.TargetType;
@@ -260,6 +261,15 @@
 
  private void thinkAttack()
  {
+ final SkillUseHolder queuedSkill = _actor.getActingPlayer().getQueuedSkill();
+ if ((queuedSkill != null))
+ {
+ _actor.abortAttack();
+ _actor.getActingPlayer().useMagic(queuedSkill.getSkill(), queuedSkill.getItem(), queuedSkill.isCtrlPressed(), queuedSkill.isShiftPressed());
+ _actor.getActingPlayer().setQueuedSkill(null, null, false, false);
+ return;
+ }
+
  final WorldObject target = getTarget();
  if ((target == null) || !target.isCreature())
  {
Index: java/org/l2jmobius/gameserver/model/actor/Creature.java
===================================================================
--- java/org/l2jmobius/gameserver/model/actor/Creature.java (revision 8911)
+++ java/org/l2jmobius/gameserver/model/actor/Creature.java (working copy)
@@ -1220,6 +1220,12 @@
  QuestManager.getInstance().getQuest("PvpFlaggingStopTask").notifyEvent("FLAG_CHECK", npc, null);
  }
  }
+
+ // Always try to charge soulshots.
+ if (!isChargedShot(ShotType.SOULSHOTS) && !isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ rechargeShots(true, false, false);
+ }
  }
  finally
  {
Index: java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
===================================================================
--- java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java (revision 8961)
+++ java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java (working copy)
@@ -8420,7 +8420,7 @@
 
  // If a skill is currently being used, queue this one if this is not the same
  // In case of double casting, check if both slots are occupied, then queue skill.
- if ((!doubleCast && isCastingNow(SkillCaster::isAnyNormalType)) || (isCastingNow(s -> s.getCastingType() == SkillCastingType.NORMAL) && isCastingNow(s -> s.getCastingType() == SkillCastingType.NORMAL_SECOND)))
+ if ((!doubleCast && (isAttackingNow() || isCastingNow(SkillCaster::isAnyNormalType))) || (isCastingNow(s -> s.getCastingType() == SkillCastingType.NORMAL) && isCastingNow(s -> s.getCastingType() == SkillCastingType.NORMAL_SECOND)))
  {
  // Do not queue skill if called by an item.
  if (item == null)


Offline greg21

  • Heir
  • **
    • Posts: 10
Nice we are fine now. But there are some problems with the pets too. If you cast a Pet skill and you are trying to use another one the same time the second skill doesn't go on queue you have to click it after end of your first skill, and if you normal attacking and you are trying to cast a skill the skill stops the attack. But also when you cast a skill and after that the Pet is normal attacking the mob by itself if you push the attack action the Pet stops the attack and you have to push the stop and attack to unstuck it. I found the files for the Pet too but i will try to fix it tomorrow.


Online Mobius

  • Distinguished King
  • *****
    • Posts: 16064
Nice we are fine now. But there are some problems with the pets too. If you cast a Pet skill and you are trying to use another one the same time the second skill doesn't go on queue you have to click it after end of your first skill, and if you normal attacking and you are trying to cast a skill the skill stops the attack. But also when you cast a skill and after that the Pet is normal attacking the mob by itself if you push the attack action the Pet stops the attack and you have to push the stop and attack to unstuck it. I found the files for the Pet too but i will try to fix it tomorrow.

That might be fixed.
Try if that happens at l2mobius.net


Offline greg21

  • Heir
  • **
    • Posts: 10
Where is it fixed? On private? cause i don't have access to the private source i use the fremium. I played the high five mobius server and i saw that the bug where the pet used to stuck if you hit attack and you are already auto attacking after the skill it doesn't exist but the skill cancels the normal attack and i think i got stuck when the catherok stunned me and after the stun i couldn't attack, i guess i had to push the stop action.

I don't know what happens on the classic secret of empire or on the other classics or on fafurion private source because you do not have servers for these chronicles but i guess the problem will exist there too


Online Mobius

  • Distinguished King
  • *****
    • Posts: 16064
Is this part really needed?
Shots are already charged within the same method.
Code: [Select]
Index: java/org/l2jmobius/gameserver/model/actor/Creature.java
===================================================================
--- java/org/l2jmobius/gameserver/model/actor/Creature.java (revision 8911)
+++ java/org/l2jmobius/gameserver/model/actor/Creature.java (working copy)
@@ -1220,6 +1220,12 @@
  QuestManager.getInstance().getQuest("PvpFlaggingStopTask").notifyEvent("FLAG_CHECK", npc, null);
  }
  }
+
+ // Always try to charge soulshots.
+ if (!isChargedShot(ShotType.SOULSHOTS) && !isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ rechargeShots(true, false, false);
+ }
  }
  finally
  {


Offline greg21

  • Heir
  • **
    • Posts: 10
Yes because when you attack and then you cast the queued skill that skill after the attack has no shots charged because the doAutoAttack() command which is responsible for the shots it's at the end of thinkattack() function so you don't have charged shots when the code
Code: [Select]
if ((queuedSkill != null))
{
_actor.abortAttack();
currPlayer.useMagic(queuedSkill.getSkill(), queuedSkill.getItem(), queuedSkill.isCtrlPressed(),
                        queuedSkill.isShiftPressed());
currPlayer.setQueuedSkill(null, null, false, false);
return;
}
runs because they used to be charged only at the beginning of the doAutoAttack() function, i saw that before i fixed it when the attack used to get canceled by the skill but the skill had -50% dmg almost. If you want check it just to be sure. Also i fixed the pet problems so now my summon don't get it's normal attack canceled by the skill and the skill is on queue but also after the cast of your skill the summon auto attacks again but it doesn't when you use a skill without normal attacking first, and finally i fixed the bug where  the pet used to get stuck when you were pushing the attack action while you were already attacking. I think on the highfive server the skill used to cancel the attack but you don't have the bug where the pet used to get stuck when you were pushing the attack action while you were already attacking. Also when you were normal attacking with your character and you were trying to cast a skill the same time the attack used to finish instantly. But still i don't know what is going on with fafurion or with the classic chronicles because you have no servers for these chronicles yet and i do not have private source access to check it. Anyway if you want i can share the pet fixes too and you can check them to be sure about them.


Online Mobius

  • Distinguished King
  • *****
    • Posts: 16064

Offline greg21

  • Heir
  • **
    • Posts: 10
Yes i think it's working that way too. But there are 3-4 lines i don't remember, i will create a New function on creature.java and i will use that in the thinkattack function i will use it in doautoattack function too. You are right that this code should be used only when it' s needed, not on every hit. I will test it and i will give you the code.

Update

On the file L2J_Mobius_Classic_2.4_SecretOfEmpire\java\org\l2jmobius\gameserver\model\actor\Creature.java

Under the function private void onAttackFinish(Attack attack)

i placed this one
Code: [Select]
public void soulshotCharge()
{
// Always try to charge soulshots.
if (!isChargedShot(ShotType.SOULSHOTS) && !isChargedShot(ShotType.BLESSED_SOULSHOTS))
{
rechargeShots(true, false, false);
}
}

and i used it on that place in the public void doAutoAttack

Code: [Select]
// Make sure that char is facing selected target
// also works: setHeading(Util.convertDegreeToClientHeading(Util.calculateAngleFrom(this, target)));
setHeading(Util.calculateHeadingFrom(this, target));

soulshotCharge();

i placed it at the same place with the previous code who is in the function now. And remove the soulshot code at the end of the function

Code: [Select]
QuestManager.getInstance().getQuest("PvpFlaggingStopTask").notifyEvent("FLAG_CHECK", npc, null);
}
}
- // Always try to charge soulshots.
- if (!isChargedShot(ShotType.SOULSHOTS) && !isChargedShot(ShotType.BLESSED_SOULSHOTS))
- {
- rechargeShots(true, false, false);
- }

On the file L2J_Mobius_Classic_2.4_SecretOfEmpire\java\org\l2jmobius\gameserver\ai\PlayerAI.java

place that code in the function thinkAttack(), make the if ((queuedSkill != null)) like that and this is it

Code: [Select]
if ((queuedSkill != null))
{
_actor.abortAttack();
currPlayer.soulshotCharge();
currPlayer.useMagic(queuedSkill.getSkill(), queuedSkill.getItem(), queuedSkill.isCtrlPressed(), queuedSkill.isShiftPressed());
currPlayer.setQueuedSkill(null, null, false, false);
return;
}


Online Mobius

  • Distinguished King
  • *****
    • Posts: 16064
Method rechargeShots is used with other parameters as well.
I do not want it to be used as a method.
Might cause future confusion that only that method is used.

Code: [Select]
Index: java/org/l2jmobius/gameserver/ai/PlayerAI.java
===================================================================
--- java/org/l2jmobius/gameserver/ai/PlayerAI.java (revision 9000)
+++ java/org/l2jmobius/gameserver/ai/PlayerAI.java (working copy)
@@ -24,11 +24,13 @@
 import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_PICK_UP;
 import static org.l2jmobius.gameserver.ai.CtrlIntention.AI_INTENTION_REST;
 
+import org.l2jmobius.gameserver.enums.ShotType;
 import org.l2jmobius.gameserver.model.WorldObject;
 import org.l2jmobius.gameserver.model.actor.Creature;
 import org.l2jmobius.gameserver.model.actor.Summon;
 import org.l2jmobius.gameserver.model.actor.instance.PlayerInstance;
 import org.l2jmobius.gameserver.model.actor.instance.StaticObjectInstance;
+import org.l2jmobius.gameserver.model.holders.SkillUseHolder;
 import org.l2jmobius.gameserver.model.interfaces.ILocational;
 import org.l2jmobius.gameserver.model.skills.Skill;
 import org.l2jmobius.gameserver.model.skills.targets.TargetType;
@@ -260,6 +262,24 @@
 
  private void thinkAttack()
  {
+ final SkillUseHolder queuedSkill = _actor.getActingPlayer().getQueuedSkill();
+ if ((queuedSkill != null))
+ {
+ // Abort attack.
+ _actor.abortAttack();
+
+ // Recharge shots.
+ if (!_actor.isChargedShot(ShotType.SOULSHOTS) && !_actor.isChargedShot(ShotType.BLESSED_SOULSHOTS))
+ {
+ _actor.rechargeShots(true, false, false);
+ }
+
+ // Use queued skill.
+ _actor.getActingPlayer().useMagic(queuedSkill.getSkill(), queuedSkill.getItem(), queuedSkill.isCtrlPressed(), queuedSkill.isShiftPressed());
+ _actor.getActingPlayer().setQueuedSkill(null, null, false, false);
+ return;
+ }
+
  final WorldObject target = getTarget();
  if ((target == null) || !target.isCreature())
  {
Index: java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java
===================================================================
--- java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java (revision 9018)
+++ java/org/l2jmobius/gameserver/model/actor/instance/PlayerInstance.java (working copy)
@@ -8627,7 +8627,7 @@
 
  // If a skill is currently being used, queue this one if this is not the same
  // In case of double casting, check if both slots are occupied, then queue skill.
- if ((!doubleCast && isCastingNow(SkillCaster::isAnyNormalType)) || (isCastingNow(s -> s.getCastingType() == SkillCastingType.NORMAL) && isCastingNow(s -> s.getCastingType() == SkillCastingType.NORMAL_SECOND)))
+ if ((!doubleCast && (isAttackingNow() || isCastingNow(SkillCaster::isAnyNormalType))) || (isCastingNow(s -> s.getCastingType() == SkillCastingType.NORMAL) && isCastingNow(s -> s.getCastingType() == SkillCastingType.NORMAL_SECOND)))
  {
  // Do not queue skill if called by an item.
  if (item == null)