[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

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