static int textAlreadyAdded(char *text) { int i; char *clean; if (strcmpignorecase("msgid \"\"", text) == 0) { return TRUE; } clean = replaceString(text, "msgid \"", ""); clean[strlen(clean) - 1] = '\0'; clean = replaceString(clean, "\\", ""); clean = replaceString(clean, "\\", ""); for (i=0;i<poIndex;i++) { if (strcmpignorecase(added[i], text) == 0) { return TRUE; } } if (checkExists(clean) == FALSE) { return TRUE; } STRNCPY(added[poIndex], text, MAX_LINE_LENGTH); poIndex++; return FALSE; }
static char *getSongName(char *name, int oldSong) { int i; if (oldSong == 1) { for (i=0; i<musicTracksLength; i+=2) { if (strcmpignorecase(name, oldMusicTracks[i]) == 0) { return oldMusicTracks[i + 1]; } } } else { for (i=0; i<musicTracksLength; i+=2) { if (strcmpignorecase(name, newMusicTracks[i]) == 0) { return newMusicTracks[i + 1]; } } } printf("Could not match song: %s\n", name); return NULL; }
static void activate(int val) { EntityList *el, *entities; Entity *temp; entities = getEntities(); if (game.status == IN_GAME) { playSoundToMap("sound/item/tuning_fork", EDGAR_CHANNEL, self->x, self->y, 0); for (el=entities->next;el!=NULL;el=el->next) { if (el->entity->inUse == TRUE) { if ((strcmpignorecase(el->entity->requires, "TUNING_FORK") == 0 && getDistanceFromPlayer(el->entity) < 128) || (strcmpignorecase(el->entity->requires, "BOSS_TUNING_FORK") == 0)) { temp = self; self = el->entity; self->activate(100); self = temp; } } } } }
Entity *addLargeSpider(int x, int y, char *name) { Entity *e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add a Large Spider"); } loadProperties(name, e); e->x = x; e->y = y; e->action = strcmpignorecase(name, "enemy/large_red_spider") == 0 ? &redLookForPlayer : &lookForPlayer; e->resumeNormalFunction = strcmpignorecase(name, "enemy/large_red_spider") == 0 ? &redLookForPlayer : &lookForPlayer; e->draw = &drawLoopingAnimationToMap; e->die = ¨ e->touch = &touch; e->takeDamage = &takeDamage; e->reactToBlock = &changeDirection; e->creditsAction = &creditsMove; e->type = ENEMY; setEntityAnimation(e, "STAND"); return e; }
Entity *addLargeBook(int x, int y, char *name) { Entity *e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add a Book"); } loadProperties(name, e); e->x = x; e->y = y; e->draw = &drawLoopingAnimationToMap; e->touch = &entityTouch; e->takeDamage = &takeDamage; if (strcmpignorecase(name, "enemy/large_red_book") == 0) { e->action = &redWait; e->die = &redDieInit; e->creditsAction = &creditsMove; } else if (strcmpignorecase(name, "enemy/large_blue_book") == 0) { e->action = &blueWait; e->die = &blueDieInit; e->creditsAction = &creditsMove; } else if (strcmpignorecase(name, "enemy/large_yellow_book") == 0) { e->action = &yellowWait; e->die = &yellowDieInit; e->creditsAction = &creditsMove; } else { e->action = &greenWait; e->die = &greenDieInit; e->creditsAction = &greenCreditsMove; } e->type = ENEMY; setEntityAnimation(e, "STAND"); return e; }
int removeInventoryItemByObjectiveName(char *name) { int i, found; Entity *e; found = FALSE; for (i=0;i<MAX_INVENTORY_ITEMS;i++) { if (inventory.item[i].inUse == TRUE && strcmpignorecase(inventory.item[i].objectiveName, name) == 0) { if (inventory.item[i].flags & STACKABLE) { inventory.item[i].health--; if (inventory.item[i].health <= 0) { inventory.item[i].inUse = FALSE; } } else { inventory.item[i].inUse = FALSE; if (strcmpignorecase(playerWeapon.name, inventory.item[i].name) == 0) { e = removePlayerWeapon(); e->inUse = FALSE; } else if (strcmpignorecase(playerShield.name, inventory.item[i].name) == 0) { e = removePlayerShield(); e->inUse = FALSE; } } found = TRUE; break; } } if (found == TRUE) { sortInventory(); } return found; }
void addMapTriggerFromResource(char *key[], char *value[]) { int i, triggerName, count, targetType, targetName, total; total = triggerName = count = targetType = targetName = -1; for (i=0;i<MAX_PROPS_FILES;i++) { if (strcmpignorecase("TRIGGER_NAME", key[i]) == 0) { triggerName = i; } else if (strcmpignorecase("TRIGGER_COUNT", key[i]) == 0) { count = i; } else if (strcmpignorecase("TRIGGER_TOTAL", key[i]) == 0) { total = i; } else if (strcmpignorecase("TRIGGER_TYPE", key[i]) == 0) { targetType = i; } else if (strcmpignorecase("TRIGGER_TARGET", key[i]) == 0) { targetName = i; } } if (total == -1 && count != -1) { total = count; count = 0; } if (triggerName == -1 || count == -1 || targetType == -1 || targetName == -1 || total == -1) { showErrorAndExit("Map Trigger is missing resources"); } addMapTrigger(value[triggerName], atoi(value[count]), atoi(value[total]), getTriggerTypeByName(value[targetType]), value[targetName]); }
Entity *addDoor(char *name, int x, int y, int type) { Entity *e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add a Door"); } loadProperties(strcmpignorecase(name, "common/wooden_door") == 0 ? "door/metal_door" : name, e); e->x = x; e->y = y; e->type = type; e->draw = &drawLoopingAnimationToMap; e->touch = &touch; e->action = &setStart; e->flags |= OBSTACLE; setEntityAnimation(e, "STAND"); return e; }
static void die() { Entity *e; if ((prand() % 3 == 0) && isSpaceEmpty(self) == NULL) { /* Drop a shell */ setEntityAnimation(self, "WALK"); if (strcmpignorecase(self->name, "enemy/purple_snail") == 0) { e = addSnailShell(self->x, self->y, "enemy/purple_snail_shell"); } else { e = addSnailShell(self->x, self->y, "enemy/snail_shell"); } e->face = self->face; e->x += (self->w - e->w) / 2; } playSoundToMap("sound/enemy/snail/snail_die", -1, self->x, self->y, 0); entityDie(); }
static void fireballTouch(Entity *other) { Entity *temp; /* Projectiles will cancel each other out */ if (other->dirX != self->dirX && strcmpignorecase(self->name, other->name) == 0) { if (self->inUse == FALSE || other->inUse == FALSE) { return; } self->inUse = FALSE; other->inUse = FALSE; } else if (self->parent != other && other->takeDamage != NULL) { temp = self; self = other; self->takeDamage(temp, self->type == ENEMY ? 50 : temp->damage); self = temp; self->inUse = FALSE; } }
static int compare(const void *a, const void *b) { char* aa = *(char**)a; char* bb = *(char**)b; return strcmpignorecase(aa, bb); }
void activateEntitiesValueWithObjectiveName(char *name, int value) { EntityList *el; Entity *temp; for (el=entities->next;el!=NULL;el=el->next) { if (el->entity->inUse == TRUE && el->entity->activate != NULL && strcmpignorecase(el->entity->objectiveName, name) == 0) { temp = self; self = el->entity; if (self->type == MANUAL_LIFT && self->active == FALSE) { setInfoBoxMessage(90, 255, 255, 255, _("This lift is not active")); } else { self->activate(value - self->health); } self = temp; } } }
static void preCacheSound(char *name) { int i; Mix_Chunk *chunk = NULL; for (i=0;i<soundIndex;i++) { if (strcmpignorecase(sound[i].name, name) == 0) { return; } } if (soundIndex == MAX_SOUNDS) { showErrorAndExit("Ran out of space for sounds"); } chunk = loadSound(name); sound[soundIndex].effect = chunk; STRNCPY(sound[soundIndex].name, name, sizeof(sound[soundIndex].name)); soundIndex++; }
Entity *addGlassWall(int x, int y, char *name) { Entity *e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add a Glass Wall"); } loadProperties(name, e); e->x = x; e->y = y; e->type = KEY_ITEM; e->face = RIGHT; e->action = strcmpignorecase(name, "item/horizontal_glass_wall") == 0 ? &horizontalGlassWait : &glassWait; e->touch = &pushEntity; e->activate = &activate; e->takeDamage = &takeDamage; e->draw = &drawLoopingAnimationToMap; e->active = FALSE; setEntityAnimation(e, "STAND"); return e; }
Entity *addScanner(int x, int y, char *name) { Entity *e = getFreeEntity(); if (e == NULL) { showErrorAndExit("No free slots to add a Scanner"); } loadProperties(name, e); e->x = x; e->y = y; e->action = &init; e->draw = &drawLoopingAnimationToMap; e->creditsAction = strcmpignorecase("enemy/blue_scanner", e->name) == 0 ? &blueCreditsMove : &creditsMove; e->type = ENEMY; setEntityAnimation(e, "STAND"); return e; }
static void becomeTransparent() { if (strcmpignorecase(self->name, "boss/azriel") != 0) { printf("%s cannot become transparent!\n", self->name); exit(1); } self->endX--; if (self->endX <= 0) { if (self->alpha > 128) { self->alpha--; self->endX = 3; } else { self->alpha = 128; self->endX = 0; } } }
static void finishEating() { self->target->health--; setEntityAnimation(self, "STAND"); if (self->target->health <= 0) { self->target->inUse = FALSE; self->target = NULL; self->action = &lookForFood; self->thinkTime = 0; self->mental = 0; } else { if (strcmpignorecase(self->target->name, "item/chicken_feed") == 0) { self->target->thinkTime = 600; self->target->flags &= ~NO_DRAW; } self->action = &doNothing; setEntityAnimation(self, "ATTACK_1"); self->animationCallback = &finishEating; } }
static void iceBlockDrop() { if (self->standingOn != NULL && strcmpignorecase(self->name, self->standingOn->name) == 0) { self->standingOn->action = self->standingOn->die; } self->thinkTime--; if (self->thinkTime <= 0 && (self->flags & FLY)) { self->flags &= ~FLY; self->thinkTime = 300; } if (self->flags & ON_GROUND) { self->touch = &iceBlockTouch; self->takeDamage = &iceBlockTakeDamage; if (self->thinkTime <= 0) { self->die(); } } checkToMap(self); }
static void soulTouch(Entity *other) { if (self->health == 1 && other->type == PLAYER) { if (self->target != NULL) { self->target->inUse = FALSE; } keyItemTouch(other); } else if (self->health == 1 && strcmpignorecase(other->name, "enemy/spirit") == 0) { self->touch = NULL; self->action = &bottleFill; self->activate = NULL; fireTrigger(other->objectiveName); other->target = self; other->action = other->die; self->mental = 11; playSoundToMap("sound/enemy/spirit/spirit_explode", -1, self->x, self->y, 0); self->endX = playSoundToMap("sound/enemy/spirit/spirit_scream", -1, self->x, self->y, 0); } }
Entity *addEnemy(char *name, int x, int y) { int i; Entity *e; for (i=0;i<length;i++) { if (strcmpignorecase(enemies[i].name, name) == 0) { e = enemies[i].construct(x, y, name); if (e->fallout == NULL) { e->fallout = &entityDieNoDrop; } if (e->pain == NULL) { e->pain = &enemyPain; } e->originalWeight = e->weight; return e; } } showErrorAndExit("Could not find enemy %s", name); return NULL; }
static void init() { if (strcmpignorecase(self->name, "enemy/red_spider") == 0) { if (self->health > 20) { setEntityAnimation(self, "PURPLE"); } else if (self->health > 10) { setEntityAnimation(self, "BLUE"); } } if (self->y == self->startY) { self->targetY = self->endY; } else { self->targetY = self->weight == 2 ? self->endY : self->startY; } self->action = &move; }
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 takeDamage(Entity *other, int damage) { Entity *temp; if (!(self->flags & INVULNERABLE)) { if (strcmpignorecase(other->name, "weapon/wood_axe") == 0) { playSoundToMap("sound/item/chop", -1, self->x, self->y, 0); self->health -= damage; if (self->health > 0) { setCustomAction(self, &flashWhite, 6, 0, 0); } else { if (self->mental > 0) { self->health = self->maxHealth; self->mental--; } else { setInfoBoxMessage(60, 255, 255, 255, _("It's out of apples...")); } } } else { playSoundToMap("sound/common/dink", -1, self->x, self->y, 0); if (other->reactToBlock != NULL) { temp = self; self = other; self->reactToBlock(temp); self = temp; } damage = 0; if (other->type != PROJECTILE && prand() % 10 == 0) { setInfoBoxMessage(60, 255, 255, 255, _("This weapon is not having any effect...")); } } setCustomAction(self, &invulnerableNoFlash, HIT_INVULNERABLE_TIME, 0, 0); } }
static void touch(Entity *other) { float dirX, dirY; if (self->active == FALSE && other->type == PLAYER) { setInfoBoxMessage(0, 255, 255, 255, _("Press Action to interact")); } else if (self->health == 1 && fabs(self->x - other->x) <= fabs(self->dirX) && fabs(self->y - other->y) <= fabs(self->dirY)) { if (strcmpignorecase(other->name, "item/robot_direction") == 0) { dirY = dirX = 0; switch (other->health) { case 0: dirY = -self->speed; setEntityAnimation(self, "JUMP"); break; case 1: dirY = self->speed; setEntityAnimation(self, "JUMP"); break; case 2: dirX = -self->speed; setEntityAnimation(self, "WALK"); self->face = LEFT; break; default: dirX = self->speed; setEntityAnimation(self, "WALK"); self->face = RIGHT; break; } if (dirY != self->dirY || dirX != self->dirX) { self->x = other->x; self->y = other->y; } self->dirY = dirY; self->dirX = dirX; } } }
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 playSound(char *name) { int i; Mix_Chunk *chunk = NULL; if (game.audio == FALSE || game.sfxDefaultVolume == 0) { return; } for (i=0;i<soundIndex;i++) { if (strcmpignorecase(sound[i].name, name) == 0) { chunk = sound[i].effect; if (chunk == NULL) { return; } break; } } if (chunk == NULL) { if (soundIndex == MAX_SOUNDS) { showErrorAndExit("Ran out of space for sounds"); } chunk = loadSound(name); sound[soundIndex].effect = chunk; STRNCPY(sound[soundIndex].name, name, sizeof(sound[soundIndex].name)); soundIndex++; if (chunk == NULL) { return; } } Mix_VolumeChunk(chunk, game.sfxDefaultVolume * VOLUME_STEPS); #if DEV == 1 if (game.gameType == REPLAYING) { printf("%f %s\n", (float)game.frames / 60, name); } #endif playSoundChunk(chunk, -1, 0); }
void iceBlockTakeDamage(Entity *other, int damage) { Entity *temp; if (self->flags & INVULNERABLE) { return; } if (strcmpignorecase(other->name, "weapon/pickaxe") == 0) { self->damage = 0; self->die(); } else if (damage != 0) { self->health -= damage; if (other->type == PROJECTILE) { temp = self; self = other; self->die(); self = temp; } if (self->health > 0) { setCustomAction(self, &flashWhite, 6, 0, 0); /* Don't make an enemy invulnerable from a projectile hit, allows multiple hits */ if (other->type != PROJECTILE) { setCustomAction(self, &invulnerableNoFlash, HIT_INVULNERABLE_TIME, 0, 0); } if (self->pain != NULL) { self->pain(); } } else { self->damage = 0; self->die(); } } }
static void validate() { int allStatues, orderCorrect; EntityList *list = getEntitiesByName(self->name); EntityList *l; Entity *e; allStatues = TRUE; orderCorrect = TRUE; for (l=list->next;l!=NULL;l=l->next) { e = l->entity; if (e->target == NULL) { allStatues = FALSE; break; } else if (strcmpignorecase(e->requires, e->target->objectiveName) != 0) { orderCorrect = FALSE; } } if (allStatues == TRUE) { if (orderCorrect == TRUE) { for (l=list->next;l!=NULL;l=l->next) { e = l->entity; e->active = FALSE; e->activate = NULL; } fireTrigger(self->name); fireGlobalTrigger(self->name); addMedal("occult"); } else { runScript("wrong_order"); } } freeEntityList(list); }
int hasPersistance(char *mapName) { int val = FALSE; char *line, itemName[MAX_MESSAGE_LENGTH], *savePtr; unsigned char *buffer; FILE *read; savePtr = NULL; snprintf(itemName, sizeof(itemName), "MAP_NAME %s", mapName); read = fopen(tempFile, "rb"); if (read == NULL) { if (temporaryDataExists == TRUE) { showErrorAndExit("HAS PERSISTANCE: Could not find persistance file: %s", strerror(errno)); } return val; } fclose(read); buffer = decompressFile(tempFile); line = strtok_r((char *)buffer, "\n", &savePtr); while (line != NULL) { if (line[strlen(line) - 1] == '\n') { line[strlen(line) - 1] = '\0'; } if (line[strlen(line) - 1] == '\r') { line[strlen(line) - 1] = '\0'; } if (strcmpignorecase(line, itemName) == 0) { val = TRUE; break; } line = strtok_r(NULL, "\n", &savePtr); } free(buffer); return val; }
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); } }