static void die() { int i; Entity *e; if (strcmpignorecase(self->name, "item/horizontal_glass_wall") == 0) { for (i=0;i<7;i++) { e = addTemporaryItem("item/horizontal_glass_wall_piece", self->x, self->y, RIGHT, 0, 0); e->x += self->w / 2 - e->w / 2; e->y += self->h / 2 - e->h / 2; e->dirX = (prand() % 10) * (prand() % 2 == 0 ? -1 : 1); e->dirY = ITEM_JUMP_HEIGHT + (prand() % ITEM_JUMP_HEIGHT); setEntityAnimationByID(e, i); e->thinkTime = 60 + (prand() % 60); } self->flags |= NO_DRAW; self->touch = NULL; self->action = &respawnWait; self->thinkTime = 300; } else { for (i=0;i<7;i++) { e = addTemporaryItem("item/glass_wall_piece", self->x, self->y, RIGHT, 0, 0); e->x += self->w / 2 - e->w / 2; e->y += self->h / 2 - e->h / 2; e->dirX = (prand() % 10) * (prand() % 2 == 0 ? -1 : 1); e->dirY = ITEM_JUMP_HEIGHT + (prand() % ITEM_JUMP_HEIGHT); setEntityAnimationByID(e, i); e->thinkTime = 60 + (prand() % 60); } self->inUse = FALSE; fireTrigger(self->objectiveName); fireGlobalTrigger(self->objectiveName); } }
static void generateSolution() { int i; char c[2]; Entity *e; for (i=0;i<4;i++) { snprintf(c, 2, "%ld", 1 + prand() % self->health); self->requires[i] = c[0]; } self->requires[i] = '\0'; e = self->target; while (e != NULL) { e->health = 0; setEntityAnimationByID(e, e->health); e = e->target; } self->endX = self->x; self->endY = self->y + self->h - TILE_SIZE; }
static void init() { if (self->active == TRUE) { setEntityAnimationByID(self, self->health); } else if (self->active == FALSE && self->health < 0) { setEntityAnimationByID(self, -self->health); self->frameSpeed = 0; } self->action = &entityWait; }
static void iceBlockDie() { int i; Entity *e; for (i=0;i<8;i++) { e = addTemporaryItem("common/ice_piece", self->x, self->y, RIGHT, 0, 0); e->x += self->w / 2 - e->w / 2; e->y += self->h / 2 - e->h / 2; e->dirX = (prand() % 10) * (prand() % 2 == 0 ? -1 : 1); e->dirY = ITEM_JUMP_HEIGHT + (prand() % ITEM_JUMP_HEIGHT); setEntityAnimationByID(e, i); e->thinkTime = 60 + (prand() % 60); e->touch = NULL; } playSoundToMap("sound/common/shatter", -1, player.x, player.y, 0); self->inUse = FALSE; }
void scriptAddToInventory(char *name, int quiet) { int i; Entity *e; e = addPermanentItem(name, 0, 0); for (i=0;i<MAX_INVENTORY_ITEMS;i++) { if (inventory.item[i].inUse == FALSE) { inventory.item[i] = *e; inventory.item[i].face = RIGHT; inventory.item[i].thinkTime = 0; setEntityAnimationByID(&inventory.item[i], 0); if (quiet == FALSE) { setInfoBoxMessage(60, 255, 255, 255, _("Picked up %s"), _(inventory.item[i].objectiveName)); } break; } } e->inUse = FALSE; }
static void entityWait() { int i; Entity *e; if (self->mental == 1) { for (i=0; i<4; i++) { e = addTemporaryItem("boss/azriel_grave_piece", self->x, self->y, RIGHT, 0, 0); e->x += self->w / 2 - e->w / 2; e->y += self->h / 2 - e->h / 2; e->dirX = (prand() % 10) * (prand() % 2 == 0 ? -1 : 1); e->dirY = ITEM_JUMP_HEIGHT + (prand() % ITEM_JUMP_HEIGHT); setEntityAnimationByID(e, i); e->thinkTime = 60 + (prand() % 60); } playSoundToMap("sound/common/crumble", -1, self->x, self->y, 0); self->inUse = FALSE; } checkToMap(self); }
static void displayInputCode() { self->thinkTime--; if (self->thinkTime <= 0) { self->thinkTime = self->maxThinkTime; self->target->health = (int)self->target->requires[self->mental]; setEntityAnimationByID(self->target, self->target->health); if (self->mental == strlen(self->target->requires)) { self->mental = 0; self->action = &readInputCode; } else { playSoundToMap("sound/item/charge_beep", -1, self->x, self->y, 0); self->mental++; self->action = &clearInputCode; } } }
static void glassWait() { if (self->active == TRUE) { if ((self->thinkTime % 60) == 0) { self->mental++; setEntityAnimationByID(self, self->mental); playSoundToMap("sound/item/crack", -1, self->x, self->y, 0); } self->thinkTime--; if (self->mental == 5) { playSoundToMap("sound/common/shatter", -1, self->x, self->y, 0); self->action = ¨ } } checkToMap(self); }
static void spellMove() { int i; Entity *e; checkToMap(self); self->thinkTime--; if (self->thinkTime <= 0) { self->inUse = FALSE; } else { for (i=0;i<2;i++) { e = addBasicDecoration(self->x, self->y, "decoration/particle"); if (e != NULL) { e->x += prand() % self->w; e->y += prand() % self->h; e->thinkTime = 5 + prand() % 30; setEntityAnimationByID(e, prand() % 5); } } } }
Entity *addParticle(int x, int y) { Entity *e; e = getFreeDecoration(); if (e == NULL) { return NULL; } loadProperties("decoration/particle", e); e->thinkTime = 20 + (prand() % 30); e->x = x; e->y = y; e->action = &move; e->draw = &drawLoopingAnimationToMap; setEntityAnimationByID(e, prand() % 5); return e; }
static void shieldWait() { int i; float radians; Entity *e; if (self->head->flags & NO_DRAW) { self->flags |= NO_DRAW; } else { self->flags &= ~NO_DRAW; } self->x = self->head->x + self->head->w / 2 - self->w / 2; self->y = self->head->y + self->head->h / 2 - self->h / 2; self->thinkTime += 5; radians = DEG_TO_RAD(self->thinkTime); self->alpha = 128 + (64 * cos(radians)); if (self->maxHealth != self->head->health) { self->die(); for (i=0;i<8;i++) { e = addTemporaryItem("boss/sorceror_staff_piece", self->x, self->y, self->face, 0, 0); setEntityAnimationByID(e, i == 0 ? 0 : 1); e->x += (self->head->w - e->w) / 2; e->y += (self->head->h - e->h) / 2; e->dirX = (prand() % 10) * (prand() % 2 == 0 ? -1 : 1); e->dirY = ITEM_JUMP_HEIGHT + (prand() % ITEM_JUMP_HEIGHT); setEntityAnimationByID(e, i == 0 ? 0 : 1); e->thinkTime = 180 + (prand() % 60); } } }
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 horizontalGlassWait() { if (self->active == TRUE) { if (self->mental < 3) { self->mental++; setEntityAnimationByID(self, self->mental); self->active = FALSE; playSoundToMap("sound/item/crack", -1, self->x, self->y, 0); if (self->mental == 3) { STRNCPY(self->objectiveName, self->requires, sizeof(self->objectiveName)); STRNCPY(self->requires, "BOSS_TUNING_FORK", sizeof(self->requires)); } } else { self->thinkTime++; if ((self->thinkTime % 180) == 0) { self->mental++; setEntityAnimationByID(self, self->mental); playSoundToMap("sound/item/crack", -1, self->x, self->y, 0); } if (self->mental == 4) { playSoundToMap("sound/common/shatter", -1, self->x, self->y, 0); self->action = ¨ } } } checkToMap(self); }
static int checkSolution() { int i, total; char solution[6], c[2]; Entity *e; e = self->target; while (e != NULL) { if (e->y == self->endY && e->x == self->x) { break; } e = e->target; } if (e == NULL) { showErrorAndExit("Could not find starting peg for row"); } for (i=0;i<4;i++) { if (e->health == 0) { setInfoBoxMessage(180, 255, 255, 255, _("Select a colour for every peg in the row")); return -1; } snprintf(c, 2, "%d", e->health); solution[i] = c[0]; e = e->target; } solution[i] = '\0'; total = 0; for (i=0;i<4;i++) { if (solution[i] == self->requires[i]) { total++; } } e->health = total + 1; setEntityAnimationByID(e, e->health); return strcmpignorecase(solution, self->requires) == 0 ? TRUE : FALSE; }
void doTeleport() { int i; float speed; Entity *e; if (abs(self->x - self->targetX) < TELEPORT_SPEED && abs(self->y - self->targetY) < TELEPORT_SPEED) { self->flags &= ~(NO_DRAW|HELPLESS|TELEPORTING); self->x = self->targetX; self->y = self->targetY; addParticleExplosion(self->x + self->w / 2, self->y + self->h / 2); self->dirY = self->dirX = 0; self->standingOn = NULL; if (!(self->flags & NO_END_TELEPORT_SOUND)) { playSoundToMap("sound/common/teleport", -1, self->x, self->y, 0); } } else { self->flags |= NO_DRAW|HELPLESS|INVULNERABLE; speed = getDistance(self->x, self->y, self->targetX, self->targetY) / 20; speed = speed < TELEPORT_SPEED ? TELEPORT_SPEED : (speed > 30 ? 30 : speed); normalize(&self->dirX, &self->dirY); self->dirX *= speed; self->dirY *= speed; self->x += self->dirX; self->y += self->dirY; for (i=0;i<5;i++) { e = addBasicDecoration(self->x, self->y, "decoration/particle"); if (e != NULL) { e->x += prand() % self->w; e->y += prand() % self->h; e->thinkTime = 5 + prand() % 30; setEntityAnimationByID(e, prand() % 5); } } } }
Entity *addProjectile(char *name, Entity *owner, int x, int y, float dirX, float dirY) { Entity *e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add a projectile"); } loadProperties(name, e); e->flags &= ~PLAYER_TOUCH_ONLY; e->x = x; e->y = y; e->dirX = dirX; e->dirY = dirY; e->action = &projectileMove; e->draw = &drawLoopingAnimationToMap; e->touch = &entityTouch; e->type = PROJECTILE; e->fallout = &removeProjectile; e->creditsAction = &projectileMove; e->parent = owner; if (e->thinkTime == 0) { showErrorAndExit("No valid thinktime defined for %s", name); } if (hasEntityAnimation(e, "DIE") == TRUE) { e->die = &projectileDie; } else { e->die = &removeProjectile; } e->face = e->dirX > 0 ? RIGHT : LEFT; setEntityAnimationByID(e, 0); e->flags |= ATTACKING; return e; }
static void finalSpellWait() { Entity *e; self->thinkTime--; if (self->thinkTime <= 0) { self->mental++; if (self->mental >= 9) { self->mental = 9; } setEntityAnimationByID(self, self->mental); self->thinkTime = 60; } if (self->head->mental == 3 || self->health != self->head->health) { self->inUse = FALSE; } else { e = addPixelDecoration(self->x, self->y); if (e != NULL) { e->x = self->x + (prand() % 32) * (prand() % 2 == 0 ? -1 : 1) + self->w / 2; e->y = self->y + (prand() % 32) * (prand() % 2 == 0 ? -1 : 1) + self->h / 2; e->startX = e->x; e->startY = e->y; e->endX = self->x + self->w / 2; e->endY = self->y + self->h / 2; e->thinkTime = 15; e->health = 0; e->maxHealth = 255; e->mental = 0; calculatePath(e->startX, e->startY, e->endX, e->endY, &e->dirX, &e->dirY); } } self->x = self->head->x + self->offsetX; self->y = self->head->y + self->offsetY; }
static void pegInit() { setEntityAnimationByID(self, self->health); self->mental = 0; self->action = &entityWait; self->flags &= ~DO_NOT_PERSIST; }
static void clearInputCode() { self->thinkTime--; if (self->thinkTime <= 0) { setEntityAnimationByID(self->target, 0); self->thinkTime = self->mental > strlen(self->target->requires) ? 0 : self->maxThinkTime; self->action = &displayInputCode; } }
static void phantasmalBoltMoveToTarget() { Entity *e; if (atTarget()) { setEntityAnimation(self, "PHANTASMAL_BOLT_READY"); e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add Azriel's Phantasmal Bolt"); } loadProperties("boss/azriel_phantasmal_bolt", e); setEntityAnimationByID(e, 0); e->face = self->face; if (e->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 = &phantasmalBoltWait; e->draw = &drawLoopingAnimationToMap; e->thinkTime = 30; e->head = self; self->mental = 1; self->action = &phantasmalBolt; } checkToMap(self); becomeTransparent(); }
static void die() { int i; Entity *e; char name[MAX_VALUE_LENGTH]; playSoundToMap("sound/common/crumble", -1, self->x, self->y, 0); snprintf(name, sizeof(name), "%s_piece", self->name); fireTrigger(self->objectiveName); fireGlobalTrigger(self->objectiveName); for (i=0;i<9;i++) { e = addTemporaryItem(name, self->x, self->y, self->face, 0, 0); e->x += (self->w - e->w) / 2; e->y += (self->w - e->w) / 2; e->dirX = (prand() % 5) * (prand() % 2 == 0 ? -1 : 1); e->dirY = ITEM_JUMP_HEIGHT + (prand() % ITEM_JUMP_HEIGHT); setEntityAnimationByID(e, i); e->thinkTime = 60 + (prand() % 180); } self->damage = 0; if (!(self->flags & INVULNERABLE)) { self->touch = &entityTouch; self->flags &= ~FLY; self->flags |= (DO_NOT_PERSIST|NO_DRAW); self->thinkTime = 60; setCustomAction(self, &invulnerableNoFlash, 240, 0, 0); self->frameSpeed = 0; self->action = &standardDie; self->damage = 0; } }
static void entityWait() { if (self->maxHealth != self->health) { self->thinkTime--; if (self->thinkTime <= 0) { self->health += (self->maxThinkTime == 1 ? 1 : -1); setEntityAnimationByID(self, self->health); if (self->health == self->maxHealth || self->health == 0) { if (self->health == 14) { activateEntitiesWithRequiredName(self->objectiveName, TRUE); playSoundToMap("sound/item/striker_top", -1, self->x, self->y, 0); } else { self->maxHealth = 0; self->thinkTime = 90; if (self->health == 0) { self->maxThinkTime = 0; self->thinkTime = 0; } else { self->maxThinkTime = self->maxThinkTime == 1 ? -1 : 1; } } } else { self->thinkTime = 4; } } } checkToMap(self); }
static void touch(Entity *other) { Entity *e; pushEntity(other); if (other->standingOn == self) { if (self->thinkTime < 5) { playSoundToMap("sound/item/inflate", -1, self->x, self->y, 0); self->health++; } if (self->health == 3) { if (self->thinkTime < 5) { e = addBubble(self->x, self->y, "item/bubble"); e->x = self->face == LEFT ? getLeftEdge(self) : getRightEdge(self); e->x += self->face == LEFT ? -e->w : e->w; e->y = self->y + self->h / 2 - e->h / 2; e->dirX = self->face == LEFT ? -e->speed : e->speed; } self->thinkTime = 60; } else if (self->health > 3) { self->health = 3; self->thinkTime = 60; } else { self->thinkTime = 10; } setEntityAnimationByID(self, self->health + 3); } }
static void init() { if (self->health != 14) { self->health = self->maxHealth = 0; } else { setEntityAnimationByID(self, self->health); } self->maxThinkTime = self->thinkTime = 0; self->action = &entityWait; }
static void entityWait() { self->thinkTime--; if (self->thinkTime <= 0) { if (self->target != NULL) { setEntityAnimationByID(self->target, 0); } self->thinkTime = 0; } checkToMap(self); }
void loadInventoryItems() { int i, j; Entity e; for (i=0;i<MAX_INVENTORY_ITEMS;i++) { if (inventory.item[i].inUse == TRUE) { loadProperties(inventory.item[i].name, &e); inventory.item[i].fallout = &keyItemFallout; for (j=0;j<MAX_ANIMATION_TYPES;j++) { inventory.item[i].animation[j] = e.animation[j]; } inventory.item[i].currentAnim = -1; setEntityAnimationByID(&inventory.item[i], 0); if (inventory.item[i].type == WEAPON && strcmpignorecase(inventory.item[i].name, playerWeapon.name) == 0) { self = &inventory.item[i]; setPlayerWeapon(1); } else if (inventory.item[i].type == SHIELD && strcmpignorecase(inventory.item[i].name, playerShield.name) == 0) { self = &inventory.item[i]; setPlayerShield(1); } else if (inventory.item[i].type == TEMP_ITEM) { inventory.item[i].type = ITEM; inventory.item[i].action = &doNothing; inventory.item[i].flags &= ~DO_NOT_PERSIST; } } } }
static void init() { int i; Entity *e; for (i=0;i<self->mental;i++) { e = getFreeEntity(); loadProperties("item/tree_apple", e); e->type = ITEM; e->face = prand() % 2 == 0 ? LEFT : RIGHT; e->action = &appleWait; e->draw = &drawLoopingAnimationToMap; e->mental = i + 1; setEntityAnimationByID(e, i); e->x = self->x + e->offsetX; e->y = self->y + e->offsetY; e->dirX = 1 * (prand() % 2 == 0 ? -1 : 1); e->startX = e->x; e->thinkTime = prand() % 20; e->flags |= DO_NOT_PERSIST; e->head = self; } if (self->mental > 0) { self->activate = &activate; self->takeDamage = &takeDamage; } self->action = &entityWait; }
static void init() { Entity *e = getEntityByObjectiveName(self->requires); if (e == NULL) { showErrorAndExit("Balloon couldn't find target %s", self->requires); } self->face = RIGHT; self->target = e; self->target->flags |= HELPLESS; self->action = &hover; setEntityAnimationByID(self, self->mental); }
static void addSparkles() { Entity *e; e = addBasicDecoration(self->x, self->y, "decoration/particle"); if (e != NULL) { e->x += prand() % self->box.w; e->y += prand() % self->box.h; e->thinkTime = 5 + prand() % 30; setEntityAnimationByID(e, prand() % 5); e->dirX = 0; e->dirY = -2; } }
static void iceDrop() { int i; Entity *e; checkToMap(self); self->thinkTime--; if (self->thinkTime <= 0) { self->flags &= ~FLY; } if (self->flags & ON_GROUND) { playSoundToMap("sound/common/shatter", -1, self->x, self->y, 0); for (i=0;i<8;i++) { e = addTemporaryItem("misc/ice_spike_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->head->mental--; self->inUse = FALSE; } }