static void redLookForPlayer() { self->thinkTime--; if (self->thinkTime <= 0) { self->thinkTime = 0; } setEntityAnimation(self, "WALK"); moveAndJump(); if (player.health > 0 && (prand() % 10 == 0) && self->thinkTime <= 0) { if (collision(self->x + (self->face == LEFT ? -160 : self->w), self->y, 160, self->h, player.x, player.y, player.w, player.h) == 1) { setEntityAnimation(self, "STAND"); self->thinkTime = 30; self->dirX = 0; self->mental = 3; self->action = &webAttack; facePlayer(); } } }
static void headButtMoveToPosition() { checkToMap(self); facePlayer(); if (atTarget()) { self->flags &= ~(FLY|UNBLOCKABLE); setEntityAnimation(self, "ATTACK_2"); self->thinkTime = 60; self->x = self->targetX; self->y = self->targetY; self->dirX = 0; self->dirY = 0; self->startX = 0; self->startY = self->y; self->action = &moveToHeadButtRange; } }
static void lookForPlayer() { self->thinkTime--; if (self->thinkTime <= 0) { self->thinkTime = 0; } setEntityAnimation(self, "WALK"); moveAndJump(); if (player.health > 0 && (prand() % 10 == 0) && self->thinkTime <= 0) { if (collision(self->x + (self->face == LEFT ? -64 : self->w), self->y, 64, self->h, player.x, player.y, player.w, player.h) == 1) { setEntityAnimation(self, "STAND"); self->thinkTime = 30; self->dirX = 0; self->action = &pounceAttack; self->reactToBlock = &pounceReactToBlock; facePlayer(); } } }
static void spinAttackEnd() { checkToMap(self); if ((self->flags & ON_GROUND) && self->thinkTime == 0) { facePlayer(); self->dirX = 0; self->maxThinkTime--; if (self->maxThinkTime > 0) { self->action = &spinAttackStart; self->thinkTime = 0; } else { self->action = &grubAttackFinish; self->thinkTime = 30; } } }
static void grubAttackFinish() { if (self->frameSpeed > 0) { self->frameSpeed = -1; facePlayer(); setEntityAnimation(self, "ATTACK_2"); self->animationCallback = &attackFinished; self->frameSpeed = 0; } else if (self->thinkTime > 0) { self->thinkTime--; if (self->thinkTime <= 0) { self->frameSpeed = -1; } } }
static void pounceAttack() { long onGround; if (self->thinkTime > 0) { self->thinkTime--; checkToMap(self); } else { if (self->flags & ON_GROUND) { self->dirX = (self->face == RIGHT ? 6 : -6); self->dirY = -6; } else { if (self->dirX == 0) { self->dirX = self->face == RIGHT ? -3 : 3; self->dirY = -5; self->face = self->face == RIGHT ? LEFT : RIGHT; } } onGround = (self->flags & ON_GROUND); checkToMap(self); if (onGround == 0 && ((self->flags & ON_GROUND) || (self->standingOn != NULL))) { if (player.health > 0 && collision(self->x + (self->face == LEFT ? -16 : self->w), self->y, 16, self->h, player.x, player.y, player.w, player.h) == 1) { self->thinkTime = 60; self->dirX = 0; self->action = &pounceAttack; facePlayer(); } else { self->action = self->resumeNormalFunction; self->reactToBlock = &changeDirection; self->dirX = self->face == LEFT ? -self->speed : self->speed; } } } }
static void spinAttack() { self->thinkTime--; checkToMap(self); if (self->dirX == 0 || isAtEdge(self)) { shakeScreen(MEDIUM, 15); self->dirX = self->face == LEFT ? 3 : -3; self->dirY = -6; self->action = &spinAttackEnd; self->thinkTime = 0; playSoundToMap("sound/common/crash", -1, self->x, self->y, 0); facePlayer(); } else if (self->thinkTime <= 0) { self->action = &spinAttackEnd; self->thinkTime = 0; } }
static void stingAttackMoveToPosition() { int bottomY; checkToMap(self); facePlayer(); if (atTarget()) { self->dirY = 0; self->dirX = 0; bottomY = self->y + self->h - 1; setEntityAnimation(self, "ATTACK_3"); self->y = bottomY - self->h; self->frameSpeed = 12; self->thinkTime = 120; self->action = &stingAttackWindUp; } }
static void dieFinish() { if (self->thinkTime > 0) { self->thinkTime--; setCustomAction(self, &invulnerableNoFlash, 240, 0, 0); if (self->thinkTime <= 0) { fireTrigger(self->objectiveName); fireGlobalTrigger(self->objectiveName); } } if (self->endY == 1) { setEntityAnimation(self, "STAND"); self->thinkTime = 60; facePlayer(); self->action = &finalAttack; } checkToMap(self); }
static void punch() { Entity *e; if (self->y > self->targetY) { self->thinkTime--; if (self->thinkTime <= 0) { if (self->thinkTime == 0) { playSoundToMap("sound/common/crumble", BOSS_CHANNEL, self->x, self->y, 0); shakeScreen(MEDIUM, 15); } e = addSmallRock(self->x, self->y, "common/small_rock"); e->x += (self->w - e->w) / 2; e->y += (self->h - e->h) / 2; e->dirX = -3; e->dirY = -8; e = addSmallRock(self->x, self->y, "common/small_rock"); e->x += (self->w - e->w) / 2; e->y += (self->h - e->h) / 2; e->dirX = 3; e->dirY = -8; self->y -= 12; if (self->y <= self->targetY) { self->y = self->targetY; self->maxThinkTime--; self->thinkTime = self->maxThinkTime > 0 ? 30 : 90; } } } else { self->thinkTime--; if (self->thinkTime < 0) { self->targetY = self->y + self->h; self->action = &punchSink; } } facePlayer(); }
static void selectRandomBottomTarget() { Target *t; if (prand() % 2 == 0) { t = getTargetByName("FLY_BOSS_TARGET_BOTTOM_RIGHT"); } else { t = getTargetByName("FLY_BOSS_TARGET_BOTTOM_LEFT"); } if (t == NULL) { showErrorAndExit("Fly boss cannot find target"); } self->targetX = t->x; self->targetY = t->y; calculatePath(self->x, self->y, self->targetX, self->targetY, &self->dirX, &self->dirY); self->dirX *= self->speed; self->dirY *= self->speed; facePlayer(); }
void ColossusAI::update(float dt) { // Is the player dead? if (GameLayer::isPlayerDead()) { // If the tumbler is grounded, run away if (troll->isGrounded()) { moveFromPlayer(); colossus->rect = colossus->walkAnim.update(dt); } // Wait for the ground to hit it's feet else { colossus->rect = colossus->walkAnim.reset(); } faceAwayPlayer(); return; } if (abs(trollPlayerXDiff()) > 20.f && !isCrushing) { moveToPlayer(); facePlayer(); colossus->rect = colossus->walkAnim.update(dt); } else { updateCrush(dt); } }
static void headButtFinish() { self->touch = &entityTouch; if (self->flags & ON_GROUND) { facePlayer(); self->dirX = 0; self->thinkTime = 120; if (prand() % 2 == 0) { self->action = &attackFinished; } else { self->action = &moveToHeadButtRange; } } checkToMap(self); }
static void moveToHeadButtRange() { int playerX, bossX; facePlayer(); self->thinkTime--; if (self->thinkTime <= 0) { bossX = self->x + (self->face == LEFT ? 0 : self->w - 1); playerX = player.x + (self->face == RIGHT ? 0 : player.w - 1); if (abs(bossX - playerX) < 24) { self->dirX = self->face == LEFT ? -self->speed * 3 : self->speed * 3; self->dirY = -3; self->action = &headButt; self->reactToBlock = &reactToHeadButtBlock; } else { self->dirX = self->face == LEFT ? -self->speed : self->speed; } } checkToMap(self); }
static void doIntro() { int i; Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { self->x = self->startX; setEntityAnimation(self, "STAND"); playSoundToMap("sound/common/gib", -1, self->x, self->y, 0); for (i=0;i<11;i++) { e = addTemporaryItem("boss/fly_boss_cocoon_piece", self->x, self->y, RIGHT, 0, 0); e->x += (self->w - e->w) / 2; e->y += (self->h - e->h) / 2; e->dirX = (prand() % 3) * (prand() % 2 == 0 ? -1 : 1); e->dirY = ITEM_JUMP_HEIGHT + (prand() % ITEM_JUMP_HEIGHT); setEntityAnimationByID(e, i); e->thinkTime = 180 + (prand() % 60); } self->draw = &drawLoopingAnimationToMap; playSoundToMap("sound/boss/fly_boss/buzz", BOSS_CHANNEL, self->x, self->y, 0); self->takeDamage = &takeDamage; self->action = &introPause; self->touch = &entityTouch; self->thinkTime = 120; self->startY = self->y; self->dirY = self->dirX = 0; self->startX = 0; facePlayer(); } else { if (self->x == self->startX || (self->thinkTime % 2 == 0)) { self->x = self->startX + (3 * (self->x < self->startX ? 1 : -1)); } } }
static void spitIce() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { facePlayer(); e = addProjectile("enemy/ice", self, self->x, self->y, 0, 0); if (e == NULL) { showErrorAndExit("No free slots to add Ice"); } e->face = self->face; e->flags |= PLAYER_TOUCH_ONLY|FLY; if (self->face == LEFT) { e->x = self->x + self->w - e->w - self->offsetX; } else { e->x = self->x + self->offsetX; } e->y = self->y + self->offsetY; calculatePath(e->x, e->y, player.x + player.w / 2, player.y + player.h / 2, &e->dirX, &e->dirY); e->dirX *= 8; e->dirY *= 8; e->touch = &iceTouch; self->mental--; if (self->mental <= 0) { setEntityAnimation(self, "ICE_STAND"); self->thinkTime = 60; self->action = &spitFinish; } else { self->thinkTime = 30; } } checkToMap(self); }
static void createThunderCloudFinish() { facePlayer(); checkToMap(self); hover(); }
static void grubAttackInit() { facePlayer(); setEntityAnimation(self, "ATTACK_2"); self->thinkTime = 30; self->animationCallback = &grubAttackWait; self->maxThinkTime = 1 + prand() % 5; }
static void chasePlayer() { long onGround = self->flags & ON_GROUND; self->thinkTime--; if (self->thinkTime > 0) { checkToMap(self); } else if (self->thinkTime == 0) { facePlayer(); self->frameSpeed = 12; checkToMap(self); } else { self->dirX = self->face == LEFT ? -2.0f : 2.0f; checkToMap(self); if (!(self->flags & ON_GROUND)) { self->mental++; } if (onGround == 0 && (self->flags & ON_GROUND)) { if (self->mental > 15) { playSoundToMap("sound/common/crash", -1, self->x, self->y, 0); shakeScreen(STRONG, 30); addDust(); self->thinkTime = 30; self->dirX = 0; self->frameSpeed = 0; } self->mental = 0; } } }
static void dropWait() { self->thinkTime--; facePlayer(); if (self->thinkTime <= 0) { self->flags |= FLY; self->action = &attackFinished; } }
static void eatInit() { self->damage = 0; self->layer = FOREGROUND_LAYER; facePlayer(); self->action = &eatAttack; self->takeDamage = &eatTakeDamage; self->mental = 10000; }
static void castLightningInit() { self->thinkTime--; if (self->thinkTime <= 0) { if (self->maxThinkTime == 1) { self->action = &createThunderCloud; } else if (self->maxThinkTime == 2) { facePlayer(); self->endX = 0; self->targetX = self->x + (self->face == RIGHT ? 64 : -64); self->action = &createLightningWaveInit; } else { facePlayer(); self->endX = 5; self->targetX = self->x + (self->face == RIGHT ? 64 : -64); self->action = &castLightningBolt; } } hover(); }
static void superFireballAttackInit() { facePlayer(); playSoundToMap("sound/common/spell", BOSS_CHANNEL, self->x, self->y, 0); self->flags &= ~NO_DRAW; addParticleExplosion(self->x + self->w / 2, self->y + self->h / 2); self->action = &superFireballAttack; self->touch = &entityTouch; self->thinkTime = -1; self->head->mental = 0; }
static void iceAttack() { self->thinkTime--; if (player.health > 0 && self->thinkTime <= 0) { self->endY = self->endY == 1 ? 0 : 1; self->action = &castIceInit; } facePlayer(); checkToMap(self); hover(); }
static void entityWait() { int i; self->thinkTime--; facePlayer(); hover(); if (self->thinkTime <= 0 && player.health > 0) { i = self->health <= (self->maxHealth / 10) ? prand() % 10 : prand() % 4; switch (i) { case 0: self->action = &bulletFireInit; break; case 1: self->action = &headButtInit; break; case 2: self->thinkTime = 120 + prand() % 180; self->action = &dropInit; break; case 3: self->action = &slimeFireInit; break; default: self->action = &stingAttackInit; break; } self->damage = 1; playSoundToMap("sound/boss/fly_boss/buzz", BOSS_CHANNEL, self->x, self->y, 0); } }
static void fireDropMoveToTop() { checkToMap(self); if (self->y <= self->targetY) { self->y = self->targetY; self->dirY = 0; self->startY = 3 + prand() % 3; self->action = &fireDropMoveAbovePlayer; setEntityAnimation(self, "FIRE_WALK"); facePlayer(); } }
static void spinAttackEnd() { checkToMap(self); if (self->flags & ON_GROUND) { facePlayer(); setEntityAnimation(self, "STAND"); self->speed = self->originalSpeed; self->dirX = (self->face == RIGHT ? self->speed : -self->speed); self->action = &walk; self->thinkTime = 60; } }
static void spinAttackInit() { setEntityAnimation(self, "ATTACK_2"); self->thinkTime--; if (self->thinkTime <= 0) { facePlayer(); self->action = &spinAttack; self->endX = prand() % 3; self->speed = self->speed * 8; self->dirX = self->face == LEFT ? -self->speed : self->speed; } checkToMap(self); }
static void bulletFireMoveToPosition() { checkToMap(self); facePlayer(); if (atTarget()) { self->maxThinkTime = 5 + prand() % 15; self->x = self->targetX; self->y = self->targetY; self->dirX = 0; self->dirY = 0; self->startX = 0; self->startY = self->y; self->action = &fireBullets; } }
static void slimeFireMoveToPosition() { checkToMap(self); facePlayer(); if (atTarget()) { self->maxThinkTime = 1 + prand() % 4; self->x = self->targetX; self->y = self->targetY; self->dirX = 0; self->dirY = 0; self->startX = 0; self->startY = self->y; self->action = &fireSlime; } }