static void creditsMove() { if (self->mental == 0) { createBeam(); self->mental = 1; } self->thinkTime += 5; self->dirY += cos(DEG_TO_RAD(self->thinkTime)); self->dirY /= 3; self->dirX = self->speed; checkToMap(self); if (self->mental == 1) { self->endX = MAX(getMapCeiling(self->x + self->w - 1, self->y), getMapCeiling(self->x, self->y)); self->endY = MIN(getMapFloor(self->x + self->w - 1, self->y), getMapFloor(self->x, self->y)); } if (self->dirX == 0) { self->inUse = FALSE; } }
static void statueAttack() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { e = addEnemy("enemy/flame_statue", 0, 0); e->health = 5; e->layer = BACKGROUND_LAYER; e->x = player.x + player.w / 2 - e->w / 2; e->x -= player.w * 2; e->mental = 0; e->y = getMapFloor(self->x + self->w / 2, self->y); e->targetY = e->y - e->h; e->action = &statueRise; e->touch = NULL; e->thinkTime = 240; e = addEnemy("enemy/flame_statue", 0, 0); e->health = 5; e->layer = BACKGROUND_LAYER; e->x = player.x + player.w / 2 - e->w / 2; e->x += player.w * 2; e->mental = 1; e->y = getMapFloor(self->x + self->w / 2, self->y); e->targetY = e->y - e->h; e->action = &statueRise; e->touch = NULL; e->thinkTime = 240; self->thinkTime = 600; self->action = &statueRiseWait; } hover(); }
static void init() { self->endY = MIN(getMapFloor(self->startX + self->w - 1, self->y), getMapFloor(self->startX, self->y)); self->mental = 0; self->action = &move; self->creditsAction = &creditsMove; }
static void init() { createVine(); self->endY = MIN(getMapFloor(self->x + self->w - 1, self->y), getMapFloor(self->x, self->y)); self->endY -= self->startY; self->action = &entityWait; }
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(e->targetX, 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); 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->action = &castWait; setEntityAnimation(self, "ATTACK_2"); self->animationCallback = &summonEnd; } }
static void redBeamWait() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { e = getFreeEntity(); loadProperties("boss/azriel_ground_spikes", e); e->head = self; e->x = self->x + self->w / 2 - e->w / 2; e->y = getMapFloor(self->head->x + self->head->w / 2, self->head->y); e->startY = e->y - e->h; e->endY = e->y; e->action = &spikeRise; e->draw = &drawLoopingAnimationToMap; e->touch = &entityTouch; e->face = RIGHT; e->type = ENEMY; self->thinkTime = 30; self->action = &redBeamFinish; } }
static void init() { addChain(); addRay(); self->endY = getMapFloor(self->startX, self->startY); self->action = &entityWait; }
static void init() { /*if (self->startY == 0 && self->endY == 0)*/ { self->startY = self->y; self->endY = getMapFloor(self->x, self->y); } self->action = &followPlayer; }
static void spikeAttackMoveToTopTarget() { Entity *e; if (atTarget()) { self->thinkTime--; if (self->thinkTime <= 0) { e = getFreeEntity(); loadProperties("boss/azriel_light_beam", e); setEntityAnimation(e, "APPEAR"); e->animationCallback = &beamAppearFinish; e->head = self; e->x = getMapStartX() + prand() % (SCREEN_WIDTH - e->w); e->y = getMapFloor(self->x + self->w / 2, self->y) - e->h; e->startY = e->y; e->action = &beamWait; e->draw = &drawBeam; e->touch = &entityTouch; e->face = RIGHT; e->type = ENEMY; e->thinkTime = 240; e->mental = prand() % 3 == 0 ? 1 : 0; e->targetX = playSoundToMap("sound/boss/grimlore/grimlore_summon", -1, e->x, e->y, -1); self->action = &spikeAttackWait; self->mental = 1; } } checkToMap(self); becomeTransparent(); }
static void castIce() { int i, mapFloor; Entity *e; mapFloor = getMapFloor(self->head->x + self->head->w / 2, self->head->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; e->face = (i == 0 ? RIGHT : LEFT); e->targetY = mapFloor - e->h; e->x -= e->w / 2; e->action = &iceWallMove; e->draw = &drawLoopingAnimationToMap; e->head = self; e->type = ENEMY; e->flags |= DO_NOT_PERSIST; e->head = self; e->thinkTime = 60; setEntityAnimation(e, "STAND"); } self->action = &castWait; setEntityAnimation(self, "ATTACK_2"); self->animationCallback = &summonEnd; }
static void fly() { if (self->dirX == 0) { self->dirX = (self->face == RIGHT ? -self->speed : self->speed); self->face = (self->face == RIGHT ? LEFT : RIGHT); } self->thinkTime += 5; self->dirY += cos(DEG_TO_RAD(self->thinkTime)); self->dirY /= 3; checkToMap(self); if (self->mental == 1) { self->endX = MAX(getMapCeiling(self->x + self->w - 1, self->y), getMapCeiling(self->x, self->y)); self->endY = MIN(getMapFloor(self->x + self->w - 1, self->y), getMapFloor(self->x, self->y)); } }
static void createLightBeam() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { e = getFreeEntity(); loadProperties("boss/azriel_light_beam", e); setEntityAnimation(e, "APPEAR"); e->animationCallback = &beamAppearFinish; self->target = e; e->head = self; e->x = self->x + self->w / 2 - e->w / 2; e->y = getMapFloor(self->x + self->w / 2, self->y) - e->h; e->startY = e->y; e->action = &beamWait; e->draw = &drawBeam; e->touch = &entityTouch; e->face = RIGHT; e->type = ENEMY; e->thinkTime = 3600; e->mental = 0; self->action = &introRaise; self->thinkTime = 120; self->mental = 1; playDefaultBossMusic(); } }
static void raiseDead() { char targetName[MAX_VALUE_LENGTH]; Target *t; Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { snprintf(targetName, MAX_VALUE_LENGTH, "GRAVE_%c", self->description[self->mental]); t = getTargetByName(targetName); if (t == NULL) { showErrorAndExit("Azriel cannot find target"); } e = addEnemy("enemy/zombie", t->x, t->y); e->y = getMapFloor(self->x + self->w / 2, self->y); e->startX = e->x; e->startY = e->y - e->h; e->endY = e->y; e->thinkTime = 15 + prand() % 105; self->mental--; if (self->mental <= 0) { self->thinkTime = 30; self->action = &raiseDeadFinish; } } checkToMap(self); becomeTransparent(); }
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 destroyFloor() { EntityList *list; EntityList *l; Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { if (self->mental == 0) { self->y = getMapFloor(self->x + self->w / 2, self->y) - self->h; playSoundToMap("sound/common/spell", -1, self->x, self->y, 0); self->flags &= ~NO_DRAW; addParticleExplosion(self->x + self->w / 2, self->y + self->h / 2); self->thinkTime = 60; self->mental = 1; } else if (self->mental == 1) { setEntityAnimation(self, "ATTACK_1"); self->mental = 2; self->thinkTime = 600; list = getEntitiesByObjectiveName("SORCEROR_FLOOR"); for (l=list->next;l!=NULL;l=l->next) { e = l->entity; e->active = TRUE; } freeEntityList(list); } else if (self->mental == 2) { setEntityAnimation(self, "STAND"); list = getEntitiesByObjectiveName("SORCEROR_FLOOR"); for (l=list->next;l!=NULL;l=l->next) { e = l->entity; e->active = FALSE; } freeEntityList(list); self->thinkTime = 30; self->action = &teleportAway; } } if (player.y >= getMapMaxY()) { self->thinkTime = 5; self->mental = 2; } checkToMap(self); }
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 beamWait() { int i, x, startX, floor; Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { if (self->mental == 1) { self->thinkTime = 60; setEntityAnimation(self, "STAND_RED"); self->action = &redBeamWait; } else { i = 0; floor = getMapFloor(self->head->x + self->head->w / 2, self->head->y); /* Left side of beam */ x = self->x; startX = getMapStartX(); for (;x>=startX;) { e = getFreeEntity(); loadProperties("boss/azriel_ground_spikes", e); e->head = self; e->x = x - e->w; e->y = floor; e->startY = e->y - e->h; e->endY = e->y; e->action = &spikeRise; e->draw = &drawLoopingAnimationToMap; e->touch = &entityTouch; e->face = RIGHT; e->type = ENEMY; e->thinkTime = prand() % 30; x = e->x; i++; } /* Right side of beam */ x = self->x + self->w; startX = getMapStartX() + SCREEN_WIDTH; for (;x<startX;) { e = getFreeEntity(); loadProperties("boss/azriel_ground_spikes", e); e->head = self; e->x = x; e->y = floor; e->startY = e->y - e->h; e->endY = e->y; e->action = &spikeRise; e->draw = &drawLoopingAnimationToMap; e->touch = &entityTouch; e->face = RIGHT; e->type = ENEMY; e->thinkTime = prand() % 30; x = e->x + e->w; i++; } self->mental = i; self->thinkTime = 30; self->action = &beamFinish; } } }
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 entityWait() { int x1, y1, x2, y2, w1, h1, w2, h2; EntityList *el, *entities; Entity *other; if (self->dirX > 0) { self->endX = getMapRight(self->startX, self->startY); self->box.w = self->endX - self->x; } else if (self->dirX < 0) { self->x = getMapLeft(self->startX, self->startY); self->box.w = self->startX - self->x; } if (self->dirY > 0) { self->endY = getMapFloor(self->startX, self->startY); self->box.h = self->endY - self->y; } else if (self->dirY < 0) { self->y = getMapCeiling(self->startX, self->startY); self->box.h = self->startY - self->y; } entities = getEntities(); for (el=entities->next;el!=NULL;el=el->next) { other = el->entity; if (other->inUse == TRUE && (other->type == MANUAL_DOOR || other->type == AUTO_DOOR || other->type == WEAK_WALL)) { x1 = self->x + self->box.x; y1 = self->y + self->box.y; w1 = self->box.w; h1 = self->box.h; x2 = other->x + other->box.x; y2 = other->y + other->box.y; w2 = other->box.w; h2 = other->box.h; if (collision(x1, y1, w1, h1, x2, y2, w2, h2) == TRUE) { if (self->dirX > 0) { self->endX = other->x; self->box.w = self->endX - self->x; } else if (self->dirX < 0) { self->x = other->x + other->w; self->box.w = self->startX - self->x; } if (self->dirY > 0) { self->endY = other->y; self->box.h = self->endY - self->y; } else if (self->dirY < 0) { self->y = other->y + other->h; self->box.h = self->startY - self->y; } } } } }
static void init() { self->endY = getMapFloor(self->x, self->y) - self->y; self->action = strcmpignorecase("enemy/blue_scanner", self->name) == 0 ? &closedEyeMove : &lookForPlayer; }
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->mental--; if (self->mental <= 0) { self->thinkTime = 60; self->action = &attackFinished; } else { self->thinkTime = 30; } } hover(); }
static void disintegrationAttack() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { if (self->mental == 0) { self->y = getMapFloor(self->x + self->w / 2, self->y) - self->h; self->flags &= ~NO_DRAW; addParticleExplosion(self->x + self->w / 2, self->y + self->h / 2); self->mental = 1; self->thinkTime = 30; } else { e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add the Disintegration Spell"); } setEntityAnimation(self, "ATTACK_2"); loadProperties("boss/sorceror_disintegration_spell", e); setEntityAnimation(e, "STAND"); e->face = self->face; 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->action = &disintegrationSpellInit; e->thinkTime = 120; e->startX = e->x; e->startY = e->y; e->head = self; e->endX = player.x + player.w / 2; e->endY = player.y + player.h / 2; e->draw = &drawLoopingAnimationToMap; self->mental = 1; self->action = &disintegrationAttackWait; self->thinkTime = 30; } } }
static void lightningCageWait() { int i, middle; Entity *e; 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; middle = 0; e = NULL; if (self->head->mental == 1) { if (self->mental == 0) { self->endY = getMapFloor(self->x + self->w / 2, self->y); for (i=self->y;i<self->endY;i+=32) { e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add lightning"); } loadProperties("enemy/lightning", e); setEntityAnimation(e, "STAND"); if (i == self->startY) { middle = self->targetX + self->w / 2 - e->w / 2; } e->x = middle; e->y = i; e->action = &cageLightningWait; e->draw = &drawLoopingAnimationToMap; e->touch = &entityTouch; e->head = self; e->currentFrame = prand() % 6; e->face = RIGHT; e->thinkTime = 15; } e->mental = 1; self->mental = 1; if (self->face == LEFT) { self->targetX = playSoundToMap("sound/boss/azriel/azriel_lightning_cage", -1, self->x, self->y, -1); } } } else if (self->head->mental == 2) { if (self->face == LEFT) { stopSound(self->targetX); } self->inUse = FALSE; } }
static void riftAttack() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { if (self->mental == 0) { self->y = getMapFloor(self->x + self->w / 2, self->y) - self->h; self->flags &= ~NO_DRAW; addParticleExplosion(self->x + self->w / 2, self->y + self->h / 2); self->mental = 1; self->thinkTime = 60; } else { setEntityAnimation(self, "ATTACK_1"); e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add an Energy Rift"); } loadProperties("enemy/energy_rift", e); e->damage = 1; e->action = &riftMove; e->touch = &entityTouch; e->draw = &drawLoopingAnimationToMap; e->type = ENEMY; setEntityAnimation(e, "STAND"); if (self->face == LEFT) { e->x = self->x - e->w; } else { e->x = self->x + self->w; } e->thinkTime = 15; e->y = self->y; e->dirX = self->face == LEFT ? -e->speed : e->speed; e->head = self; e->targetX = getMapStartX() + SCREEN_WIDTH / 2 - e->w / 2; e->targetY = e->y; e->health = 0; playSoundToMap("sound/common/spell", -1, self->x, self->y, 0); self->mental = -1; self->action = &riftAttackWait; self->thinkTime = 60; } } checkToMap(self); }