static void entityWait() { self->layer = self->mental < 0 ? BACKGROUND_LAYER : FOREGROUND_LAYER; checkToMap(self); }
static void createIceWall() { int i, mapFloor; Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { mapFloor = getMapFloor(self->x, self->y); for (i=0;i<2;i++) { e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add Ice Wall"); } loadProperties("enemy/ice_wall", e); e->x = player.x + player.w / 2 + (i == 0 ? -200 : 200); e->y = mapFloor + 50; e->face = (i == 0 ? RIGHT : LEFT); e->targetY = mapFloor - e->h; e->x -= e->w / 2; e->action = &iceWallMove; e->draw = &drawLoopingAnimationToMap; e->touch = &iceWallTouch; e->head = self; e->type = ENEMY; e->flags |= DO_NOT_PERSIST; e->head = self; e->thinkTime = 60; setEntityAnimation(e, "STAND"); } self->endX--; if (self->endX <= 0) { self->thinkTime = 0; self->action = &teleportToOtherSide; } else { self->thinkTime = 90; } } checkToMap(self); hover(); }
static void createIceBlock() { int x, y; Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add Ice Block"); } loadProperties("edgar/edgar_frozen", e); setEntityAnimation(e, "STAND"); x = player.x + player.w / 2; y = self->y - 100 - (prand() % 60); e->x = x; e->y = y; if (isValidOnMap(e) == TRUE) { e->x = self->x + self->w / 2; e->y = self->y + self->h / 2; e->x -= e->w / 2; e->y -= e->h / 2; e->targetX = x; e->targetY = y; e->damage = 1; e->health = 50; calculatePath(e->x, e->y, e->targetX, e->targetY, &e->dirX, &e->dirY); e->flags |= (NO_DRAW|HELPLESS|TELEPORTING|NO_END_TELEPORT_SOUND); playSoundToMap("sound/common/spell", -1, self->x, self->y, 0); e->action = &iceBlockDrop; e->draw = &drawLoopingAnimationToMap; e->touch = &entityTouch; e->pain = &enemyPain; e->die = &iceBlockDie; e->head = self; e->face = self->face; e->type = ENEMY; e->thinkTime = 30; e->flags |= FLY|DO_NOT_PERSIST; self->endX--; if (self->endX <= 0) { self->thinkTime = 0; self->action = &castIceFinish; } else { self->thinkTime = 60; } } else { e->inUse = FALSE; } } checkToMap(self); hover(); }
static void createLightningWave() { int i, top, bottom, valid; Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { bottom = getMapFloor(self->x, self->y); top = getMapCeiling(self->x, self->y); valid = TRUE; playSoundToMap("sound/enemy/thunder_cloud/lightning", -1, self->x, self->y, 0); for (i=top;i<bottom;i+=32) { e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add lightning"); } loadProperties("enemy/lightning", e); setEntityAnimation(e, "STAND"); e->x = self->targetX + self->w / 2 - e->w / 2; e->y = i; e->action = &lightningWait; e->draw = &drawLoopingAnimationToMap; e->touch = &entityTouch; e->head = self; e->currentFrame = prand() % 6; e->face = RIGHT; e->thinkTime = 15; if (isValidOnMap(e) == FALSE) { valid = FALSE; e->inUse = FALSE; break; } } if (valid == TRUE) { e = addSmallRock(self->targetX, bottom, "common/small_rock"); e->x += (self->w - e->w) / 2; e->y -= e->h; e->dirX = -3; e->dirY = -8; e = addSmallRock(self->targetX, bottom, "common/small_rock"); e->x += (self->w - e->w) / 2; e->y -= e->h; e->dirX = 3; e->dirY = -8; self->targetX += self->face == RIGHT ? 64 : -64; self->thinkTime = 30; } else { self->action = &teleportToOtherSide; } } checkToMap(self); hover(); }
static void summon() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { e = addBook(self->x, self->y, "enemy/green_book"); e->pain = &enemyPain; e->targetX = player.x + player.w / 2 - e->w / 2 + 32; e->targetY = player.y - 32 - prand() % 64; e->startY = e->targetY; e->x = e->targetX; e->y = e->targetY; if (isValidOnMap(e) == TRUE) { e->x = self->x + self->w / 2; e->y = self->y + self->h / 2; e->x -= e->w / 2; e->y -= e->h / 2; e->health = 30; calculatePath(e->x, e->y, e->targetX, e->targetY, &e->dirX, &e->dirY); e->flags |= (NO_DRAW|HELPLESS|TELEPORTING|NO_END_TELEPORT_SOUND); playSoundToMap("sound/common/spell", -1, self->x, self->y, 0); e->face = RIGHT; self->endX--; } else { e->inUse = FALSE; } if (self->endX <= 0) { self->thinkTime = 300; self->action = &physicalAttackFinish; } else { self->thinkTime = 45; } } checkToMap(self); hover(); }
static void headWait() { self->face = self->head->face; if (self->face == LEFT) { self->x = self->head->x + self->head->w - self->w - self->offsetX; } else { self->x = self->head->x + self->offsetX; } self->y = self->head->y + self->offsetY; self->startY = self->y; self->endX += 3; if (self->endX >= 360) { self->endX = 0; } self->y = self->startY + sin(DEG_TO_RAD(self->endX)) * 4; checkToMap(self); alignBodyToHead(); if (self->head->health <= 0) { self->die(); } if (self->head->mental == 1) { self->thinkTime = 30; self->maxThinkTime = 1 + prand() % 3; self->action = &headBiteInit; } self->damage = self->head->damage; self->face = self->head->face; if (self->head->flags & FLASH) { self->flags |= FLASH; } else { self->flags &= ~FLASH; } if (self->head->inUse == FALSE) { self->inUse = FALSE; } }
static void entityWait() { self->face = RIGHT; checkToMap(self); }
static void walk() { if (self->maxThinkTime == 1) { self->dirX = (self->face == RIGHT ? self->speed : -self->speed); } if (self->offsetX != 0) { if (self->maxThinkTime == 0) { self->maxThinkTime = 1; playSoundToMap("sound/enemy/rampaging_master_tortoise/stomp", -1, self->x, self->y, 0); } self->dirX = self->standingOn == NULL ? 0 : self->standingOn->dirX; } else { self->maxThinkTime = 0; } if (self->maxThinkTime == 0 && (self->dirX == 0 || isAtEdge(self) == TRUE)) { self->dirX = (self->face == RIGHT ? -self->speed : self->speed); self->face = (self->face == RIGHT ? LEFT : RIGHT); } checkToMap(self); if (player.health > 0) { if (self->mental != -1 && prand() % 60 == 0) { self->dirX = 0; self->action = &riftAttackInit; self->thinkTime = 30; } else if (prand() % 60 == 0 && collision(self->x + (self->face == RIGHT ? self->w : -320), self->y, 320, self->h, player.x, player.y, player.w, player.h) == 1) { switch (prand() % 3) { case 0: self->dirX = 0; self->thinkTime = 60; self->action = &spinAttackInit; break; case 1: self->dirX = 0; self->thinkTime = 15; self->action = &castIce; break; default: self->thinkTime = 15; self->action = &breatheFireInit; self->dirX = 0; break; } } } }
static void entityWait() { setEntityAnimation(self, self->active == TRUE ? "WALK" : "STAND"); checkToMap(self); }
static void superSpearAttack() { int i, j; Entity *e; checkToMap(self); if (self->flags & ON_GROUND) { setEntityAnimation(self, "ATTACK_4"); if (self->thinkTime == -1) { for (i=0; i<6; i++) { e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add the Fireball Attack particle"); } loadProperties("boss/awesome_fireball_particle", e); setEntityAnimation(e, "STAND"); e->head = self; e->x = self->x + self->w / 2 - e->w / 2; e->y = self->y + self->h / 2 - e->h / 2; e->startX = e->x; e->startY = e->y; e->draw = &drawLoopingAnimationToMap; e->mental = 180; e->health = i * 60; e->action = &fireballChargeWait; } self->mental = 6; self->thinkTime = 0; } else if (self->mental <= 0) { self->mental = 0; setEntityAnimation(self, "ATTACK_3"); self->thinkTime = 60; if (self->face == RIGHT || self->target->health <= 0) { j = 1; for (i=self->x + self->w; i<self->target->x;) { e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add a Ground Spear"); } loadProperties("enemy/ground_spear", e); setEntityAnimation(e, "STAND"); e->x = i; e->y = self->y + self->h; e->startY = e->y - e->h; e->endY = e->y; e->thinkTime = 15 * j; e->damage = 1; e->touch = &entityTouch; e->action = &spearWait; e->draw = &drawLoopingAnimationToMap; e->head = self; i += e->w * 2; self->mental++; j++; } self->action = &superSpearAttackFinished; } else if (self->endY == 0 || self->target->health <= 0) { j = 1; for (i=self->x; i>self->target->x + self->target->w;) { e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add a Ground Spear"); } loadProperties("enemy/ground_spear", e); setEntityAnimation(e, "STAND"); e->x = i; e->y = self->y + self->h; e->startY = e->y - e->h; e->endY = e->y; e->thinkTime = 15 * j; e->damage = 1; e->touch = &entityTouch; e->action = &spearWait; e->draw = &drawLoopingAnimationToMap; e->head = self; i -= e->w * 2; self->mental++; j++; } self->action = &superSpearAttackFinished; } } } }
static void entityWait() { int i; Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { self->mental = self->mental == 0 ? 1 : 0; self->thinkTime = 120; for (i=0;i<2;i++) { e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add a Flame Statue Flame"); } loadProperties("enemy/horizontal_flame", e); if (i == 0) { e->face = RIGHT; e->x = self->x + self->w; e->y = self->y + (self->mental == 1 ? self->offsetY : self->offsetX); } else { e->face = LEFT; e->x = self->x - e->w; e->y = self->y + (self->mental == 0 ? self->offsetY : self->offsetX); } e->action = &flameWait; e->draw = &drawLoopingAnimationToMap; e->touch = &flameTouch; e->head = self; e->thinkTime = self->thinkTime; if (i == 0) { e->endY = playSoundToMap("sound/enemy/fire_burner/flame", -1, self->x, self->y, -1); } else { e->endY = -1; } e->type = ENEMY; e->flags |= DO_NOT_PERSIST|PLAYER_TOUCH_ONLY; setEntityAnimation(e, "STAND"); } self->action = &doFlame; } self->dirX = self->standingOn != NULL ? self->standingOn->dirX : 0; checkToMap(self); }
static void superFireballAttack() { int i; Entity *e; checkToMap(self); if (self->endY == 1 && (self->flags & ON_GROUND)) { setEntityAnimation(self, "ATTACK_1"); if (self->thinkTime == -1) { for (i=0; i<6; i++) { e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add the Fireball Attack particle"); } loadProperties("boss/awesome_fireball_particle", e); setEntityAnimation(e, "STAND"); e->head = self; if (self->face == LEFT) { e->x = self->x + self->w - e->w - e->offsetX; } else { e->x = self->x + e->offsetX; } e->y = self->y + self->offsetY; e->startX = e->x; e->startY = e->y; e->draw = &drawLoopingAnimationToMap; e->mental = 360; e->health = i * 60; e->action = &fireballChargeWait; } self->mental = 6; self->thinkTime = 0; } else if (self->mental <= 0) { self->thinkTime--; if (self->thinkTime <= 0) { setEntityAnimation(self, "ATTACK_2"); for (i=0; i<5; i++) { e = addProjectile("boss/awesome_super_fireball", self, self->x, self->y, (self->face == RIGHT ? 14 : -14), 0); e->touch = &fireballTouch; e->action = &fireballMove; e->type = ENEMY; e->x += (self->face == RIGHT ? self->w : e->w); e->y += self->offsetY; e->x += self->face == RIGHT ? -2 : 2; } playSoundToMap("sound/boss/awesome_boss/hadouken", BOSS_CHANNEL, self->x, self->y, 0); self->thinkTime = 120; self->target->thinkTime = 120; self->action = &superFireballAttackFinished; self->target->action = &superFireballAttackFinished; } } } else if (self->endY == 0 && self->target->health <= 0) { self->thinkTime = 120; self->action = &teleportOut; } }
static void teleportWait() { int i; Target *t; setEntityAnimation(self, "STAND"); if (player.health <= 0) { self->thinkTime--; if (self->thinkTime <= 0) { self->x = self->startX; self->y = self->startY; self->flags &= ~NO_DRAW; addParticleExplosion(self->x + self->w / 2, self->y + self->h / 2); playSoundToMap("sound/common/spell", -1, self->x, self->y, 0); self->action = &teleportIn; facePlayer(); self->head->mental--; } } else if (self->target->health <= 0) { self->thinkTime--; if (self->thinkTime <= 0) { self->x = self->target->x; t = getTargetByName((prand() % 2 == 0) ? "AWESOME_TARGET_LEFT" : "AWESOME_TARGET_RIGHT"); if (t == NULL) { showErrorAndExit("Awesome Boss cannot find target"); } self->y = t->y; faceTarget(); self->thinkTime = 60; self->flags &= ~NO_DRAW; addParticleExplosion(self->x + self->w / 2, self->y + self->h / 2); playSoundToMap("sound/common/spell", -1, self->x, self->y, 0); self->action = &healPartner; self->touch = &entityTouch; self->dirY = 0; self->head->mental--; } } else if (self->head->health == self->head->maxHealth) { if (self->head->mental == self->head->damage && self->head->targetY <= 0) { if (self->head->damage == 2) { t = getTargetByName((int)self->endX % 2 == 0 ? "AWESOME_TARGET_LEFT" : "AWESOME_TARGET_RIGHT"); self->x = t->x; self->y = t->y; self->action = superSpearAttackInit; } else { switch (self->head->targetX) { case 0: self->thinkTime = 30 * self->endX; self->mental = 5; self->action = &superDropAttackInit; self->flags |= FLY; self->dirY = 0; break; default: t = getTargetByName(self->endX <= 2 ? "AWESOME_TARGET_LEFT" : "AWESOME_TARGET_RIGHT"); self->x = t->x; self->y = t->y; self->endY = 1; /* The other one will stand behind their partner */ if (self->endX == 2 || self->endX == 4) { self->x += self->endX == 2 ? -24 : 24; self->endY = 0; } self->action = superFireballAttackInit; break; } } } } else if (self->active == TRUE) { self->thinkTime--; if (self->thinkTime <= 0) { i = prand() % 2; switch (i) { case 0: self->action = &fireballAttackInit; break; default: self->action = &dropAttackInit; break; } setEntityAnimation(self, "STAND"); self->dirY = 0; self->head->mental--; } } checkToMap(self); }
static void doIntro() { char name[MAX_VALUE_LENGTH]; Entity *e; checkToMap(self); self->thinkTime--; self->endX = 1; self->flags |= LIMIT_TO_SCREEN; if (self->thinkTime <= 0) { self->flags |= DO_NOT_PERSIST; snprintf(name, sizeof(name), "boss/awesome_boss_%d", self->mental); e = addEnemy(name, self->x - 8 * self->mental, self->y - 64); e->face = RIGHT; e->active = TRUE; e->targetX = e->x; e->targetY = e->y; e->startX = e->x; e->startY = e->y; e->maxHealth = e->health = self->maxHealth; e->endX = self->mental; calculatePath(e->x, e->y, e->targetX, e->targetY, &e->dirX, &e->dirY); e->flags |= (NO_DRAW|HELPLESS|TELEPORTING|NO_END_TELEPORT_SOUND|LIMIT_TO_SCREEN); e->action = &introWait; e->head = self; playSoundToMap("sound/common/spell", -1, self->x, self->y, 0); self->thinkTime = 30; self->mental++; if (self->mental == 5) { self->target = getEntityByObjectiveName(self->requires); if (self->target == NULL) { showErrorAndExit("Awesome Boss %s cannot find %s", self->objectiveName, self->requires); } self->thinkTime = 60; self->action = &entityWait; } } }
static void eatAttackWait() { Entity *temp; if (self->face == LEFT) { player.x = self->x + self->w - player.w - self->offsetX; } else { player.x = self->x + self->offsetX; } player.y = self->y + self->offsetY; self->thinkTime--; if (self->thinkTime <= 0) { temp = self; self = &player; self->takeDamage(temp, 3); self = temp; self->thinkTime = 60; if (player.health <= 0) { removeInventoryItemByObjectiveName("Amulet of Resurrection"); self->action = &attackFinished; } } if (self->health <= self->mental) { setEntityAnimation(self, "SPIT_OUT"); if (self->face == LEFT) { player.x = self->x + self->w - player.w - self->offsetX; } else { player.x = self->x + self->offsetX; } player.y = self->y + self->offsetY; setCustomAction(&player, &invulnerable, 60, 0, 0); setPlayerStunned(30); player.x -= player.dirX; player.y -= player.dirY; player.dirX = (10 + prand() % 3) * (self->face == LEFT ? -1 : 1); player.dirY = -3; self->touch = &touch; self->flags &= ~GRABBING; self->thinkTime = 60; self->action = &eatAttackFinish; } self->maxThinkTime--; checkToMap(self); }
static void spinnerMove() { int i; Entity *e; if (!(self->flags & NO_DRAW)) { for (i=0;i<8;i++) { e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add a spinner part"); } loadProperties("boss/snake_boss_special_shot", e); setEntityAnimation(e, "STAND"); e->x = self->x; e->y = self->y; e->startX = i * 30; e->mental = 0; e->damage = 2; e->health = 30; e->speed = 3; e->flags |= FLY; e->head = self; e->face = RIGHT; e->action = &rotateAroundTarget; e->touch = &entityTouch; e->die = &spinnerPartDie; e->draw = &drawLoopingAnimationToMap; e->type = ENEMY; } self->flags |= NO_DRAW; self->targetX = getMapStartX() - 128; self->dirX = -1; } checkToMap(self); if (self->x <= self->targetX && (self->flags & NO_DRAW)) { self->head->mental = 0; self->inUse = FALSE; } }
static void stalagmiteAttack() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add a stalagmite"); } loadProperties("item/stalagmite", e); setEntityAnimation(e, "STAND"); e->x = self->x + self->w / 2; e->y = self->y + self->h / 2; e->targetX = player.x + player.w / 2 - e->w / 2; e->targetY = getMapFloor(self->x, self->y); e->startY = e->targetY - e->h; calculatePath(e->x, e->y, e->targetX, e->targetY, &e->dirX, &e->dirY); e->flags |= (NO_DRAW|HELPLESS|TELEPORTING|NO_END_TELEPORT_SOUND); playSoundToMap("sound/common/spell", -1, self->x, self->y, 0); e->head = self; e->face = RIGHT; setEntityAnimation(e, "STAND"); e->action = &stalagmiteRise; e->draw = &drawLoopingAnimationToMap; e->touch = &entityTouch; e->damage = 2; e->takeDamage = &stalagmiteTakeDamage; e->die = &stalagmiteDie; e->head = self; e->face = self->face; e->type = ENEMY; e->thinkTime = 0; e->flags |= DO_NOT_PERSIST; self->mental--; if (self->mental <= 0) { self->thinkTime = 60; self->action = &stalagmiteAttackFinish; } else { self->thinkTime = 180; } } self->maxThinkTime--; checkToMap(self); }
static void breatheFire() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { setEntityAnimation(self, "BREATHE_FIRE"); switch (prand() % 4) { case 0: createAutoDialogBox(_("Chaos"), _("Burn to ashes!"), 180); break; case 1: createAutoDialogBox(_("Chaos"), _("Feel my power!"), 180); break; case 2: createAutoDialogBox(_("Chaos"), _("I will destroy you!"), 180); break; default: createAutoDialogBox(_("Chaos"), _("Suffer!"), 180); break; } e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add Chaos's Fire"); } loadProperties("boss/chaos_flame", e); e->face = self->face; e->action = &flameWait; e->creditsAction = &flameWait; e->draw = &drawLoopingAnimationToMap; e->thinkTime = 300; if (game.status != IN_CREDITS) { shakeScreen(LIGHT, 300); } e->mental = 1; e->health = 1200; e->head = self; if (self->face == LEFT) { e->x = self->x + self->w - e->w - e->offsetX; } else { e->x = self->x + e->offsetX; } e->y = self->y + e->offsetY; e->dirX = 14; e->startX = e->x; e->endX = e->face == LEFT ? getMapStartX() - SCREEN_WIDTH : getMapStartX() + SCREEN_WIDTH; playSoundToMap("sound/boss/chaos/breathe_fire", BOSS_CHANNEL, self->x, self->y, 0); self->thinkTime = 30; self->mental = 1; self->action = &breatheFireFinish; self->creditsAction = &breatheFireFinish; } checkToMap(self); }
static void attacking() { checkToMap(self); }
static void spearAttack() { int i, j, startX; Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { self->mental = 0; startX = getMapStartX(); j = 1; for (i=self->x;i>=startX;) { e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add a Ground Spear"); } loadProperties("enemy/ground_spear", e); setEntityAnimation(e, "STAND"); e->x = i; e->y = self->y + self->h; e->startY = e->y - e->h; e->endY = e->y; e->thinkTime = 15 * j; e->damage = 2; e->touch = &entityTouch; e->action = &spearWait; e->draw = &drawLoopingAnimationToMap; e->head = self; i -= e->w * 2; self->mental++; j++; } j = 1; for (;i<self->x;) { e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add a Ground Spear"); } loadProperties("enemy/ground_spear", e); setEntityAnimation(e, "STAND"); e->x = i; e->y = self->y + self->h; e->startY = e->y - e->h; e->endY = e->y; e->thinkTime = 15 * j; e->damage = 2; e->touch = &entityTouch; e->action = &spearWait; e->draw = &drawLoopingAnimationToMap; e->head = self; i += e->w * 2; self->mental++; j++; } self->action = &spearAttackFinished; } self->maxThinkTime--; checkToMap(self); }
static void moveToTarget() { /* Move vertically first */ if (self->y > self->targetY) { self->dirY = -self->speed; self->dirX = 0; } /* Now move horizontally */ else { self->y = self->targetY; self->dirX = self->targetX < self->x ? -self->speed : self->speed; self->dirY = 0; } checkToMap(self); if (self->target != NULL) { self->target->y = self->y + self->h / 2; self->target->x = self->x + (self->w - self->target->w) / 2; self->target->x += self->dirX; self->target->y += self->dirY; } if (fabs(self->x - self->targetX) <= fabs(self->dirX) && fabs(self->y - self->targetY) <= fabs(self->dirY)) { self->x = self->targetX; self->y = self->targetY; self->dirX = 0; self->dirY = 0; if (self->health == 1) { if (self->x == self->endX && self->y == self->endY) { setEntityAnimation(self, "STAND"); self->health = 2; self->startX = self->endX; self->startY = self->endY; } } else if (self->health == -1) { self->health = 0; } self->active = FALSE; self->action = &entityWait; } }
static void entityWait() { int rand; self->thinkTime--; if (self->thinkTime <= 0) { if (player.health > 0) { if (self->target != NULL && self->target->inUse == TRUE && self->target->mental == 1) /* Confused */ { rand = prand() % 8; } else if (self->target != NULL && self->target->inUse == TRUE && self->target->mental == 2) /* Blinded */ { rand = prand() % 4; } else { rand = prand() % 10; } switch (rand) { case 0: self->action = &eatAttackInit; break; case 1: self->action = &stalagmiteAttackInit; break; case 2: self->action = &holdPersonInit; break; case 3: self->action = &vineAttackInit; break; case 4: self->action = &riftAttackInit; break; case 5: self->action = &spearAttackInit; break; case 6: self->action = &spinnerAttackInit; break; case 7: self->action = &stompAttackInit; break; case 8: self->action = &confuseAttackInit; break; default: self->action = &blindAttackInit; break; } if (game.cheating == TRUE || self->maxThinkTime <= 0 || player.weight == 0) { self->action = &breatheFireInit; } } } self->maxThinkTime--; checkToMap(self); }
static void castLightningBolt() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add lightning"); } loadProperties("enemy/lightning", e); setEntityAnimation(e, "STAND"); e->x = self->x + self->w / 2; e->y = self->y + self->h / 2; e->x -= e->w / 2; e->y -= e->h / 2; e->targetX = player.x + player.w / 2 - e->w / 2; e->targetY = getMapCeiling(self->x, self->y); e->startY = e->targetY; e->endY = getMapFloor(e->targetX, e->targetY); calculatePath(e->x, e->y, e->targetX, e->targetY, &e->dirX, &e->dirY); e->flags |= (NO_DRAW|HELPLESS|TELEPORTING|NO_END_TELEPORT_SOUND); playSoundToMap("sound/common/spell", -1, self->x, self->y, 0); e->head = self; e->face = RIGHT; e->action = &lightningBolt; e->draw = &drawLoopingAnimationToMap; e->head = self; e->face = self->face; e->type = ENEMY; e->thinkTime = 0; e->flags |= FLY|DO_NOT_PERSIST; self->endX--; if (self->endX <= 0) { self->thinkTime = 0; self->action = &castLightningFinish; } else { self->thinkTime = 30; } } checkToMap(self); hover(); }
static void dieWait() { int i; Entity *e; self->thinkTime--; if (self->mental == 0) { self->x = self->startX + sin(DEG_TO_RAD(self->endX)) * 4; self->endX += 90; if (self->endX >= 360) { self->endX = 0; } } if (self->thinkTime <= 0) { if (self->mental == 0) { self->x = self->startX; self->layer = MID_GROUND_LAYER; setEntityAnimation(self, "DIE_2"); shakeScreen(MEDIUM, 60); playSoundToMap("sound/common/crash", BOSS_CHANNEL, self->x, self->y, 0); for (i=0;i<300;i++) { e = addSmoke(self->x + (prand() % self->w), self->y + self->h, "decoration/dust"); if (e != NULL) { e->y -= prand() % e->h; } } self->mental = 1; self->thinkTime = 120; } else { fireTrigger(self->objectiveName); fireGlobalTrigger(self->objectiveName); clearContinuePoint(); freeBossHealthBar(); } } checkToMap(self); }
static void summon2() { int i; Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { i = prand() % 4; switch (i) { case 0: e = addBook(self->x, self->y, "enemy/green_book"); break; case 1: e = addBook(self->x, self->y, "enemy/yellow_book"); break; case 2: e = addBook(self->x, self->y, "enemy/red_book"); break; default: e = addBook(self->x, self->y, "enemy/blue_book"); break; } e->pain = &enemyPain; e->targetX = player.x + player.w / 2 - e->w / 2 + (self->face == RIGHT ? 64 : -64); e->targetY = player.y - 32 - prand() % 64; e->startY = e->targetY; e->x = e->targetX; e->y = e->targetY; if (isValidOnMap(e) == TRUE) { e->x = self->x + self->w / 2; e->y = self->y + self->h / 2; e->x -= e->w / 2; e->y -= e->h / 2; e->health = 30; calculatePath(e->x, e->y, e->targetX, e->targetY, &e->dirX, &e->dirY); e->flags |= (NO_DRAW|HELPLESS|TELEPORTING|NO_END_TELEPORT_SOUND); playSoundToMap("sound/common/spell", -1, self->x, self->y, 0); e->face = RIGHT; self->endX--; } else { e->inUse = FALSE; } if (self->endX <= 0) { self->thinkTime = 120; self->action = &physicalAttackFinish; } else { self->thinkTime = 45; } } facePlayer(); checkToMap(self); hover(); }
static void riftAttack() { int i, width; Entity *e; Target *t1, *t2; self->thinkTime--; if (self->thinkTime <= 0) { self->mental = 2; t1 = getTargetByName("CHAOS_TARGET_LEFT"); t2 = getTargetByName("CHAOS_TARGET_RIGHT"); if (t1 == NULL || t2 == NULL) { showErrorAndExit("Chaos cannot find target"); } width = (t2->x - t1->x) / 2; for (i=0;i<self->mental;i++) { e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add an Energy Rift"); } loadProperties("enemy/energy_rift", e); e->damage = 2; e->action = &riftOpen; e->touch = &entityTouch; e->draw = &drawLoopingAnimationToMap; e->type = ENEMY; setEntityAnimation(e, "STAND"); e->x = (i == 0 ? t1->x : t2->x) - e->w / 2; e->y = (i == 0 ? t1->y : t2->y); e->speed = width; e->thinkTime = 15; e->head = self; e->health = 0; } self->action = &riftAttackWait; self->thinkTime = 15; } self->maxThinkTime--; checkToMap(self); }
static void iceWallMove() { int i; Entity *e; if (self->y > self->targetY) { self->y -= 12; if (self->y <= self->targetY) { self->y = self->targetY; 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; } } else { self->thinkTime--; if (self->thinkTime == 0) { self->dirX = self->face == LEFT ? -self->speed : self->speed; } else if (self->thinkTime < 0 && self->dirX == 0) { playSoundToMap("sound/common/shatter", -1, self->x, self->y, 0); for (i=0;i<8;i++) { e = addTemporaryItem("misc/ice_wall_piece", self->x, self->y, RIGHT, 0, 0); e->x = self->x + self->w / 2; e->x -= e->w / 2; e->y = self->y + self->h / 2; e->y -= e->h / 2; e->dirX = (prand() % 4) * (prand() % 2 == 0 ? -1 : 1); e->dirY = ITEM_JUMP_HEIGHT * 2 + (prand() % ITEM_JUMP_HEIGHT); setEntityAnimationByID(e, i); e->thinkTime = 60 + (prand() % 60); e->touch = NULL; } self->inUse = FALSE; } checkToMap(self); } }
static void eatAttack() { self->thinkTime--; if (self->thinkTime <= 0) { if (self->x <= self->targetX) { self->x = self->targetX; setEntityAnimation(self, "MOUTH_CLOSE"); if (self->flags & GRABBING) { self->mental = self->health - 80; self->thinkTime = 600; self->action = &eatAttackWait; } else { self->thinkTime = 60; self->touch = &touch; self->action = &eatAttackFinish; } self->targetX = self->startX; self->dirX = 0; } else { setEntityAnimation(self, "MOUTH_OPEN"); self->dirX = -12; self->touch = &eatTouch; if (self->flags & GRABBING) { if (self->face == LEFT) { player.x = self->x + self->w - player.w - self->offsetX; } else { player.x = self->x + self->offsetX; } player.y = self->y + self->offsetY; } } } self->maxThinkTime--; checkToMap(self); }
static void entityWait() { checkToMap(self); }
static void soulSteal() { Target *t; setCustomAction(&player, &stickToFloor, 3, 0, 0); self->thinkTime--; player.x = self->targetX; self->maxThinkTime += self->mental; if (self->maxThinkTime > 255) { self->maxThinkTime = 255; self->mental *= -1; } else if (self->maxThinkTime < 0) { self->maxThinkTime = 0; self->mental *= -1; } player.alpha = self->maxThinkTime; if (self->thinkTime <= 0) { self->flags |= NO_DRAW; addParticleExplosion(self->x + self->w / 2, self->y + self->h / 2); playSoundToMap("sound/common/spell", -1, self->x, self->y, 0); t = getTargetByName("AZRIEL_TOP_TARGET"); if (t == NULL) { showErrorAndExit("Azriel cannot find target"); } self->x = t->x; self->y = t->y; self->head->health++; self->head->alpha = self->head->health * 64; if (self->head->alpha > 255) { self->head->alpha = 255; } self->head->thinkTime = self->head->maxThinkTime; self->head->mental = 0; player.alpha = self->targetY; player.alpha -= 64; if (player.alpha <= 0) { player.alpha = 0; player.thinkTime = 600; player.health = 0; setPlayerLocked(TRUE); } self->thinkTime = 30; self->action = &soulStealFinish; } checkToMap(self); becomeTransparent(); }