[BACK]Return to SeedCatalog.c CVS log [TXT][DIR] Up to [contributed] / brogue-ce / src / brogue

Annotation of brogue-ce/src/brogue/SeedCatalog.c, Revision 1.1

1.1     ! rubenllo    1: /*
        !             2:  *  SeedCatalog.c
        !             3:  *  Brogue
        !             4:  *
        !             5:  *  Copyright 2012. All rights reserved.
        !             6:  *
        !             7:  *  This file is part of Brogue.
        !             8:  *
        !             9:  *  This program is free software: you can redistribute it and/or modify
        !            10:  *  it under the terms of the GNU Affero General Public License as
        !            11:  *  published by the Free Software Foundation, either version 3 of the
        !            12:  *  License, or (at your option) any later version.
        !            13:  *
        !            14:  *  This program is distributed in the hope that it will be useful,
        !            15:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            16:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            17:  *  GNU Affero General Public License for more details.
        !            18:  *
        !            19:  *  You should have received a copy of the GNU Affero General Public License
        !            20:  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
        !            21:  */
        !            22:
        !            23: #include "Rogue.h"
        !            24: #include "IncludeGlobals.h"
        !            25:
        !            26: #define  CSV_HEADER_STRING "dungeon_version,seed,depth,quantity,category,kind,enchantment,runic,vault_number,opens_vault_number,carried_by_monster_name,ally_status_name,mutation_name"
        !            27: #define  NO_ENCHANTMENT_STRING ""
        !            28: #define  NO_RUNIC_STRING ""
        !            29: #define  NO_VAULT_STRING ""
        !            30: #define  NO_OPENS_VAULT_STRING ""
        !            31: #define  NO_CARRIED_BY_MONSTER_STRING ""
        !            32: #define  NO_ALLY_STATUS_STRING ""
        !            33: #define  NO_MUTATION_STRING ""
        !            34:
        !            35: static void printSeedCatalogCsvLine(unsigned long seed, short depth, short quantity, char categoryName[50], char kindName[50],
        !            36:                                     char enchantment[50], char runicName[50], char vaultNumber[10], char opensVaultNumber[10],
        !            37:                                     char carriedByMonsterName[50], char allyStatusName[20], char mutationName[100]){
        !            38:
        !            39:     printf("%s,%lu,%i,%i,%s,%s,%s,%s,%s,%s,%s,%s,%s\n", BROGUE_DUNGEON_VERSION_STRING, seed, depth, quantity, categoryName,
        !            40:            kindName, enchantment, runicName, vaultNumber, opensVaultNumber, carriedByMonsterName, allyStatusName,
        !            41:            mutationName);
        !            42: }
        !            43:
        !            44: static void getMonsterDetailedName(creature *theMonster, char *theMonsterName) {
        !            45:     if (theMonster->mutationIndex >= 0) {
        !            46:         sprintf(theMonsterName, "%s [%s]", theMonster->info.monsterName, mutationCatalog[theMonster->mutationIndex].title);
        !            47:     } else {
        !            48:         strcpy(theMonsterName, theMonster->info.monsterName);
        !            49:     }
        !            50: }
        !            51:
        !            52: static void printSeedCatalogItem(item *theItem, creature *theMonster, boolean isCsvFormat) {
        !            53:     char inGameItemName[500] = "", carriedByMonsterName[100] = "", vaultNumber[36] = "", opensVaultNumber[36] = "";
        !            54:     char categoryName[20] = "", kindName[50] = "", enchantment[5] = "", runicName[30] = "", mutationName[100] = "";
        !            55:
        !            56:     if (isCsvFormat) {     //for csv output we need the item name components: category, kind, enchantment, & runic
        !            57:         strcpy(categoryName, itemCategoryNames[unflag(theItem->category)]);
        !            58:         itemKindName(theItem, kindName);
        !            59:         itemRunicName(theItem, runicName);
        !            60:         if (theItem->category & (ARMOR | CHARM | RING | STAFF | WAND | WEAPON)) {   //enchantable items
        !            61:             if (theItem->category == WAND) {
        !            62:                 sprintf(enchantment, "%i", theItem->charges);
        !            63:             } else {
        !            64:                 sprintf(enchantment, "%i", theItem->enchant1);
        !            65:             }
        !            66:         }
        !            67:     } else {
        !            68:         itemName(theItem, inGameItemName, true, true, NULL);   //for standard output, use the in-game item name as base
        !            69:     }
        !            70:
        !            71:     if (theMonster != NULL) {   //carried by monster
        !            72:         if (isCsvFormat) {
        !            73:             sprintf(carriedByMonsterName, theMonster->info.monsterName);
        !            74:             strcpy(mutationName, theMonster->mutationIndex >= 0 ? mutationCatalog[theMonster->mutationIndex].title : "");
        !            75:         } else {
        !            76:             getMonsterDetailedName(theMonster, carriedByMonsterName);
        !            77:         }
        !            78:     }
        !            79:
        !            80:     // vaultNumber
        !            81:     if (pmap[theItem->xLoc][theItem->yLoc].machineNumber > 0) {
        !            82:         //not all machines are "vaults" so we need to exclude some.
        !            83:         if (pmap[theItem->xLoc][theItem->yLoc].layers[0] != ALTAR_SWITCH
        !            84:             && pmap[theItem->xLoc][theItem->yLoc].layers[0] != ALTAR_SWITCH_RETRACTING
        !            85:             && pmap[theItem->xLoc][theItem->yLoc].layers[0] != ALTAR_CAGE_RETRACTABLE
        !            86:             && pmap[theItem->xLoc][theItem->yLoc].layers[0] != ALTAR_INERT
        !            87:             && pmap[theItem->xLoc][theItem->yLoc].layers[0] != AMULET_SWITCH
        !            88:             && pmap[theItem->xLoc][theItem->yLoc].layers[0] != FLOOR) {
        !            89:
        !            90:             sprintf(vaultNumber, isCsvFormat ? "%i" : " (vault %i)", pmap[theItem->xLoc][theItem->yLoc].machineNumber);
        !            91:         }
        !            92:     }
        !            93:
        !            94:     // opensVaultNumber
        !            95:     if (theItem->category == KEY && theItem->kind == KEY_DOOR) {
        !            96:         sprintf(opensVaultNumber, isCsvFormat ? "%i" : " (opens vault %i)",
        !            97:                 pmap[theItem->keyLoc[0].x][theItem->keyLoc[0].y].machineNumber - 1);
        !            98:     }
        !            99:
        !           100:     if (isCsvFormat) {
        !           101:         printSeedCatalogCsvLine(rogue.seed, rogue.depthLevel, theItem->quantity, categoryName, kindName, enchantment,
        !           102:                                 runicName, vaultNumber, opensVaultNumber, carriedByMonsterName, NO_ALLY_STATUS_STRING,
        !           103:                                 mutationName);
        !           104:     } else {
        !           105:         upperCase(inGameItemName);
        !           106:         if (theMonster != NULL) {
        !           107:             printf("        %s (%s)%s%s\n", inGameItemName, carriedByMonsterName, vaultNumber, opensVaultNumber);
        !           108:         } else {
        !           109:             printf("        %s%s%s\n", inGameItemName, vaultNumber, opensVaultNumber);
        !           110:         }
        !           111:     }
        !           112: }
        !           113:
        !           114: static void printSeedCatalogMonster(creature *theMonster, boolean isCsvFormat) {
        !           115:     char categoryName[10] = "", allyStatusName[20] = "", mutationName[100] = "", theMonsterName[100] = "";
        !           116:
        !           117:     strcpy(mutationName, theMonster->mutationIndex >= 0 ? mutationCatalog[theMonster->mutationIndex].title : "");
        !           118:
        !           119:     if (theMonster->bookkeepingFlags & MB_CAPTIVE) {
        !           120:         strcpy(categoryName,"ally");
        !           121:         if (cellHasTMFlag(theMonster->xLoc, theMonster->yLoc, TM_PROMOTES_WITH_KEY)) {
        !           122:             strcpy(allyStatusName, isCsvFormat ? "caged" : "A caged ");
        !           123:         } else {
        !           124:             strcpy(allyStatusName, isCsvFormat ? "shackled" : "A shackled ");
        !           125:         }
        !           126:     } else if (theMonster->creatureState == MONSTER_ALLY) {
        !           127:         strcpy(categoryName,"ally");
        !           128:         strcpy(allyStatusName, isCsvFormat ? "allied" : "An allied ");
        !           129:     } else {
        !           130:         strcpy(categoryName,"monster");
        !           131:     }
        !           132:
        !           133:     if (isCsvFormat) {
        !           134:         printSeedCatalogCsvLine(rogue.seed, rogue.depthLevel, 1, categoryName, theMonster->info.monsterName,
        !           135:                                 NO_ENCHANTMENT_STRING, NO_RUNIC_STRING, NO_VAULT_STRING, NO_OPENS_VAULT_STRING,
        !           136:                                 NO_CARRIED_BY_MONSTER_STRING, allyStatusName, mutationName);
        !           137:     } else {
        !           138:         getMonsterDetailedName(theMonster, theMonsterName);
        !           139:         printf("        %s%s\n", allyStatusName, theMonsterName);
        !           140:     }
        !           141: }
        !           142:
        !           143: static void printSeedCatalogMonsters(boolean isCsvFormat, boolean includeAll) {
        !           144:     creature *theMonster;
        !           145:
        !           146:     for (theMonster = monsters->nextCreature; theMonster != NULL; theMonster = theMonster->nextCreature) {
        !           147:         if (theMonster->bookkeepingFlags & MB_CAPTIVE || theMonster->creatureState == MONSTER_ALLY || includeAll) {
        !           148:             printSeedCatalogMonster(theMonster, isCsvFormat);
        !           149:         }
        !           150:     }
        !           151:
        !           152:     for (theMonster = dormantMonsters->nextCreature; theMonster != NULL; theMonster = theMonster->nextCreature) {
        !           153:         if (theMonster->bookkeepingFlags & MB_CAPTIVE || theMonster->creatureState == MONSTER_ALLY || includeAll) {
        !           154:             printSeedCatalogMonster(theMonster, isCsvFormat);
        !           155:         }
        !           156:     }
        !           157: }
        !           158:
        !           159: static void printSeedCatalogMonsterItems(boolean isCsvFormat) {
        !           160:     creature *theMonster;
        !           161:
        !           162:     for (theMonster = monsters->nextCreature; theMonster != NULL; theMonster = theMonster->nextCreature) {
        !           163:         if (theMonster->carriedItem != NULL && theMonster->carriedItem->category != GOLD) {
        !           164:             printSeedCatalogItem(theMonster->carriedItem, theMonster, isCsvFormat);
        !           165:         }
        !           166:     }
        !           167:
        !           168:     for (theMonster = dormantMonsters->nextCreature; theMonster != NULL; theMonster = theMonster->nextCreature) {
        !           169:         if (theMonster->carriedItem != NULL && theMonster->carriedItem->category != GOLD) {
        !           170:             printSeedCatalogItem(theMonster->carriedItem, theMonster, isCsvFormat);
        !           171:         }
        !           172:     }
        !           173: }
        !           174:
        !           175: static void printSeedCatalogFloorGold(int gold, short piles, boolean isCsvFormat) {
        !           176:     char kindName[50] = "";
        !           177:
        !           178:     if (isCsvFormat) {
        !           179:         if (piles == 1) {
        !           180:             strcpy(kindName, "gold pieces");
        !           181:         } else if (piles > 1) {
        !           182:             sprintf(kindName, "gold pieces (%i piles)", piles);
        !           183:         }
        !           184:         printSeedCatalogCsvLine(rogue.seed, rogue.depthLevel, gold, "gold", kindName, NO_ENCHANTMENT_STRING,
        !           185:                                 NO_RUNIC_STRING, NO_VAULT_STRING, NO_OPENS_VAULT_STRING, NO_CARRIED_BY_MONSTER_STRING,
        !           186:                                 NO_ALLY_STATUS_STRING, NO_MUTATION_STRING);
        !           187:     } else {
        !           188:         if (piles == 1) {
        !           189:             printf("        %i gold pieces\n", gold);
        !           190:         } else if (piles > 1) {
        !           191:             printf("        %i gold pieces (%i piles)\n", gold, piles);
        !           192:         }
        !           193:     }
        !           194: }
        !           195:
        !           196: static void printSeedCatalogFloorItems(boolean isCsvFormat) {
        !           197:     item *theItem;
        !           198:     int gold = 0;
        !           199:     short piles = 0;
        !           200:
        !           201:     for (theItem = floorItems->nextItem; theItem != NULL; theItem = theItem->nextItem) {
        !           202:         if (theItem->category == GOLD) {
        !           203:             piles++;
        !           204:             gold += theItem->quantity;
        !           205:         } else if (theItem->category == AMULET) {
        !           206:         } else {
        !           207:             printSeedCatalogItem(theItem, NULL, isCsvFormat);
        !           208:         }
        !           209:     }
        !           210:
        !           211:     if (gold > 0) {
        !           212:         printSeedCatalogFloorGold(gold, piles, isCsvFormat);
        !           213:     }
        !           214: }
        !           215:
        !           216: static void printSeedCatalogAltars(boolean isCsvFormat) {
        !           217:     short i, j;
        !           218:     boolean c_altars[50] = {0}; //IO.displayMachines uses 50
        !           219:     char vaultNumber[10] = "";
        !           220:
        !           221:     for (j = 0; j < DROWS; j++) {
        !           222:         for (i = 0; i < DCOLS; i++) {
        !           223:             if (pmap[i][j].layers[0] == RESURRECTION_ALTAR) {
        !           224:                 sprintf(vaultNumber, "%i", pmap[i][j].machineNumber);
        !           225:                 if (isCsvFormat) {
        !           226:                     printSeedCatalogCsvLine(rogue.seed, rogue.depthLevel, 1, "altar", "resurrection altar",
        !           227:                             NO_ENCHANTMENT_STRING, NO_RUNIC_STRING, vaultNumber, NO_OPENS_VAULT_STRING,
        !           228:                             NO_CARRIED_BY_MONSTER_STRING, NO_ALLY_STATUS_STRING, NO_MUTATION_STRING);
        !           229:                 } else {
        !           230:                     printf("        A resurrection altar (vault %s)\n", vaultNumber);
        !           231:                 }
        !           232:             }
        !           233:             // commutation altars come in pairs. we only want to print 1.
        !           234:             if (pmap[i][j].layers[0] == COMMUTATION_ALTAR) {
        !           235:                 c_altars[pmap[i][j].machineNumber] = true;
        !           236:             }
        !           237:         }
        !           238:     }
        !           239:     for (i = 0; i < 50; i++) {
        !           240:         if (c_altars[i]) {
        !           241:             sprintf(vaultNumber, "%i", i);
        !           242:             if (isCsvFormat) {
        !           243:                 printSeedCatalogCsvLine(rogue.seed, rogue.depthLevel, 1, "altar", "commutation altar",
        !           244:                                         NO_ENCHANTMENT_STRING, NO_RUNIC_STRING, vaultNumber, NO_OPENS_VAULT_STRING,
        !           245:                                         NO_CARRIED_BY_MONSTER_STRING, NO_ALLY_STATUS_STRING, NO_MUTATION_STRING);
        !           246:             } else {
        !           247:                 printf("        A commutation altar (vault %s)\n",vaultNumber);
        !           248:             }
        !           249:         }
        !           250:     }
        !           251: }
        !           252:
        !           253: void printSeedCatalog(unsigned long startingSeed, unsigned long numberOfSeedsToScan, unsigned int scanThroughDepth,
        !           254:                       boolean isCsvFormat) {
        !           255:     unsigned long theSeed;
        !           256:     char path[BROGUE_FILENAME_MAX];
        !           257:     char message[1000] = "";
        !           258:     rogue.nextGame = NG_NOTHING;
        !           259:
        !           260:     getAvailableFilePath(path, LAST_GAME_NAME, GAME_SUFFIX);
        !           261:     strcat(path, GAME_SUFFIX);
        !           262:
        !           263:     sprintf(message, "Brogue seed catalog, seeds %lu to %lu, through depth %u.\n"
        !           264:                      "Generated with %s. Dungeons unchanged since %s.\n\n"
        !           265:                      "To play one of these seeds, press control-N from the title screen"
        !           266:                      " and enter the seed number.\n",
        !           267:             startingSeed, startingSeed + numberOfSeedsToScan - 1, scanThroughDepth, BROGUE_VERSION_STRING,
        !           268:             BROGUE_DUNGEON_VERSION_STRING, scanThroughDepth);
        !           269:
        !           270:     if (isCsvFormat) {
        !           271:         fprintf(stderr, "%s", message);
        !           272:         printf("%s\n",CSV_HEADER_STRING);
        !           273:     } else {
        !           274:         printf("%s", message);
        !           275:     }
        !           276:
        !           277:     for (theSeed = startingSeed; theSeed < startingSeed + numberOfSeedsToScan; theSeed++) {
        !           278:         if (!isCsvFormat) {
        !           279:             printf("Seed %li:\n", theSeed);
        !           280:         }
        !           281:         fprintf(stderr, "Scanning seed %li...\n", theSeed);
        !           282:         rogue.nextGamePath[0] = '\0';
        !           283:         randomNumbersGenerated = 0;
        !           284:
        !           285:         rogue.playbackMode = false;
        !           286:         rogue.playbackFastForward = false;
        !           287:         rogue.playbackBetweenTurns = false;
        !           288:
        !           289:         strcpy(currentFilePath, path);
        !           290:         initializeRogue(theSeed);
        !           291:         rogue.playbackOmniscience = true;
        !           292:         for (rogue.depthLevel = 1; rogue.depthLevel <= scanThroughDepth; rogue.depthLevel++) {
        !           293:             startLevel(rogue.depthLevel == 1 ? 1 : rogue.depthLevel - 1, 1); // descending into level n
        !           294:             if (!isCsvFormat) {
        !           295:                 printf("    Depth %i:\n", rogue.depthLevel);
        !           296:             }
        !           297:
        !           298:             printSeedCatalogFloorItems(isCsvFormat);
        !           299:             printSeedCatalogMonsterItems(isCsvFormat);
        !           300:             printSeedCatalogMonsters(isCsvFormat, false); // captives and allies only
        !           301:             if (rogue.depthLevel >= 13) { // resurrection & commutation altars can spawn starting on 13
        !           302:                 printSeedCatalogAltars(isCsvFormat);
        !           303:             }
        !           304:         }
        !           305:
        !           306:         freeEverything();
        !           307:         remove(currentFilePath); // Don't add a spurious LastGame file to the brogue folder.
        !           308:     }
        !           309:
        !           310: }

CVSweb