private boolean doAttackHitByPole(Attack attack) { boolean hitted = false; int charX, charY, charZ, targetX, targetY, targetZ, dx, dy, dz; double angleChar, angleTarget; int maxRadius = 80; int maxAngleDiff = 90; if(getKnownObjects() == null) { _log.warning("ahehe, knownObjects == null in doAttackHitByPole() oO"); return false; } charX = this.getX(); charY = this.getY(); charZ = this.getZ(); // -y (-90 degree) // | // | / Heading (360 - this angle from horizontal line) // | / // | / // o ------------------- +x (0/360 degree) // | \ // | \ // | \ Heading (this angle from horizontal line) // | // +y (90 degree) // // Diff angle is char positive angle subtract target positive angle // =========================================================== // Make sure that char is facing selected target angleTarget = calculateTargetAngelFromChar(charX, charY, getTarget().getX(), getTarget().getY()); this.setHeading((int)((angleTarget / 360.0) * 64399.0)); // Update char's heading degree angleChar = convertHeadingToDegree(this.getHeading()); if (angleChar == 0) angleChar = 360; // =========================================================== for (L2Object obj : getKnownObjects()) { if (obj == null) continue; //Check if the L2Object is a L2Character if(obj instanceof L2Character) { targetX = obj.getX(); targetY = obj.getY(); targetZ = obj.getZ(); dx = Math.abs(charX - targetX); dy = Math.abs(charY - targetY); dz = Math.abs(charZ - targetZ); if (dx*dx + dy*dy + dz*dz > maxRadius*maxRadius) continue; angleTarget = calculateTargetAngelFromChar(charX, charY, obj.getX(), obj.getY()); if (Math.abs(angleChar - angleTarget) > maxAngleDiff) continue; L2Character target = (L2Character) obj; // Launch a simple attack against the L2Character targeted if(!target.isAlikeDead()) { if (target == getAI().getAttackTarget()) hitted |= doAttackHitSimple(attack, target); if(target.isAutoAttackable(this)) { if (target == getAI().getAttackTarget()) continue; hitted |= doAttackHitSimple(attack, target); target.getAI().notifyEvent(CtrlEvent.EVT_ATTACKED, this); } } } } // Return true if one hit isn't missed return hitted; } private double calculateTargetAngelFromChar(int charX, int charY, int targetX, int targetY) { // -y (-90 degree) // | // | / Heading (360 - this angle from horizontal line) // | / // | / // o ------------------- +x (0/360 degree) // | \ // | \ // | \ Heading (this angle from horizontal line) // | // +y (90 degree) // // Diff angle is char positive angle subtract target positive angle int dx, dy; double angleTarget, sine, cosine, distanceXY; dx = Math.abs(charX - targetX); dy = Math.abs(charY - targetY); distanceXY = Math.sqrt(dx*dx + dy*dy); cosine = (targetX - charX) / distanceXY; sine = (targetY - charY) / distanceXY; angleTarget = Math.abs(Math.atan2(sine, cosine)); if (cosine < 0 && sine < 0) angleTarget = 180 + angleTarget; else if (cosine < 0 && sine >= 0) angleTarget = 180 - angleTarget; else if (cosine >= 0 && sine < 0) angleTarget = 360 - angleTarget; if (angleTarget == 0) angleTarget = 360; return angleTarget; } private double convertHeadingToDegree(int heading) { double angle = 360.0 * (this.getHeading() / 64399.0); if (angle == 0) angle = 360; return angle; }