/** * Look for Zildo around him, only if the character is "alertable". * * @return TRUE = Zildo is around the character / FALSE = not in the field of view */ boolean lookForZildo(Angle p_angle) { if (!quel_deplacement.isAlertable()) { return false; } PersoZildo zildo = EngineZildo.persoManagement.getZildo(); if (zildo == null || !zildo.isAlive()) { // Maybe he's dead ? return false; } int dix, diy; boolean temp, r; final int DISTANCEMAX = 16 * 6; r = false; // On calcule la distance en x et en y entre le perso et Zildo dix = (int) (x - zildo.x); diy = (int) (y - zildo.y); temp = (Math.abs(dix) > Math.abs(diy)); if (p_angle.isHorizontal() == temp) { switch (p_angle) { case NORD: if (diy > 0 && diy < DISTANCEMAX) { r = true; } break; case EST: if (dix > 0 && dix < DISTANCEMAX) { r = true; } break; case SUD: if (diy < 0 && diy > -DISTANCEMAX) { r = true; } break; case OUEST: if (dix < 0 && dix > -DISTANCEMAX) { r = true; } break; } } return r; }
/** * Move method for PNJ. Classes deriving from this one should override this method for specific * moves. Note that common one like projection, or target reaching and so on, are handled by * {@link #animate(int)} method. */ public void move() { if (pv <= 0) { return; } PersoZildo zildo = EngineZildo.persoManagement.getZildo(); float sx = getX(), sy = getY(); if (isAlerte() && MouvementPerso.VOLESPECTRE != quel_deplacement && MouvementPerso.ZONEARC != quel_deplacement) { // Zildo has been caught, so the monster try to reach him, or run away (hen) boolean fear = quel_deplacement.isAfraid(); reachAvoidTarget(zildo, fear); walkTile(true); } else { // Common moves if (zildo != null) { switch (quel_deplacement) { case VOLESPECTRE: double beta; if (cptMouvement == 100) { if (desc == PersoDescription.CORBEAU) { // Black bird : focus moving zone on Zildo int pasx, pasy; if ((int) zildo.x / 16 > x / 16) { pasx = 16; } else { pasx = -16; } if ((int) zildo.y / 16 > y / 16) { pasy = 16; } else { pasy = -16; } zone_deplacement.incX1(pasx * 3); zone_deplacement.incY1(pasy * 3); zone_deplacement.incX2(pasx * 3); zone_deplacement.incY2(pasy * 3); } attente = 1 + (int) Math.random() * 5; if (pathFinder.getTarget() == null || desc == PersoDescription.CORBEAU) { pathFinder.determineDestination(); } cptMouvement = 0; } else if (attente != 0) { attente--; } else { if (desc == PersoDescription.CORBEAU) { if (pos_seqsprite != 0) { pos_seqsprite = (4 * Constantes.speed) + (pos_seqsprite - 4 * Constantes.speed + 1) % (8 * Constantes.speed); } else { // Est-ce que Zildo est dans les parages ?} beta = x - zildo.x; float vitesse = y - zildo.y; beta = Math.sqrt(beta * beta + vitesse * vitesse); if (beta < 16 * 5) { pos_seqsprite = 4 * Constantes.speed; } break; } } // On se déplace en courbe pathFinder.reachDestination(0); // Speed is unused cptMouvement++; } break; case HEN: if (z > 0) { // La poule est en l'air, elle n'est plus libre de ses mouvements physicMoveWithCollision(); } // Sinon elle agit comme les scripts de zone break; case ZONEARC: if (!isWounded() && isAlerte() && zildo.isAlive()) { // Get the enemy aligned with Zildo to draw arrows int xx = (int) getX(); int yy = (int) getY(); int deltaX = Math.abs((int) (zildo.x - xx - 2)); int deltaY = Math.abs((int) (zildo.y - yy)); if (deltaX <= 1 || deltaY <= 1) { // Get sight on Zildo and shoot ! sight(zildo, false); action = new ShotArrowAction(this); break; } // Gets on a right position to shoot Zildo if (deltaX <= deltaY) { pathFinder.setTarget(new Point(zildo.x, yy)); } else { pathFinder.setTarget(new Point(xx, zildo.y)); } } else if (lookForZildo(angle)) { setAlerte(true); } break; case WAKEUP: case INVOKE: pos_seqsprite++; break; case FOLLOW: pathFinder.determineDestination(); break; default: break; } } if (quel_deplacement != MouvementPerso.OBSERVE && quel_deplacement != MouvementPerso.VOLESPECTRE && quel_deplacement != MouvementPerso.SLEEPING) { if (pathFinder.getTarget() != null && this.getX() == pathFinder.getTarget().x && this.getY() == pathFinder.getTarget().y) { pathFinder.setTarget(null); destinationReached(); } if (!isGhost() && info == PersoInfo.ENEMY && !isAlerte() && quel_deplacement != MouvementPerso.IMMOBILE) { setAlerte(lookForZildo(angle)); } if (this.getAttente() > 0) { if (desc == PersoDescription.BAS_GARDEVERT) { // Turns his head around to look for Zildo if (attente == 1 && cptMouvement < 3) { if (!alerte && lookForZildo(Angle.rotate(angle, PersoGardeVert.mouvetete[cptMouvement]))) { alerte = true; EngineZildo.soundManagement.broadcastSound(BankSound.MonstreTrouve, this); } cptMouvement++; setAttente(20); } } attente--; // Stop hen's movements when it's flying (TODO : this isn't very clean, idem for fish !) } else if (quel_deplacement != MouvementPerso.HEN || z == 0 || (desc == PersoDescription.FISH && !flying)) { // On déplace le PNJ if (pathFinder.getTarget() == null && quel_deplacement.isMobile()) { // Pas de destination, donc on en fixe une dans la zone de déplacement cptMouvement = 0; pathFinder.determineDestination(); } float vitesse = pathFinder.speed; /* if (quel_deplacement == MouvementPerso.RAT) { // Script du rat => plus rapide, et crache des pierres} vitesse += 1.5; pos_seqsprite = pos_seqsprite % (8 * Constantes.speed - 1); if (quel_spr == PersoDescription.CRABE && Math.random() * 40 == 2) { // On crache une boule de pierre} pos_seqsprite = 8 * Constantes.speed; EngineZildo.spriteManagement.spawnSpriteGeneric(SpriteAnimation.ROCKBALL, (int) x, (int) y, (int) (angle.value + Math.random() * 4) // Attention : math.random() était 'i' // en pascal , null, null); attente = (int) (Math.random() * 5); } } else if (quel_deplacement == MouvementPerso.ELECTRIC) { vitesse = 0.2f; } */ if (pathFinder.getTarget() != null) { // Move character if he has a target Pointf loc = pathFinder.reachDestination(vitesse); // Check for infinite movement (A => B => A => B ...) boolean hasCollided = loc.x == x && loc.y == y; if ((deltaMoveX != 0 || deltaMoveY != 0) && loc.isSame(new Pointf(x - deltaMoveX, y - deltaMoveY))) { pathFinder.setTarget(null); } else { boolean slowDown = walkTile(true); if (slowDown) { x = (loc.x + x) / 2; y = (loc.y + y) / 2; } else { x = loc.x; y = loc.y; } } // suite_mouvement if (quel_deplacement == MouvementPerso.BEE) { angle = Angle.fromInt(angle.value & 2); } // Does character reach his destination ? if (pathFinder.getTarget() == null) { destinationReached(); pos_seqsprite = 0; } if (mouvement != MouvementZildo.SAUTE) { // Collision ? if (!quel_deplacement.isFlying() && hasCollided) { this.setX(sx); this.setY(sy); pathFinder.collide(); pos_seqsprite = 0; } else { pos_seqsprite = (pos_seqsprite + 1) % 512; } } } } } } }