float fTan(float val){ return fSin(val)/fCos(val); }
/** * Episode 1 guardian iteration. * * @param ticks Time * * @return Remaining event */ JJ1Event* MedGuardian::step(unsigned int ticks) { fixed sin = fSin(ticks / 2); fixed cos = fCos(ticks / 2); set = prepareStep(ticks); if (!set) return remove(false); if (level->getEventHits(gridX, gridY) >= set->strength / 2) stage = 1; if (level->getEventHits(gridX, gridY) >= set->strength) stage = 2; // Stage 0: Move in an eight shape and fire the occasional shot if (stage == 0) { if (direction == 1) { // Lower right part of the eight setAnimType(E_LEFTANIM); dx = TTOF(gridX) + (sin * 96) - x + ITOF(96); dy = TTOF(gridY) - (cos * 64) - y; if (cos > 0) direction = 2; } if (direction == 2) { // Upper left part of the eight setAnimType(E_LEFTANIM); dx = TTOF(gridX) - (sin * 96) - x - ITOF(96); dy = TTOF(gridY) - (cos * 64) - y; if (cos < 0) direction = 3; } if (direction == 3) { // Lower left part of the eight setAnimType(E_RIGHTANIM); dx = TTOF(gridX) - (sin * 96) - x - ITOF(96); dy = TTOF(gridY) - (cos * 64) - y; if (cos > 0) direction = 4; } if (direction == 4) { // Upper right part of the eight setAnimType(E_RIGHTANIM); dx = TTOF(gridX) + (sin * 96) - x + ITOF(96); dy = TTOF(gridY) - (cos * 64) - y; if (cos < 0) direction = 1; } // Decide if there should be a shot if ((ticks % (set->bulletPeriod * 25) > (unsigned int)(set->bulletPeriod * 25) - 300)) { level->setEventTime(gridX, gridY, ticks + 300); shoot = true; } // Shoot if there is a shot if (level->getEventTime(gridX, gridY) && (ticks > level->getEventTime(gridX, gridY)) && shoot) { if (set->bullet < 32) level->createBullet(NULL, gridX, gridY, x + anim->getAccessoryShootX(), y + anim->getAccessoryShootY(), set->bullet, (animType != E_LEFTANIM), ticks); shoot = false; } } // Stage 1: Hop back and forth destroying the bottom row of tiles if (stage == 1) { fixed startPos = TTOF(gridY) + ITOF(40); if (direction < 5) { // Move up or down towards the starting position for hopping direction = (y > startPos) ? 5 : 6; } // Move up to the correct height if (direction == 5) { if (y > startPos) { dx = 0; dy = ITOF(-2); } else direction = 7; } // Move down to the correct height if (direction == 6) { if (y < startPos) { dx = 0; dy = ITOF(2); } else direction = 7; } // Cosinus should be near zero before we start hopping. if (direction == 7) { dx = 0; dy = 0; if (cos > -100 && cos < 100) direction = 8; } // Start hopping if (direction == 8) { if (level->checkMaskUp(x, y) || level->checkMaskUp(x + width, y)) setAnimType((animType == E_LEFTANIM) ? E_RIGHTANIM : E_LEFTANIM); dy = startPos - abs(cos * 96) - y; dx = abs(cos * 6); if (animType == E_LEFTANIM) dx *= -1; if (cos < 0 && level->checkMaskDown(x + ITOF(anim->getWidth() / 2), y + TTOF(1))) direction = 9; } // Destroy the block underneath if (direction == 9) { // Shake a bit dx = (FTOI(x) % 2) ? ITOF(1) : ITOF(-1); dy = 0; // Remove the tile if (cos > 0 && cos < 100) { level->setTile( FTOT(x + ITOF((anim->getWidth() / 2))), FTOT(y) + 1, set->magnitude); direction = 8; } } } // Stage 2: End of behavior if (stage == 2) { dx = 0; dy = ITOF(4); } x += dx; y += dy; dx = dx << 6; dy = dy << 6; return this; }